Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
OpenGLArea.c
Go to the documentation of this file.
1/*
2#define DEBUG
3*/
4
5/*this*/
6#include "OpenGLAreaP.h"
7
8#include <X11/StringDefs.h>
9
10#include <GL/glx.h>
11
12#include <stdio.h>
13#include <stdlib.h>
14
15#ifdef __cplusplus
16extern "C"{
17#endif
18static void InitializeClass(void);
19static void InitializeWidget(Widget, Widget,ArgList,Cardinal*);
20static void RealizeWidget(Widget, XtValueMask*, XSetWindowAttributes*);
21static void DestroyWidget(Widget);
22static void ChangeWidgetSize(Widget);
23static void DrawWidget(Widget, XEvent*, Region);
24static Boolean SetValues(Widget,Widget,Widget,ArgList,Cardinal *);
25
26static void EventHandler(Widget,XtPointer,XEvent*,Boolean*);
27static int MakeCurrent(Widget);
28static void XWidgetInstallColormap(Widget);
29static void XWidgetUninstallColormap(Widget);
30static Widget XWidgetGetShell(Widget);
31#ifdef __cplusplus
32}
33#endif
34
35#define athis ((OpenGLAreaWidget)This)->openGLArea
36#define acur ((OpenGLAreaWidget)a_current)->openGLArea
37#define CWarn printf
38#define CWarnF printf
39
40static XtResource resources [] = {
41 {XoNdoubleBufferOn,"DoubleBufferOn",XtRBoolean,sizeof(Boolean),
42 XtOffset(OpenGLAreaWidget,openGLArea.doubleBufferOn),XtRImmediate,(XtPointer)True},
43 {XoNpaintCallback,XtCCallback,XtRCallback,sizeof(XtCallbackList),
44 XtOffset(OpenGLAreaWidget,openGLArea.paintCallback),XtRImmediate,(XtPointer)NULL},
45 {XoNeventCallback,XtCCallback,XtRCallback,sizeof(XtCallbackList),
46 XtOffset(OpenGLAreaWidget,openGLArea.eventCallback),XtRImmediate,(XtPointer)NULL}
47};
48
50/* Core Class Part */
51{
52 (WidgetClass) &compositeClassRec, /* pointer to superclass ClassRec */
53 "OpenGLArea", /* widget resource class name */
54 sizeof(OpenGLAreaRec), /* size in bytes of widget record */
55 InitializeClass, /* class_initialize */
56 NULL, /* dynamic initialization */
57 FALSE, /* has class been initialized? */
58 InitializeWidget, /* initialize */
59 NULL, /* notify that initialize called */
60 RealizeWidget, /* XCreateWindow for widget */
61 NULL, /* widget semantics name to proc mapWidget*/
62 0, /* number of entries in actions */
63 resources, /* resources for subclass fields */
64 XtNumber(resources), /* number of entries in resources */
65 NULLQUARK, /* resource class quarkified */
66 TRUE, /* compress MotionNotify for widget */
67 TRUE, /* compress Expose events for widget*/
68 TRUE, /* compress enter and leave events */
69 TRUE, /* select for VisibilityNotify */
70 DestroyWidget, /* free data for subclass pointers */
71 ChangeWidgetSize, /* geom manager changed widget size */
72 DrawWidget, /* rediplay window */
73 SetValues, /* set subclass resource values */
74 NULL, /* notify that SetValues called */
75 XtInheritSetValuesAlmost, /* SetValues got "Almost" geo reply*/
76 NULL, /* notify that get_values called */
77 XtInheritAcceptFocus, /* assign input focus to widget */
78 XtVersion, /* version of intrinsics used */
79 NULL, /* list of callback offsets */
80 XtInheritTranslations, /* translations */
81 XtInheritQueryGeometry, /* return preferred geometry */
82 XtInheritDisplayAccelerator, /* display your accelerator */
83 NULL /* pointer to extension record */
84},
85/* Composite Class Part */
86{
87 XtInheritGeometryManager, /* geometry manager for children */
88 XtInheritChangeManaged, /* change managed state of child */
89 XtInheritInsertChild, /* physically add child to parent */
90 XtInheritDeleteChild, /* physically remove child */
91 NULL /* pointer to extension record */
92},
93/* OpenGLArea */
94{
95 NULL
96}
97
98};
99
100WidgetClass openGLAreaWidgetClass = (WidgetClass) &openGLAreaClassRec;
101
102static void InitializeClass(void) {}
103
104static void InitializeWidget(Widget a_request,Widget This,ArgList a_args,Cardinal* a_argn) {
105 if(a_request->core.width<=0) This->core.width = 100;
106 if(a_request->core.height<=0) This->core.height = 100;
107
108#ifdef DEBUG
109 printf ("debug : OpenGLArea : InitializeWidget : %s\n",XtName(This));
110#endif
111
112 athis.visual = CopyFromParent;
113 athis.installColormap = False;
114 athis.glContext = NULL;
115
116 {Display* display;
117 Screen* screen;
118 int iscreen;
119 XVisualInfo* vinfo;
120 display = XtDisplay(This);
121 screen = XtScreen(This);
122 iscreen = XScreenNumberOfScreen(screen);
123
124 {int error,event;
125 if(glXQueryExtension(display,&error,&event)==0) {
126 CWarn ("X server does not have OpenGL extensions.\n");
127 }}
128
129 if(athis.doubleBufferOn==True) {
130 int atbs[] = {
131 GLX_RGBA,
132 GLX_RED_SIZE, 1,
133 GLX_GREEN_SIZE, 1,
134 GLX_BLUE_SIZE, 1,
135 GLX_ALPHA_SIZE, 1,
136 GLX_DEPTH_SIZE, 1,
137 GLX_DOUBLEBUFFER,
138 None
139 };
140 vinfo = glXChooseVisual (display,iscreen,atbs);
141 if(vinfo==NULL) { /*GLX_ALPHA_SIZE : problem with Xming. Try without it.*/
142 int atbs[] = {
143 GLX_RGBA,
144 GLX_RED_SIZE, 1,
145 GLX_GREEN_SIZE, 1,
146 GLX_BLUE_SIZE, 1,
147 GLX_DEPTH_SIZE, 1,
148 GLX_DOUBLEBUFFER,
149 None
150 };
151 vinfo = glXChooseVisual (display,iscreen,atbs);
152 }
153 } else {
154 int atbs[] = {
155 GLX_RGBA,
156 GLX_RED_SIZE, 1,
157 GLX_GREEN_SIZE, 1,
158 GLX_BLUE_SIZE, 1,
159 GLX_ALPHA_SIZE, 1,
160 GLX_DEPTH_SIZE, 1,
161 None
162 };
163 vinfo = glXChooseVisual (display,iscreen,atbs);
164 if(vinfo==NULL) { /*GLX_ALPHA_SIZE : problem with Xming. Try without it.*/
165 int atbs[] = {
166 GLX_RGBA,
167 GLX_RED_SIZE, 1,
168 GLX_GREEN_SIZE, 1,
169 GLX_BLUE_SIZE, 1,
170 GLX_DEPTH_SIZE, 1,
171 None
172 };
173 vinfo = glXChooseVisual (display,iscreen,atbs);
174 }
175 }
176
177 if(vinfo==NULL) {
178 CWarn ("Can't choose a visual.\n");
179 } else {
180 This->core.depth = vinfo->depth;
181 athis.visual = vinfo->visual;
182 if( (vinfo->depth ==DefaultDepth (display,iscreen)) &&
183 (vinfo->visual==DefaultVisual(display,iscreen)) ) {
184 This->core.colormap = XDefaultColormap (display,iscreen);
185 athis.installColormap = False;
186 } else {
187 This->core.colormap =
188 XCreateColormap (display,XRootWindow(display,iscreen),vinfo->visual, AllocNone);
189 athis.installColormap = True;
190 }
191 if(This->core.colormap==0L) {
192 CWarn ("Can't get/create a X colormap.\n");
193 }
194 athis.glContext = glXCreateContext (display,vinfo,NULL,GL_FALSE);
195 if(athis.glContext==NULL) {
196 CWarn ("Can't create a GLX context.\n");
197 }
198 XFree(vinfo);
199 }}
200
201 XtAddEventHandler(This,ButtonPressMask|ButtonReleaseMask|ButtonMotionMask,0,EventHandler,NULL);
202
203#ifdef DEBUG
204 printf("debug : OpenGLArea : InitializeWidget : end\n");
205#endif
206
207 /*avoid C++ warnings*/
208 a_request = NULL;
209 a_args = NULL;
210 a_argn = 0;
211}
212
213static void RealizeWidget(Widget This,XtValueMask* a_mask,XSetWindowAttributes* a_watbs) {
214#ifdef DEBUG
215 printf("debug : OpenGLArea : RealizeWidget : %s\n",XtName(This));
216#endif
217
218 /*Have to create window ourselves due to OpenGL that compells it's visual.*/
219 /*In principle colormap is correctly set in a_watbs.*/
220
221 XtCreateWindow(This,(unsigned int)InputOutput,athis.visual,*a_mask,a_watbs);
222
223 /* Call the Realize procedure (XtInheritRealize) */
224 if(openGLAreaWidgetClass->core_class.superclass->core_class.realize!=NULL)
225 (openGLAreaWidgetClass->core_class.superclass->core_class.realize)(This, a_mask, a_watbs);
226
227 /*If window is delete, all seems ok.*/
228 if(athis.installColormap==True) XWidgetInstallColormap(This);
229
230 /*MakeCurrent(This);*/
231
232#ifdef DEBUG
233 printf("debug : OpenGLArea : RealizeWidget : end\n");
234#endif
235}
236
237static void DestroyWidget(Widget This) {
238 if(athis.installColormap==True) {
239 XWidgetUninstallColormap (This);
240 athis.installColormap = False;
241 XFreeColormap(XtDisplay(This),This->core.colormap);
242 }
243 if(athis.glContext!=NULL) {
244 glXMakeCurrent(XtDisplay(This),None,NULL);
245 glXDestroyContext(XtDisplay(This),athis.glContext);
246 athis.glContext = NULL;
247 }
248}
249
250#define IFMOD(a_field) if(athis.a_field != acur.a_field)
251static Boolean SetValues(Widget a_current,Widget a_request,Widget This,ArgList a_args,Cardinal* a_argn) {
252 IFMOD(doubleBufferOn) {
253 /* Can't change buffering here if X window is created.
254 With OpenGL, buffering fix parameter of the X window.
255 Buffering must be choosen before the execution of the
256 Realize method that create the window. */
257 if(XtIsRealized(This) && (athis.installColormap==True)) {
258 CWarn("Can't change buffering after \"realization\" of the widget.\n");
259 athis.doubleBufferOn = acur.doubleBufferOn;
260 }
261 }
262 /*avoid C++ warnings*/
263 a_request = NULL;
264 a_args = NULL;
265 a_argn = 0;
266 return False;
267}
268
269static void ChangeWidgetSize(Widget This) {
270#ifdef DEBUG
271 printf("debug : OpenGLArea : ChangeWidgetSize : %s\n",XtName(This));
272#endif
273
274 /* Call the Resize procedure (XtInheritResize) */
275 if(openGLAreaWidgetClass->core_class.superclass->core_class.resize!=NULL)
276 (openGLAreaWidgetClass->core_class.superclass->core_class.resize)(This);
277
278#ifdef DEBUG
279 printf("debug : OpenGLArea : ChangeWidgetSize : end\n");
280#endif
281}
282
283static void DrawWidget(Widget This,XEvent* a_event,Region a_region) {
284#ifdef DEBUG
285 printf("debug : OpenGLArea : DrawWidget : %s\n",XtName(This));
286#endif
287
288 if(openGLAreaWidgetClass->core_class.superclass->core_class.expose!=NULL)
289 (openGLAreaWidgetClass->core_class.superclass->core_class.expose)(This,a_event,a_region);
290
291 if(MakeCurrent(This)==1) {
292#ifdef DEBUG
293 printf("debug : OpenGLArea : DrawWidget : %s : MakeCurrent ok : call paintCallback...\n",XtName(This));
294#endif
296 value.reason = XoCR_PAINT;
297 value.event = a_event;
298 XtCallCallbacks(This,XoNpaintCallback,(XtPointer)&value);
299 glXSwapBuffers(XtDisplay(This),XtWindow(This));
300 glXMakeCurrent(XtDisplay(This),None,NULL);
301 }
302
303#ifdef DEBUG
304 printf("debug : OpenGLArea : DrawWidget : end\n");
305#endif
306
307 /*avoid C++ warnings*/
308 a_event = NULL;
309 a_region = NULL;
310}
311
312
313/*------------------------------------------------------------------------*/
314/*------------------------------------------------------------------------*/
315/*------------------------------------------------------------------------*/
316
317void OpenGLAreaPaint(Widget This) {
318 if(!XtIsRealized(This)) return;
319 if(MakeCurrent(This)==1) {
321 value.reason = XoCR_PAINT;
322 value.event = 0;
323 XtCallCallbacks(This,XoNpaintCallback,(XtPointer)&value);
324 glXSwapBuffers(XtDisplay(This),XtWindow(This));
325 glXMakeCurrent(XtDisplay(This),None,NULL);
326 }
327}
328
329#ifdef TOOLS_XT_OPENGLAREA_HAS_GL2PS
330
331#include <tools/c_gl2ps.h>
332
333int OpenGLAreaWrite_gl2ps(Widget This,const char* aFileName,const char* opts) {
334 FILE* file;
335 int options;
336 int sort;
337 inlib_GLint vp[4];
338 int bufsize = 0;
339 static inlib_gl2ps_gl_funcs_t s_OpenGL_funcs = {
340 glIsEnabled,
341 glBegin,
342 glEnd,
343 glGetFloatv,
344 glVertex3f,
345 glGetBooleanv,
346 glGetIntegerv,
347 glRenderMode,
348 glFeedbackBuffer,
349 glPassThrough
350 };
351
352 file = fopen(aFileName,"w");
353 if(!file) return 1;
354
355 inlib_c_gl2ps_set_gl_funcs(&s_OpenGL_funcs);
356
362 //sort = TOOLS_GL2PS_SIMPLE_SORT;
363
364 vp[0] = 0;
365 vp[1] = 0;
366 vp[2] = This->core.width;
367 vp[3] = This->core.height;
368
369 inlib_c_gl2psBeginPage("title","exlib_Xt_OpenGLArea",
370 vp,TOOLS_GL2PS_EPS,sort,options,
371 TOOLS_GL_RGBA,0, NULL,0,0,0,bufsize,
372 file,aFileName);
373
374 {XoAnyCallbackStruct value;
375 value.reason = XoCR_PAINT;
376 value.event = 0;
377 XtCallCallbacks(This,XoNpaintCallback,(XtPointer)&value);}
378
379 inlib_c_gl2psEndPage();
380
381 inlib_c_gl2ps_reset_gl_funcs();
382
383 fclose(file);
384
385 return 0;
386}
387
388#else
389#ifdef __cplusplus
390int OpenGLAreaWrite_gl2ps(Widget,const char*,const char*) {return 1;}
391#else
392int OpenGLAreaWrite_gl2ps(Widget w,const char* f,const char* o) {return 1;}
393#endif
394#endif
395
396/*------------------------------------------------------------------------*/
397/*------------------------------------------------------------------------*/
398/*------------------------------------------------------------------------*/
399/*------------------------------------------------------------------------*/
400static int MakeCurrent(Widget This) {
401 if(This==NULL) return 0;
402 if(!XtIsRealized(This)) return 0;
403 if(athis.glContext==NULL) return 0;
404 return (int)glXMakeCurrent(XtDisplay(This),XtWindow(This),athis.glContext);
405}
406
407static void EventHandler(Widget This,XtPointer a_tag,XEvent* a_event ,Boolean* a_continue) {
409 value.reason = XoCR_EVENT;
410 value.event = a_event;
411 XtCallCallbacks(This,XoNeventCallback,(XtPointer)&value);
412 a_tag = NULL;
413 a_continue = NULL;
414}
415
416/*------------------------------------------------------------------------*/
417/*------------------------------------------------------------------------*/
418/*------------------------------------------------------------------------*/
419static void XWidgetInstallColormap(Widget This) {
420/*
421 From Mesa/widgets/GLwDrawingArea.c/post_colormap routine.
422 Could use also XtSetWMColormapWindows.
423*/
424 Display* display;
425 XWindowAttributes watbs;
426 Widget shell;
427 Window* ws = NULL;
428 int wn = 0,found,count;
429 Window wshell,wthis;
430 Colormap cmapthis;
431/*.........................................................................*/
432 if(This==NULL) return;
433 if( !XtIsWidget(This) || !XtIsRealized(This) ) return;
434 shell = XWidgetGetShell (This);
435 if(shell==NULL) return;
436 display = XtDisplay (This);
437 wthis = XtWindow (This);
438 wshell = XtWindow (shell);
439 XGetWMColormapWindows (display,wshell, &ws, &wn);
440/* Check if colormap of this is a colormap of a Window in list.*/
441 XGetWindowAttributes (display,wthis,&watbs);
442 cmapthis = watbs.colormap;
443 found = -1;
444 for(count=0;count<wn;count++) {
445 Colormap cmap;
446 XGetWindowAttributes (display,ws[count],&watbs);
447 cmap = watbs.colormap;
448 if(cmap==cmapthis) {
449 XFree (ws);
450 return; /*done*/
451 }
452 if(ws[count]==wshell) {
453 found = count;
454 }
455 }
456 /*Have to add window of this in list.*/
457 if(wn==0) {
458 if(ws!=NULL) XFree(ws);
459 ws = (Window*)malloc ( 2 * sizeof(Window));
460 } else {
461 ws = (Window*)realloc (ws,(wn + 2) * sizeof(Window));
462 }
463 if(ws==NULL) return;
464 if(found==-1) {
465 /*Window of shell not in list.*/
466 ws[wn] = wthis; wn++;
467 ws[wn] = wshell;wn++;
468 } else {
469 ws[found] = wthis;
470 ws[wn] = wshell; wn++; /*Shell must be last.*/
471 }
472 if (XSetWMColormapWindows(display,wshell, ws, wn)==0) {
473 CWarnF ("XWidgetInstallColormap: can't install colormap of %s in %s.\n",XtName(This),XtName(shell));
474 }
475 XFree (ws);
476}
477
478static void XWidgetUninstallColormap(Widget This) {
479 int count;
480 Widget shell;
481 Display* display;
482 Window wthis,wshell;
483 Window* ws = NULL;
484 int wn = 0;
485 Window* nws = NULL;
486 int nwn = 0;
487/*.........................................................................*/
488 if(This==NULL) return;
489 if( !XtIsWidget(This) || !XtIsRealized(This) ) return;
490 shell = XWidgetGetShell (This);
491 if(shell==NULL) return;
492 display = XtDisplay (This);
493 wthis = XtWindow (This);
494 wshell = XtWindow (shell);
495 XGetWMColormapWindows (display,wshell, &ws, &wn);
496 if( (wn==0) || (ws==NULL) ) return;
497 nws = (Window*)malloc ( wn * sizeof(Window));
498 if(nws==NULL) {
499 XFree (ws);
500 return;
501 }
502 nwn = 0;
503 for(count=0;count<wn;count++) {
504 if(ws[count]!=wthis) {
505 nws[nwn] = ws[count];
506 nwn++;
507 }
508 }
509 if(wn!=nwn) {
510 if (XSetWMColormapWindows(display,wshell, nws, nwn)==0) {
511 CWarnF("XWidgetUninstallColormap: can't install colormap of %s in %s.\n",XtName(This),XtName(shell));
512 }
513 }
514 XFree (ws);
515 XFree (nws);
516}
517
518Widget XWidgetGetShell(Widget This) {
519 Widget widget;
520 if(This==NULL) return NULL;
521 widget = This;
522 while(1) {
523 if(widget==NULL) return NULL;
524 if(XtIsShell(widget)) return widget;
525 widget = XtParent(widget);
526 }
527}
528
529/*
530exlib_build_use Xt inlib
531*/
#define TRUE
Definition: Globals.hh:27
#define FALSE
Definition: Globals.hh:23
#define athis
Definition: OpenGLArea.c:35
#define acur
Definition: OpenGLArea.c:36
#define CWarnF
Definition: OpenGLArea.c:38
#define IFMOD(a_field)
Definition: OpenGLArea.c:250
OpenGLAreaClassRec openGLAreaClassRec
Definition: OpenGLArea.c:49
#define CWarn
Definition: OpenGLArea.c:37
int OpenGLAreaWrite_gl2ps(Widget w, const char *f, const char *o)
Definition: OpenGLArea.c:392
WidgetClass openGLAreaWidgetClass
Definition: OpenGLArea.c:100
void OpenGLAreaPaint(Widget This)
Definition: OpenGLArea.c:317
#define XoNeventCallback
Definition: OpenGLArea.h:17
#define XoCR_PAINT
Definition: OpenGLArea.h:19
#define XoNpaintCallback
Definition: OpenGLArea.h:16
#define XoCR_EVENT
Definition: OpenGLArea.h:20
#define XoNdoubleBufferOn
Definition: OpenGLArea.h:15
#define TOOLS_GL2PS_OCCLUSION_CULL
Definition: gl2ps_def.h:64
#define TOOLS_GL2PS_BEST_ROOT
Definition: gl2ps_def.h:63
#define TOOLS_GL2PS_BSP_SORT
Definition: gl2ps_def.h:45
#define TOOLS_GL2PS_EPS
Definition: gl2ps_def.h:35
#define TOOLS_GL_RGBA
Definition: gl2ps_def.h:143
#define TOOLS_GL2PS_DRAW_BACKGROUND
Definition: gl2ps_def.h:60
#define TOOLS_GL2PS_SILENT
Definition: gl2ps_def.h:62