Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/toolx/Xt/OpenGLArea is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef toolx_Xt_OpenGLArea
0005 #define toolx_Xt_OpenGLArea
0006 
0007 #include <X11/IntrinsicP.h>
0008 #include <X11/CoreP.h>
0009 #include <X11/CompositeP.h>
0010 #include <X11/StringDefs.h>
0011 
0012 #ifndef GL_GLEXT_LEGACY
0013 #define GL_GLEXT_LEGACY
0014 #endif
0015 #include <GL/gl.h>
0016 
0017 #ifndef GL_GLEXT_PROTOTYPES
0018 #define GL_GLEXT_PROTOTYPES
0019 #endif
0020 #include <GL/glext.h>
0021 
0022 #include <GL/glx.h>
0023 
0024 #include <stdio.h>
0025 #include <stdlib.h>
0026 #include <stdarg.h>
0027 
0028 namespace toolx {
0029 namespace Xt {
0030 
0031 ///////////////////////////////////////////////////////////
0032 ///////////////////////////////////////////////////////////
0033 ///////////////////////////////////////////////////////////
0034 
0035 typedef struct _OpenGLAreaClassRec* OpenGLAreaWidgetClass;
0036 typedef struct _OpenGLAreaRec* OpenGLAreaWidget;
0037 
0038 typedef struct {
0039  int reason;
0040  XEvent* event;
0041 } XoAnyCallbackStruct;
0042 
0043 #define XoCR_PAINT 1
0044 #define XoCR_EVENT 2
0045 
0046 #define XoNdoubleBufferOn toolx::Xt::OpenGLArea::XoN_doubleBufferOn()
0047 #define XoNpaintCallback  toolx::Xt::OpenGLArea::XoN_paintCallback()
0048 #define XoNeventCallback  toolx::Xt::OpenGLArea::XoN_eventCallback()
0049 
0050 ///////////////////////////////////////////////////////////
0051 ///////////////////////////////////////////////////////////
0052 ///////////////////////////////////////////////////////////
0053 
0054 typedef struct {
0055   void* extension;
0056 } OpenGLAreaClassPart;
0057 
0058 typedef struct _OpenGLAreaClassRec {
0059   CoreClassPart core_class;
0060   CompositeClassPart composite_class;
0061   OpenGLAreaClassPart openGLArea_class;
0062 } OpenGLAreaClassRec;
0063 
0064 typedef struct {
0065   Boolean doubleBufferOn;
0066   XtCallbackList paintCallback;
0067   XtCallbackList eventCallback;
0068   Visual* visual;
0069   Boolean installColormap;
0070   GLXContext glContext;
0071 } OpenGLAreaPart;
0072 
0073 typedef struct _OpenGLAreaRec {
0074   CorePart core;
0075   CompositePart composite;
0076   OpenGLAreaPart openGLArea;
0077 } OpenGLAreaRec;
0078 
0079 ///////////////////////////////////////////////////////////
0080 ///////////////////////////////////////////////////////////
0081 ///////////////////////////////////////////////////////////
0082 
0083 class OpenGLArea {
0084 protected:
0085   static const char* class_name()         {static const char* s_s = "OpenGLArea";return s_s;}
0086   static const char* XoC_DoubleBufferOn() {static const char* s_s = "DoubleBufferOn";return s_s;}
0087 public:
0088   static const char* XoN_doubleBufferOn() {static const char* s_s = "doubleBufferOn";return s_s;}
0089   static const char* XoN_paintCallback()  {static const char* s_s = "paintCallback";return s_s;}
0090   static const char* XoN_eventCallback()  {static const char* s_s = "eventCallback";return s_s;}
0091 public:
0092   static void paint(Widget a_this) {
0093     if(!XtIsRealized(a_this)) return;
0094     if(make_current(a_this)==1) {
0095       XoAnyCallbackStruct value;
0096       value.reason = XoCR_PAINT;
0097       value.event = 0;
0098       ::XtCallCallbacks(a_this,XoNpaintCallback,(XtPointer)&value);
0099       ::glXSwapBuffers(XtDisplay(a_this),XtWindow(a_this));
0100       ::glXMakeCurrent(XtDisplay(a_this),None,NULL);
0101     }
0102   }
0103 protected:
0104   static void initialize_class(void) {}
0105 
0106   static void initialize_widget(Widget a_request,Widget a_this,ArgList,Cardinal*) {
0107     if(a_request->core.width<=0)  a_this->core.width  = 100;
0108     if(a_request->core.height<=0) a_this->core.height = 100;
0109 
0110     OpenGLAreaPart& athis = _athis(a_this);
0111     athis.visual          = CopyFromParent;
0112     athis.installColormap = False;
0113     athis.glContext       = NULL;
0114 
0115     Display* display;
0116     Screen* screen;
0117     int iscreen;
0118     XVisualInfo* vinfo;
0119     display = XtDisplay(a_this);
0120     screen = XtScreen(a_this);
0121     iscreen = XScreenNumberOfScreen(screen);
0122   
0123    {int error,event;
0124     if(::glXQueryExtension(display,&error,&event)==0) {
0125       CWarn ("X server does not have OpenGL extensions.\n");
0126     }}
0127   
0128     if(athis.doubleBufferOn==True) {
0129       int atbs_1[] = {
0130         GLX_RGBA,
0131         GLX_RED_SIZE,   1,
0132         GLX_GREEN_SIZE, 1,
0133         GLX_BLUE_SIZE,  1,
0134         GLX_ALPHA_SIZE, 1,
0135         GLX_DEPTH_SIZE, 1,
0136         GLX_DOUBLEBUFFER,
0137         None
0138       };
0139       vinfo = ::glXChooseVisual  (display,iscreen,atbs_1);
0140       if(vinfo==NULL) { //GLX_ALPHA_SIZE : problem with Xming. Try without it.
0141         int atbs_2[] = {
0142           GLX_RGBA,
0143           GLX_RED_SIZE,   1,
0144           GLX_GREEN_SIZE, 1,
0145           GLX_BLUE_SIZE,  1,
0146           GLX_DEPTH_SIZE, 1,
0147           GLX_DOUBLEBUFFER,
0148           None
0149         };
0150         vinfo = ::glXChooseVisual  (display,iscreen,atbs_2);
0151       }
0152     } else {
0153       int atbs_1[] = {
0154         GLX_RGBA,
0155         GLX_RED_SIZE,   1,
0156         GLX_GREEN_SIZE, 1,
0157         GLX_BLUE_SIZE,  1,
0158         GLX_ALPHA_SIZE, 1,
0159         GLX_DEPTH_SIZE, 1,
0160         None
0161       };
0162       vinfo = ::glXChooseVisual  (display,iscreen,atbs_1);
0163       if(vinfo==NULL) { //GLX_ALPHA_SIZE : problem with Xming. Try without it.
0164         int atbs_2[] = {
0165           GLX_RGBA,
0166           GLX_RED_SIZE,   1,
0167           GLX_GREEN_SIZE, 1,
0168           GLX_BLUE_SIZE,  1,
0169           GLX_DEPTH_SIZE, 1,
0170           None
0171         };
0172         vinfo = ::glXChooseVisual  (display,iscreen,atbs_2);
0173       }
0174     }
0175   
0176     if(vinfo==NULL) {
0177       CWarn ("Can't choose a visual.\n");
0178     } else {
0179       a_this->core.depth = vinfo->depth;
0180       athis.visual = vinfo->visual;
0181       if( (vinfo->depth ==DefaultDepth (display,iscreen))  &&
0182           (vinfo->visual==DefaultVisual(display,iscreen)) ) {
0183         a_this->core.colormap = XDefaultColormap (display,iscreen);
0184         athis.installColormap = False;
0185       } else {
0186         a_this->core.colormap =
0187         XCreateColormap (display,XRootWindow(display,iscreen),vinfo->visual, AllocNone);
0188         athis.installColormap = True;
0189       }  
0190       if(a_this->core.colormap==0L) {
0191         CWarn ("Can't get/create a X colormap.\n");
0192       }  
0193       athis.glContext = ::glXCreateContext (display,vinfo,NULL,GL_TRUE);
0194       if(athis.glContext==NULL) {
0195         athis.glContext = ::glXCreateContext (display,vinfo,NULL,GL_FALSE);
0196         if(athis.glContext==NULL) {
0197           CWarn ("Can't create a GLX context.\n");
0198         }
0199       }
0200       ::XFree(vinfo);
0201     }
0202 
0203     ::XtAddEventHandler
0204        (a_this,ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|KeyPressMask|KeyReleaseMask,0,event_handler,NULL);
0205   }
0206 
0207   static void realize_widget(Widget a_this,XtValueMask* a_mask,XSetWindowAttributes* a_watbs) {
0208 
0209     // Have to create window ourselves due to OpenGL that compells it's visual.
0210     // In principle colormap is correctly set in a_watbsy.
0211   
0212     OpenGLAreaPart& athis = _athis(a_this);
0213     
0214     ::XtCreateWindow(a_this,(unsigned int)InputOutput,athis.visual,*a_mask,a_watbs);
0215   
0216     // Call the Realize procedure (XtInheritRealize) :
0217     if(widget_class()->core_class.superclass->core_class.realize!=NULL)
0218       (widget_class()->core_class.superclass->core_class.realize)(a_this, a_mask, a_watbs);
0219   
0220     // If window is delete, all seems ok :
0221     if(athis.installColormap==True) install_colormap(a_this);
0222   
0223   }
0224 
0225   static void destroy_widget(Widget a_this) {
0226     OpenGLAreaPart& athis = _athis(a_this);
0227     if(athis.installColormap==True) {
0228       uninstall_colormap (a_this);
0229       athis.installColormap    = False;
0230       ::XFreeColormap(XtDisplay(a_this),a_this->core.colormap);
0231     }
0232     if(athis.glContext!=NULL) {
0233       ::glXMakeCurrent(XtDisplay(a_this),None,NULL);
0234       ::glXDestroyContext(XtDisplay(a_this),athis.glContext);
0235       athis.glContext = NULL;
0236     }
0237   }
0238 
0239   static Boolean set_values(Widget a_current,Widget,Widget a_this,ArgList,Cardinal*) {
0240     OpenGLAreaPart& athis = _athis(a_this);
0241     if(athis.doubleBufferOn != ((OpenGLAreaWidget)a_current)->openGLArea.doubleBufferOn) {
0242       // Can't change buffering here if X window is created.
0243       // With OpenGL, buffering fix parameter of the X window.
0244       // Buffering must be choosen before the execution of the
0245       // Realize method that create the window.
0246       if(XtIsRealized(a_this) && (athis.installColormap==True)) {
0247         CWarn("Can't change buffering after \"realization\" of the widget.\n");
0248         athis.doubleBufferOn = ((OpenGLAreaWidget)a_current)->openGLArea.doubleBufferOn;
0249       }
0250     }
0251     return False;
0252   }
0253   
0254   static void change_widget_size(Widget a_this) {
0255     // Call the Resize procedure (XtInheritResize) :
0256     if(widget_class()->core_class.superclass->core_class.resize!=NULL)
0257       (widget_class()->core_class.superclass->core_class.resize)(a_this);
0258 }
0259 
0260   static void draw_widget(Widget  a_this,XEvent* a_event,Region a_region) {
0261     if(widget_class()->core_class.superclass->core_class.expose!=NULL)
0262       (widget_class()->core_class.superclass->core_class.expose)(a_this,a_event,a_region);
0263 
0264     if(make_current(a_this)==1) {
0265       XoAnyCallbackStruct value;
0266       value.reason = XoCR_PAINT;
0267       value.event = a_event;
0268       ::XtCallCallbacks(a_this,XoNpaintCallback,(XtPointer)&value);
0269       ::glXSwapBuffers(XtDisplay(a_this),XtWindow(a_this));
0270       ::glXMakeCurrent(XtDisplay(a_this),None,NULL);
0271     }
0272   }
0273 
0274 protected:
0275   static OpenGLAreaPart& _athis(Widget a_this) {return *(&(((OpenGLAreaWidget)a_this)->openGLArea));}
0276   static void CWarn(const char* a_msg) {
0277     ::printf("%s",a_msg);
0278   }
0279   static void CWarnF(const char* a_format,...) {
0280     va_list args;
0281     va_start(args,a_format);
0282     ::vprintf(a_format,args);
0283     va_end(args);
0284   }
0285   static int make_current(Widget a_this) {
0286     if(!XtIsRealized(a_this)) return 0;
0287     OpenGLAreaPart& athis = _athis(a_this);
0288     if(athis.glContext==NULL) return 0;
0289     return (int)::glXMakeCurrent(XtDisplay(a_this),XtWindow(a_this),athis.glContext);
0290   }
0291 
0292   static void event_handler(Widget a_this,XtPointer,XEvent* a_event ,Boolean*) {
0293     XoAnyCallbackStruct value;
0294     value.reason = XoCR_EVENT;
0295     value.event = a_event;
0296     ::XtCallCallbacks(a_this,XoNeventCallback,(XtPointer)&value);
0297   }
0298 
0299   static void install_colormap(Widget a_this) {
0300     // From Mesa/widgets/GLwDrawingArea.c/post_colormap routine.
0301     // Could use also XtSetWMColormapWindows.
0302     if( !XtIsWidget(a_this) || !XtIsRealized(a_this) ) return;
0303     Widget shell = get_shell(a_this);
0304     if(shell==NULL) return;
0305     Display* display = XtDisplay (a_this);
0306     Window wthis   = XtWindow  (a_this);
0307     Window wshell  = XtWindow  (shell);
0308     Window*           ws = NULL;
0309     int               wn = 0;
0310     ::XGetWMColormapWindows (display,wshell, &ws, &wn);
0311     // Check if colormap of this is a colormap of a Window in list :
0312     XWindowAttributes watbs;
0313     XGetWindowAttributes  (display,wthis,&watbs);
0314     Colormap cmapthis = watbs.colormap;
0315     int found                 = -1;
0316     for(int count=0;count<wn;count++) {
0317       Colormap             cmap;
0318       XGetWindowAttributes (display,ws[count],&watbs);
0319       cmap                 = watbs.colormap;
0320       if(cmap==cmapthis) {
0321         ::XFree (ws);
0322         return;
0323       }
0324       if(ws[count]==wshell) {
0325         found = count;
0326       }
0327     }
0328     // Have to add window of this in list :
0329     if(wn==0) {
0330       if(ws!=NULL) ::XFree(ws);
0331       ws = (Window*)::malloc( 2 * sizeof(Window));
0332     } else {
0333       ws = (Window*)::realloc(ws,(wn + 2) * sizeof(Window));
0334     }
0335     if(ws==NULL) return;
0336     if(found==-1) {
0337       // Window of shell not in list :
0338       ws[wn] = wthis; wn++;
0339       ws[wn] = wshell;wn++;
0340     } else {
0341       ws[found] = wthis;
0342       ws[wn]    = wshell; wn++;  // Shell must be last.
0343     }
0344     if (::XSetWMColormapWindows(display,wshell, ws, wn)==0) {
0345       CWarnF ("install_colormap: can't install colormap of %s in %s.\n",XtName(a_this),XtName(shell));
0346     }
0347     ::free(ws);
0348   }
0349 
0350   static void uninstall_colormap(Widget a_this) {
0351     if( !XtIsWidget(a_this) || !XtIsRealized(a_this) ) return;
0352     Widget shell = get_shell (a_this);
0353     if(shell==NULL) return;
0354     Display* display = XtDisplay (a_this);
0355     Window wthis     = XtWindow  (a_this);
0356     Window wshell    = XtWindow  (shell);
0357     Window*           ws  = NULL;
0358     int               wn  = 0;
0359     ::XGetWMColormapWindows (display,wshell, &ws, &wn);
0360     if( (wn==0) || (ws==NULL) ) return;
0361     Window* nws = (Window*)::malloc( wn  * sizeof(Window));
0362     if(nws==NULL) {
0363       ::XFree (ws);
0364       return;
0365     }
0366     int nwn = 0;
0367     for(int count=0;count<wn;count++) {
0368       if(ws[count]!=wthis) {
0369         nws[nwn] = ws[count];
0370         nwn++;
0371       }
0372     }
0373     if(wn!=nwn) {
0374       if (::XSetWMColormapWindows(display,wshell, nws, nwn)==0) {
0375         CWarnF("uninstall_colormap: can't install colormap of %s in %s.\n",XtName(a_this),XtName(shell));
0376       }
0377     }
0378     ::XFree (ws);
0379     ::free (nws);
0380   }
0381   
0382   static Widget get_shell(Widget a_this) {
0383     Widget widget = a_this;
0384     while(1) {
0385       if(widget==NULL) return NULL;
0386       if(XtIsShell(widget)) return widget;
0387       widget = XtParent(widget);
0388     }
0389   }
0390 
0391 public:
0392   static WidgetClass widget_class() {
0393     static XtResource s_resources[] = {
0394       {(String)XoN_doubleBufferOn(),(String)XoC_DoubleBufferOn(),XtRBoolean,sizeof(Boolean),
0395        XtOffset(OpenGLAreaWidget,openGLArea.doubleBufferOn),XtRImmediate,(XtPointer)True},
0396       {(String)XoN_paintCallback(),XtCCallback,XtRCallback,sizeof(XtCallbackList),
0397        XtOffset(OpenGLAreaWidget,openGLArea.paintCallback),XtRImmediate,(XtPointer)NULL},
0398       {(String)XoN_eventCallback(),XtCCallback,XtRCallback,sizeof(XtCallbackList),
0399        XtOffset(OpenGLAreaWidget,openGLArea.eventCallback),XtRImmediate,(XtPointer)NULL}
0400     };
0401 
0402     static OpenGLAreaClassRec s_openGLAreaClassRec = {
0403       // Core Class Part :
0404       {
0405         (WidgetClass) &compositeClassRec, // pointer to superclass ClassRec   
0406         (String)class_name(),             // widget resource class name
0407         sizeof(OpenGLAreaRec),           // size in bytes of widget record   
0408         initialize_class,                // class_initialize                 
0409         NULL,                            // dynamic initialization           
0410         FALSE,                           // has class been initialized?      
0411         initialize_widget,               // initialize                       
0412         NULL,                            // notify that initialize called    
0413         realize_widget,                  // XCreateWindow for widget         
0414         NULL,                            // widget semantics name to proc mapWidget
0415         0,                               // number of entries in actions     
0416         s_resources,                     // resources for subclass fields    
0417         XtNumber(s_resources),           // number of entries in resources   
0418         NULLQUARK,                       // resource class quarkified        
0419         TRUE,                            // compress MotionNotify for widget 
0420         TRUE,                            // compress Expose events for widget
0421         TRUE,                            // compress enter and leave events  
0422         TRUE,                            // select for VisibilityNotify      
0423         destroy_widget,                  // free data for subclass pointers  
0424         change_widget_size,              // geom manager changed widget size 
0425         draw_widget,                     // rediplay window                  
0426         set_values,                      // set subclass resource values     
0427         NULL,                            // notify that SetValues called    
0428         XtInheritSetValuesAlmost,        // SetValues got "Almost" geo reply
0429         NULL,                            // notify that get_values called    
0430         XtInheritAcceptFocus,            // assign input focus to widget     
0431         XtVersion,                       // version of intrinsics used       
0432         NULL,                            // list of callback offsets         
0433         XtInheritTranslations,           // translations                     
0434         XtInheritQueryGeometry,          // return preferred geometry        
0435         XtInheritDisplayAccelerator,     // display your accelerator         
0436         NULL                             // pointer to extension record      
0437       },
0438       // Composite Class Part :
0439       {
0440         XtInheritGeometryManager,   // geometry manager for children   
0441         XtInheritChangeManaged,     // change managed state of child   
0442         XtInheritInsertChild,       // physically add child to parent  
0443         XtInheritDeleteChild,       // physically remove child             
0444         NULL                        // pointer to extension record     
0445       },
0446       // OpenGLArea :
0447       {
0448         NULL
0449       }
0450     };
0451     return (WidgetClass)&s_openGLAreaClassRec;
0452   }
0453 };
0454 
0455 }}
0456 
0457 #endif