G4RTXScanner.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 //
00030 
00031 #ifdef G4VIS_BUILD_RAYTRACERX_DRIVER
00032 
00033 #include "G4RTXScanner.hh"
00034 
00035 #include "G4TheRayTracer.hh"
00036 #include "G4RayTracerXViewer.hh"
00037 #include "G4ViewParameters.hh"
00038 #include <X11/Xlib.h>
00039 #include <X11/Xutil.h>
00040 #include <X11/Xatom.h>
00041 
00042 extern "C" {
00043   Bool G4RayTracerXScannerWaitForNotify (Display*, XEvent* e, char* arg) {
00044     return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
00045   }
00046 }
00047 
00048 G4RTXScanner::G4RTXScanner():
00049   G4VRTScanner(), theNRow(0), theNColumn(0), theStep(0)
00050   ,theIRow(0), theIColumn(0)
00051   ,display(0), win(0), scmap(0)
00052 {
00053   theGSName = "RayTracerX";
00054   theGSNickname = "RayTracerX";
00055 }
00056 
00057 G4RTXScanner::~G4RTXScanner() {}
00058 
00059 const G4String& G4RTXScanner::GetGSName() const
00060 {return theGSName;}
00061 
00062 const G4String& G4RTXScanner::GetGSNickname() const
00063 {return theGSNickname;}
00064 
00065 void G4RTXScanner::Initialize(G4int nRow, G4int nColumn) {
00066   theNRow = nRow;
00067   theNColumn = nColumn;
00068   G4int nMax = std::max (nRow, nColumn);
00069   theStep = 1;
00070   if (nMax > 3) {
00071     for (;;) {
00072       theStep *= 3;
00073       if (theStep > nMax) break;
00074     }
00075   }
00076   theIRow = theStep / 2;
00077   theIColumn = theStep / 2 - theStep;
00078 }
00079 
00080 G4bool G4RTXScanner::Coords(G4int& iRow, G4int& iColumn)
00081 {
00082   // Increment column...
00083   theIColumn += theStep;
00084 
00085   // Skip coordinates covered in the previous scan...
00086   if ((theIColumn + (3 * theStep) / 2 + 1)%(3 * theStep) == 0 &&
00087       (theIRow + (3 * theStep) / 2 + 1)%(3 * theStep) == 0)
00088     theIColumn += theStep;
00089 
00090   //  If necessary, increment row...
00091   if (theIColumn >= theNColumn) {
00092     theIColumn = theStep / 2;
00093     theIRow += theStep;
00094   }
00095 
00096   // Return if finished...
00097   if (theIRow >= theNRow && theStep <= 1) return false;
00098 
00099   // Start next scan if necessary...
00100   if (theIRow >= theNRow) {
00101     theStep /= 3;
00102     theIRow = theStep / 2;
00103     theIColumn = theStep / 2;
00104   }
00105 
00106   // Return current row and column...
00107   iRow = theIRow;
00108   iColumn = theIColumn;
00109   return true;
00110 }
00111 
00112 G4bool G4RTXScanner::GetXWindow(const G4String& name, G4ViewParameters& vp)
00113 {
00114   display = XOpenDisplay(0);  // Use display defined by DISPLAY environment.
00115   if (!display) {
00116     G4cerr << "G4RTXScanner::Initialize(): cannot get display."
00117            << G4endl;
00118     return false;
00119   }
00120 
00121   int screen_num = DefaultScreen(display);
00122 
00123   // Window size and position...
00124   int xOffset = 0, yOffset = 0;
00125   XSizeHints* size_hints = XAllocSizeHints();
00126   unsigned int width, height;
00127   const G4String& XGeometryString = vp.GetXGeometryString();
00128   if (!XGeometryString.empty()) {
00129     G4int geometryResultMask = XParseGeometry
00130       ((char*)XGeometryString.c_str(),
00131        &xOffset, &yOffset, &width, &height);
00132     if (geometryResultMask & (WidthValue | HeightValue)) {
00133       if (geometryResultMask & XValue) {
00134         if (geometryResultMask & XNegative) {
00135           xOffset = DisplayWidth(display, screen_num) + xOffset - width;
00136         }
00137         size_hints->flags |= PPosition;
00138         size_hints->x = xOffset;
00139       }
00140       if (geometryResultMask & YValue) {
00141         if (geometryResultMask & YNegative) {
00142           yOffset = DisplayHeight(display, screen_num) + yOffset - height;
00143         }
00144         size_hints->flags |= PPosition;
00145         size_hints->y = yOffset;
00146       }
00147     } else {
00148       G4cout << "ERROR: Geometry string \""
00149              << XGeometryString
00150              << "\" invalid.  Using \"600x600\"."
00151              << G4endl;
00152       width = 600;
00153       height = 600;
00154     }
00155   } else {
00156     G4cout << "ERROR: Geometry string \""
00157            << XGeometryString
00158            << "\" is empty.  Using \"600x600\"."
00159            << G4endl;
00160     width = 600;
00161     height = 600;
00162   }
00163   size_hints->width = width;
00164   size_hints->height = height;
00165   size_hints->flags |= PSize;
00166 
00167   win = XCreateSimpleWindow
00168     (display, RootWindow(display, screen_num),
00169      xOffset, yOffset, width, height,
00170      0,                                 // Border width.
00171      WhitePixel(display, screen_num),   // Border colour.
00172      BlackPixel(display, screen_num));  // Background colour.
00173 
00174   XGCValues values;
00175   gc = XCreateGC(display, win, 0, &values);
00176 
00177   int nMaps;
00178   Status status = XGetRGBColormaps
00179     (display, RootWindow(display, screen_num),
00180      &scmap, &nMaps, XA_RGB_BEST_MAP);
00181   if (!status) {
00182     system("xstdcmap -best");  // ...and try again...
00183     status = XGetRGBColormaps
00184       (display, RootWindow(display, screen_num),
00185        &scmap, &nMaps, XA_RGB_BEST_MAP);
00186     if (!status) {
00187       G4cerr <<
00188         "G4RTXScanner::Initialize(): cannot get color map."
00189         "\n  Perhaps your system does not support RGB_BEST_MAP."
00190              << G4endl;
00191       return false;
00192     }
00193   }
00194   if (!scmap->colormap) {
00195     G4cerr << "G4RTXScanner::Initialize(): color map empty."
00196            << G4endl;
00197     return false;
00198   }
00199 
00200   XWMHints* wm_hints = XAllocWMHints();
00201   XClassHint* class_hint = XAllocClassHint();
00202   const char* window_name = name.c_str();
00203   XTextProperty windowName;
00204   XStringListToTextProperty((char**)&window_name, 1, &windowName);
00205 
00206   XSetWMProperties(display, win, &windowName, &windowName,
00207                    0, 0, size_hints, wm_hints, class_hint);
00208 
00209   XMapWindow(display, win);
00210 
00211   // Wait for window to appear (wait for an "map notify" event).
00212   XSelectInput(display, win, StructureNotifyMask);
00213   XEvent event;
00214   XIfEvent (display, &event, G4RayTracerXScannerWaitForNotify, (char*) win);
00215 
00216   return true;
00217 }
00218 
00219 void G4RTXScanner::Draw
00220 (unsigned char red, unsigned char green, unsigned char blue)
00221 // Draw coloured square at current position.
00222 {
00223   unsigned long pixel_value = scmap->base_pixel +
00224     ((unsigned long) ((red * scmap->red_max) / 256.) * scmap->red_mult) +
00225     ((unsigned long) ((green * scmap->green_max) / 256.) * scmap->green_mult) +
00226     ((unsigned long) ((blue * scmap->blue_max) / 256.) * scmap->blue_mult);
00227   XSetForeground(display, gc, pixel_value);
00228 
00229   if (theStep > 1) {
00230     XFillRectangle(display, win, gc,
00231                    theIColumn - theStep / 2,
00232                    theIRow - theStep / 2,
00233                    theStep, theStep);
00234   } else {
00235     XDrawPoint(display, win, gc, theIColumn, theIRow);
00236   }
00237 
00238   XFlush(display);
00239 }
00240 
00241 #endif

Generated on Mon May 27 17:49:47 2013 for Geant4 by  doxygen 1.4.7