Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4RTXScanner.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id$
28 //
29 //
30 
31 #ifdef G4VIS_BUILD_RAYTRACERX_DRIVER
32 
33 #include "G4RTXScanner.hh"
34 
35 #include "G4TheRayTracer.hh"
36 #include "G4RayTracerXViewer.hh"
37 #include "G4ViewParameters.hh"
38 #include <X11/Xlib.h>
39 #include <X11/Xutil.h>
40 #include <X11/Xatom.h>
41 
42 extern "C" {
43  Bool G4RayTracerXScannerWaitForNotify (Display*, XEvent* e, char* arg) {
44  return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
45  }
46 }
47 
48 G4RTXScanner::G4RTXScanner():
49  G4VRTScanner(), theNRow(0), theNColumn(0), theStep(0)
50  ,theIRow(0), theIColumn(0)
51  ,display(0), win(0), scmap(0)
52 {
53  theGSName = "RayTracerX";
54  theGSNickname = "RayTracerX";
55 }
56 
57 G4RTXScanner::~G4RTXScanner() {}
58 
59 const G4String& G4RTXScanner::GetGSName() const
60 {return theGSName;}
61 
62 const G4String& G4RTXScanner::GetGSNickname() const
63 {return theGSNickname;}
64 
65 void G4RTXScanner::Initialize(G4int nRow, G4int nColumn) {
66  theNRow = nRow;
67  theNColumn = nColumn;
68  G4int nMax = std::max (nRow, nColumn);
69  theStep = 1;
70  if (nMax > 3) {
71  for (;;) {
72  theStep *= 3;
73  if (theStep > nMax) break;
74  }
75  }
76  theIRow = theStep / 2;
77  theIColumn = theStep / 2 - theStep;
78 }
79 
80 G4bool G4RTXScanner::Coords(G4int& iRow, G4int& iColumn)
81 {
82  // Increment column...
83  theIColumn += theStep;
84 
85  // Skip coordinates covered in the previous scan...
86  if ((theIColumn + (3 * theStep) / 2 + 1)%(3 * theStep) == 0 &&
87  (theIRow + (3 * theStep) / 2 + 1)%(3 * theStep) == 0)
88  theIColumn += theStep;
89 
90  // If necessary, increment row...
91  if (theIColumn >= theNColumn) {
92  theIColumn = theStep / 2;
93  theIRow += theStep;
94  }
95 
96  // Return if finished...
97  if (theIRow >= theNRow && theStep <= 1) return false;
98 
99  // Start next scan if necessary...
100  if (theIRow >= theNRow) {
101  theStep /= 3;
102  theIRow = theStep / 2;
103  theIColumn = theStep / 2;
104  }
105 
106  // Return current row and column...
107  iRow = theIRow;
108  iColumn = theIColumn;
109  return true;
110 }
111 
112 G4bool G4RTXScanner::GetXWindow(const G4String& name, G4ViewParameters& vp)
113 {
114  display = XOpenDisplay(0); // Use display defined by DISPLAY environment.
115  if (!display) {
116  G4cerr << "G4RTXScanner::Initialize(): cannot get display."
117  << G4endl;
118  return false;
119  }
120 
121  int screen_num = DefaultScreen(display);
122 
123  // Window size and position...
124  int xOffset = 0, yOffset = 0;
125  XSizeHints* size_hints = XAllocSizeHints();
126  unsigned int width, height;
127  const G4String& XGeometryString = vp.GetXGeometryString();
128  if (!XGeometryString.empty()) {
129  G4int geometryResultMask = XParseGeometry
130  ((char*)XGeometryString.c_str(),
131  &xOffset, &yOffset, &width, &height);
132  if (geometryResultMask & (WidthValue | HeightValue)) {
133  if (geometryResultMask & XValue) {
134  if (geometryResultMask & XNegative) {
135  xOffset = DisplayWidth(display, screen_num) + xOffset - width;
136  }
137  size_hints->flags |= PPosition;
138  size_hints->x = xOffset;
139  }
140  if (geometryResultMask & YValue) {
141  if (geometryResultMask & YNegative) {
142  yOffset = DisplayHeight(display, screen_num) + yOffset - height;
143  }
144  size_hints->flags |= PPosition;
145  size_hints->y = yOffset;
146  }
147  } else {
148  G4cout << "ERROR: Geometry string \""
149  << XGeometryString
150  << "\" invalid. Using \"600x600\"."
151  << G4endl;
152  width = 600;
153  height = 600;
154  }
155  } else {
156  G4cout << "ERROR: Geometry string \""
157  << XGeometryString
158  << "\" is empty. Using \"600x600\"."
159  << G4endl;
160  width = 600;
161  height = 600;
162  }
163  size_hints->width = width;
164  size_hints->height = height;
165  size_hints->flags |= PSize;
166 
167  win = XCreateSimpleWindow
168  (display, RootWindow(display, screen_num),
169  xOffset, yOffset, width, height,
170  0, // Border width.
171  WhitePixel(display, screen_num), // Border colour.
172  BlackPixel(display, screen_num)); // Background colour.
173 
174  XGCValues values;
175  gc = XCreateGC(display, win, 0, &values);
176 
177  int nMaps;
178  Status status = XGetRGBColormaps
179  (display, RootWindow(display, screen_num),
180  &scmap, &nMaps, XA_RGB_BEST_MAP);
181  if (!status) {
182  system("xstdcmap -best"); // ...and try again...
183  status = XGetRGBColormaps
184  (display, RootWindow(display, screen_num),
185  &scmap, &nMaps, XA_RGB_BEST_MAP);
186  if (!status) {
187  G4cerr <<
188  "G4RTXScanner::Initialize(): cannot get color map."
189  "\n Perhaps your system does not support RGB_BEST_MAP."
190  << G4endl;
191  return false;
192  }
193  }
194  if (!scmap->colormap) {
195  G4cerr << "G4RTXScanner::Initialize(): color map empty."
196  << G4endl;
197  return false;
198  }
199 
200  XWMHints* wm_hints = XAllocWMHints();
201  XClassHint* class_hint = XAllocClassHint();
202  const char* window_name = name.c_str();
203  XTextProperty windowName;
204  XStringListToTextProperty((char**)&window_name, 1, &windowName);
205 
206  XSetWMProperties(display, win, &windowName, &windowName,
207  0, 0, size_hints, wm_hints, class_hint);
208 
209  XMapWindow(display, win);
210 
211  // Wait for window to appear (wait for an "map notify" event).
212  XSelectInput(display, win, StructureNotifyMask);
213  XEvent event;
214  XIfEvent (display, &event, G4RayTracerXScannerWaitForNotify, (char*) win);
215 
216  return true;
217 }
218 
220 (unsigned char red, unsigned char green, unsigned char blue)
221 // Draw coloured square at current position.
222 {
223  unsigned long pixel_value = scmap->base_pixel +
224  ((unsigned long) ((red * scmap->red_max) / 256.) * scmap->red_mult) +
225  ((unsigned long) ((green * scmap->green_max) / 256.) * scmap->green_mult) +
226  ((unsigned long) ((blue * scmap->blue_max) / 256.) * scmap->blue_mult);
227  XSetForeground(display, gc, pixel_value);
228 
229  if (theStep > 1) {
230  XFillRectangle(display, win, gc,
231  theIColumn - theStep / 2,
232  theIRow - theStep / 2,
233  theStep, theStep);
234  } else {
235  XDrawPoint(display, win, gc, theIColumn, theIRow);
236  }
237 
238  XFlush(display);
239 }
240 
241 #endif