ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4RTXScanner.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4RTXScanner.cc
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 //
28 //
29 
30 #ifdef G4VIS_BUILD_RAYTRACERX_DRIVER
31 
32 #include "G4RTXScanner.hh"
33 
34 #include "G4TheRayTracer.hh"
35 #include "G4RayTracerXViewer.hh"
36 #include "G4ViewParameters.hh"
37 #include <X11/Xlib.h>
38 #include <X11/Xutil.h>
39 #include <X11/Xatom.h>
40 
41 extern "C" {
42  Bool G4RayTracerXScannerWaitForNotify (Display*, XEvent* e, char* arg) {
43  return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
44  }
45 }
46 
47 G4RTXScanner::G4RTXScanner():
48  G4VRTScanner(), theNRow(0), theNColumn(0), theStep(0)
49  ,theIRow(0), theIColumn(0)
50  ,display(0), win(0), scmap(0)
51 {
52  theGSName = "RayTracerX";
53  theGSNickname = "RayTracerX";
54 }
55 
56 G4RTXScanner::~G4RTXScanner() {}
57 
58 const G4String& G4RTXScanner::GetGSName() const
59 {return theGSName;}
60 
61 const G4String& G4RTXScanner::GetGSNickname() const
62 {return theGSNickname;}
63 
64 void G4RTXScanner::Initialize(G4int nRow, G4int nColumn) {
65  theNRow = nRow;
66  theNColumn = nColumn;
67  G4int nMax = std::max (nRow, nColumn);
68  theStep = 1;
69  if (nMax > 3) {
70  for (;;) {
71  theStep *= 3;
72  if (theStep > nMax) break;
73  }
74  }
75  theIRow = theStep / 2;
76  theIColumn = theStep / 2 - theStep;
77 }
78 
79 G4bool G4RTXScanner::Coords(G4int& iRow, G4int& iColumn)
80 {
81  // Increment column...
82  theIColumn += theStep;
83 
84  // Skip coordinates covered in the previous scan...
85  if ((theIColumn + (3 * theStep) / 2 + 1)%(3 * theStep) == 0 &&
86  (theIRow + (3 * theStep) / 2 + 1)%(3 * theStep) == 0)
87  theIColumn += theStep;
88 
89  // If necessary, increment row...
90  if (theIColumn >= theNColumn) {
91  theIColumn = theStep / 2;
92  theIRow += theStep;
93  }
94 
95  // Return if finished...
96  if (theIRow >= theNRow && theStep <= 1) return false;
97 
98  // Start next scan if necessary...
99  if (theIRow >= theNRow) {
100  theStep /= 3;
101  theIRow = theStep / 2;
102  theIColumn = theStep / 2;
103  }
104 
105  // Return current row and column...
106  iRow = theIRow;
107  iColumn = theIColumn;
108  return true;
109 }
110 
111 G4bool G4RTXScanner::GetXWindow(const G4String& name, G4ViewParameters& vp)
112 {
113  display = XOpenDisplay(0); // Use display defined by DISPLAY environment.
114  if (!display) {
115  G4cerr << "G4RTXScanner::Initialize(): cannot get display."
116  << G4endl;
117  return false;
118  }
119 
120  int screen_num = DefaultScreen(display);
121 
122  // Window size and position...
123  int xOffset = 0, yOffset = 0;
124  XSizeHints* size_hints = XAllocSizeHints();
125  unsigned int width, height;
126  const G4String& XGeometryString = vp.GetXGeometryString();
127  if (!XGeometryString.empty()) {
128  G4int geometryResultMask = XParseGeometry
129  ((char*)XGeometryString.c_str(),
130  &xOffset, &yOffset, &width, &height);
131  if (geometryResultMask & (WidthValue | HeightValue)) {
132  if (geometryResultMask & XValue) {
133  if (geometryResultMask & XNegative) {
134  xOffset = DisplayWidth(display, screen_num) + xOffset - width;
135  }
136  size_hints->flags |= PPosition;
137  size_hints->x = xOffset;
138  }
139  if (geometryResultMask & YValue) {
140  if (geometryResultMask & YNegative) {
141  yOffset = DisplayHeight(display, screen_num) + yOffset - height;
142  }
143  size_hints->flags |= PPosition;
144  size_hints->y = yOffset;
145  }
146  } else {
147  G4cout << "ERROR: Geometry string \""
148  << XGeometryString
149  << "\" invalid. Using \"600x600\"."
150  << G4endl;
151  width = 600;
152  height = 600;
153  }
154  } else {
155  G4cout << "ERROR: Geometry string \""
156  << XGeometryString
157  << "\" is empty. Using \"600x600\"."
158  << G4endl;
159  width = 600;
160  height = 600;
161  }
162  size_hints->width = width;
163  size_hints->height = height;
164  size_hints->flags |= PSize;
165 
166  win = XCreateSimpleWindow
167  (display, RootWindow(display, screen_num),
168  xOffset, yOffset, width, height,
169  0, // Border width.
170  WhitePixel(display, screen_num), // Border colour.
171  BlackPixel(display, screen_num)); // Background colour.
172 
173  XGCValues values;
174  gc = XCreateGC(display, win, 0, &values);
175 
176  int nMaps;
177  Status status = XGetRGBColormaps
178  (display, RootWindow(display, screen_num),
179  &scmap, &nMaps, XA_RGB_BEST_MAP);
180  if (!status) {
181  system("xstdcmap -best"); // ...and try again...
182  status = XGetRGBColormaps
183  (display, RootWindow(display, screen_num),
184  &scmap, &nMaps, XA_RGB_BEST_MAP);
185  if (!status) {
186  G4cerr <<
187  "G4RTXScanner::Initialize(): cannot get color map."
188  "\n Perhaps your system does not support XA_RGB_BEST_MAP."
189  << G4endl;
190  return false;
191  }
192  }
193  if (!scmap->colormap) {
194  G4cerr << "G4RTXScanner::Initialize(): color map empty."
195  << G4endl;
196  return false;
197  }
198 
199  XWMHints* wm_hints = XAllocWMHints();
200  XClassHint* class_hint = XAllocClassHint();
201  const char* window_name = name.c_str();
202  XTextProperty windowName;
203  XStringListToTextProperty((char**)&window_name, 1, &windowName);
204 
205  XSetWMProperties(display, win, &windowName, &windowName,
206  0, 0, size_hints, wm_hints, class_hint);
207 
208  XMapWindow(display, win);
209 
210  // Wait for window to appear (wait for an "map notify" event).
211  XSelectInput(display, win, StructureNotifyMask);
212  XEvent event;
213  XIfEvent (display, &event, G4RayTracerXScannerWaitForNotify, (char*) win);
214 
215  return true;
216 }
217 
219 (unsigned char red, unsigned char green, unsigned char blue)
220 // Draw coloured square at current position.
221 {
222  unsigned long pixel_value = scmap->base_pixel +
223  ((unsigned long) ((red * scmap->red_max) / 256.) * scmap->red_mult) +
224  ((unsigned long) ((green * scmap->green_max) / 256.) * scmap->green_mult) +
225  ((unsigned long) ((blue * scmap->blue_max) / 256.) * scmap->blue_mult);
226  XSetForeground(display, gc, pixel_value);
227 
228  if (theStep > 1) {
229  XFillRectangle(display, win, gc,
230  theIColumn - theStep / 2,
231  theIRow - theStep / 2,
232  theStep, theStep);
233  } else {
234  XDrawPoint(display, win, gc, theIColumn, theIRow);
235  }
236 
237  XFlush(display);
238 }
239 
240 #endif