00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00083 theIColumn += theStep;
00084
00085
00086 if ((theIColumn + (3 * theStep) / 2 + 1)%(3 * theStep) == 0 &&
00087 (theIRow + (3 * theStep) / 2 + 1)%(3 * theStep) == 0)
00088 theIColumn += theStep;
00089
00090
00091 if (theIColumn >= theNColumn) {
00092 theIColumn = theStep / 2;
00093 theIRow += theStep;
00094 }
00095
00096
00097 if (theIRow >= theNRow && theStep <= 1) return false;
00098
00099
00100 if (theIRow >= theNRow) {
00101 theStep /= 3;
00102 theIRow = theStep / 2;
00103 theIColumn = theStep / 2;
00104 }
00105
00106
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);
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
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,
00171 WhitePixel(display, screen_num),
00172 BlackPixel(display, screen_num));
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");
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
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
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