source: trunk/source/visualization/RayTracer/src/G4RTXScanner.cc @ 1315

Last change on this file since 1315 was 1315, checked in by garnier, 14 years ago

update geant4-09-04-beta-cand-01 interfaces-V09-03-09 vis-V09-03-08

File size: 7.3 KB
Line 
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: G4RTXScanner.cc,v 1.8 2010/06/14 14:33:34 gcosmo Exp $
28// GEANT4 tag $Name: vis-V09-03-08 $
29//
30//
31
32#ifdef G4VIS_BUILD_RAYTRACERX_DRIVER
33
34#include "G4RTXScanner.hh"
35
36#include "G4TheRayTracer.hh"
37#include "G4RayTracerXViewer.hh"
38#include "G4ViewParameters.hh"
39#include <X11/Xlib.h>
40#include <X11/Xutil.h>
41#include <X11/Xatom.h>
42
43extern "C" {
44  Bool G4RayTracerXScannerWaitForNotify (Display*, XEvent* e, char* arg) {
45    return (e->type == MapNotify) && (e->xmap.window == (Window) arg);
46  }
47}
48
49G4RTXScanner::G4RTXScanner():
50  G4VRTScanner(), theNRow(0), theNColumn(0), theIRow(0), theIColumn(0)
51{
52  theGSName = "RayTracerX";
53  theGSNickname = "RayTracerX";
54}
55
56G4RTXScanner::~G4RTXScanner() {}
57
58const G4String& G4RTXScanner::GetGSName() const
59{return theGSName;}
60
61const G4String& G4RTXScanner::GetGSNickname() const
62{return theGSNickname;}
63
64void 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
79G4bool 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
111G4bool 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 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 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
218void G4RTXScanner::Draw
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
Note: See TracBrowser for help on using the repository browser.