Import Geant4 11.0.0.beta source tree
This commit is contained in:
@@ -0,0 +1,481 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_Xt_OpenGLArea
|
||||
#define tools_Xt_OpenGLArea
|
||||
|
||||
#include <X11/IntrinsicP.h>
|
||||
#include <X11/CoreP.h>
|
||||
#include <X11/CompositeP.h>
|
||||
#include <X11/StringDefs.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace tools {
|
||||
namespace Xt {
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct _OpenGLAreaClassRec* OpenGLAreaWidgetClass;
|
||||
typedef struct _OpenGLAreaRec* OpenGLAreaWidget;
|
||||
|
||||
typedef struct {
|
||||
int reason;
|
||||
XEvent* event;
|
||||
} XoAnyCallbackStruct;
|
||||
|
||||
#define XoNdoubleBufferOn "doubleBufferOn"
|
||||
#define XoNpaintCallback "paintCallback"
|
||||
#define XoNeventCallback "eventCallback"
|
||||
|
||||
#define XoCR_PAINT 1
|
||||
#define XoCR_EVENT 2
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct {
|
||||
void* extension;
|
||||
} OpenGLAreaClassPart;
|
||||
|
||||
typedef struct _OpenGLAreaClassRec {
|
||||
CoreClassPart core_class;
|
||||
CompositeClassPart composite_class;
|
||||
OpenGLAreaClassPart openGLArea_class;
|
||||
} OpenGLAreaClassRec;
|
||||
|
||||
typedef struct {
|
||||
Boolean doubleBufferOn;
|
||||
XtCallbackList paintCallback;
|
||||
XtCallbackList eventCallback;
|
||||
Visual* visual;
|
||||
Boolean installColormap;
|
||||
GLXContext glContext;
|
||||
} OpenGLAreaPart;
|
||||
|
||||
typedef struct _OpenGLAreaRec {
|
||||
CorePart core;
|
||||
CompositePart composite;
|
||||
OpenGLAreaPart openGLArea;
|
||||
} OpenGLAreaRec;
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class OpenGLArea {
|
||||
public:
|
||||
static void paint(Widget a_this) {
|
||||
if(!XtIsRealized(a_this)) return;
|
||||
if(make_current(a_this)==1) {
|
||||
XoAnyCallbackStruct value;
|
||||
value.reason = XoCR_PAINT;
|
||||
value.event = 0;
|
||||
::XtCallCallbacks(a_this,XoNpaintCallback,(XtPointer)&value);
|
||||
::glXSwapBuffers(XtDisplay(a_this),XtWindow(a_this));
|
||||
::glXMakeCurrent(XtDisplay(a_this),None,NULL);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
static void initialize_class(void) {}
|
||||
|
||||
static void initialize_widget(Widget a_request,Widget a_this,ArgList,Cardinal*) {
|
||||
if(a_request->core.width<=0) a_this->core.width = 100;
|
||||
if(a_request->core.height<=0) a_this->core.height = 100;
|
||||
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
::printf ("debug : OpenGLArea : InitializeWidget : %s\n",::XtName(a_this));
|
||||
#endif
|
||||
|
||||
OpenGLAreaPart& athis = _athis(a_this);
|
||||
athis.visual = CopyFromParent;
|
||||
athis.installColormap = False;
|
||||
athis.glContext = NULL;
|
||||
|
||||
Display* display;
|
||||
Screen* screen;
|
||||
int iscreen;
|
||||
XVisualInfo* vinfo;
|
||||
display = XtDisplay(a_this);
|
||||
screen = XtScreen(a_this);
|
||||
iscreen = XScreenNumberOfScreen(screen);
|
||||
|
||||
{int error,event;
|
||||
if(::glXQueryExtension(display,&error,&event)==0) {
|
||||
CWarn ("X server does not have OpenGL extensions.\n");
|
||||
}}
|
||||
|
||||
if(athis.doubleBufferOn==True) {
|
||||
int atbs_1[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_ALPHA_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None
|
||||
};
|
||||
vinfo = ::glXChooseVisual (display,iscreen,atbs_1);
|
||||
if(vinfo==NULL) { //GLX_ALPHA_SIZE : problem with Xming. Try without it.
|
||||
int atbs_2[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None
|
||||
};
|
||||
vinfo = ::glXChooseVisual (display,iscreen,atbs_2);
|
||||
}
|
||||
} else {
|
||||
int atbs_1[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_ALPHA_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None
|
||||
};
|
||||
vinfo = ::glXChooseVisual (display,iscreen,atbs_1);
|
||||
if(vinfo==NULL) { //GLX_ALPHA_SIZE : problem with Xming. Try without it.
|
||||
int atbs_2[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None
|
||||
};
|
||||
vinfo = ::glXChooseVisual (display,iscreen,atbs_2);
|
||||
}
|
||||
}
|
||||
|
||||
if(vinfo==NULL) {
|
||||
CWarn ("Can't choose a visual.\n");
|
||||
} else {
|
||||
a_this->core.depth = vinfo->depth;
|
||||
athis.visual = vinfo->visual;
|
||||
if( (vinfo->depth ==DefaultDepth (display,iscreen)) &&
|
||||
(vinfo->visual==DefaultVisual(display,iscreen)) ) {
|
||||
a_this->core.colormap = XDefaultColormap (display,iscreen);
|
||||
athis.installColormap = False;
|
||||
} else {
|
||||
a_this->core.colormap =
|
||||
XCreateColormap (display,XRootWindow(display,iscreen),vinfo->visual, AllocNone);
|
||||
athis.installColormap = True;
|
||||
}
|
||||
if(a_this->core.colormap==0L) {
|
||||
CWarn ("Can't get/create a X colormap.\n");
|
||||
}
|
||||
athis.glContext = ::glXCreateContext (display,vinfo,NULL,GL_TRUE);
|
||||
if(athis.glContext==NULL) {
|
||||
athis.glContext = ::glXCreateContext (display,vinfo,NULL,GL_FALSE);
|
||||
if(athis.glContext==NULL) {
|
||||
CWarn ("Can't create a GLX context.\n");
|
||||
}
|
||||
}
|
||||
::XFree(vinfo);
|
||||
}
|
||||
|
||||
::XtAddEventHandler
|
||||
(a_this,ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|KeyPressMask|KeyReleaseMask,0,event_handler,NULL);
|
||||
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : InitializeWidget : end\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void realize_widget(Widget a_this,XtValueMask* a_mask,XSetWindowAttributes* a_watbs) {
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : realize_widget : %s\n",XtName(a_this));
|
||||
#endif
|
||||
|
||||
// Have to create window ourselves due to OpenGL that compells it's visual.
|
||||
// In principle colormap is correctly set in a_watbsy.
|
||||
|
||||
OpenGLAreaPart& athis = _athis(a_this);
|
||||
|
||||
::XtCreateWindow(a_this,(unsigned int)InputOutput,athis.visual,*a_mask,a_watbs);
|
||||
|
||||
// Call the Realize procedure (XtInheritRealize) :
|
||||
if(widget_class()->core_class.superclass->core_class.realize!=NULL)
|
||||
(widget_class()->core_class.superclass->core_class.realize)(a_this, a_mask, a_watbs);
|
||||
|
||||
// If window is delete, all seems ok :
|
||||
if(athis.installColormap==True) install_colormap(a_this);
|
||||
|
||||
//make_current(a_this);
|
||||
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : realize_widget : end\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void destroy_widget(Widget a_this) {
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : destroy_widget : begin\n");
|
||||
#endif
|
||||
OpenGLAreaPart& athis = _athis(a_this);
|
||||
if(athis.installColormap==True) {
|
||||
uninstall_colormap (a_this);
|
||||
athis.installColormap = False;
|
||||
::XFreeColormap(XtDisplay(a_this),a_this->core.colormap);
|
||||
}
|
||||
if(athis.glContext!=NULL) {
|
||||
::glXMakeCurrent(XtDisplay(a_this),None,NULL);
|
||||
::glXDestroyContext(XtDisplay(a_this),athis.glContext);
|
||||
athis.glContext = NULL;
|
||||
}
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : destroy_widget : end\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static Boolean set_values(Widget a_current,Widget,Widget a_this,ArgList,Cardinal*) {
|
||||
OpenGLAreaPart& athis = _athis(a_this);
|
||||
if(athis.doubleBufferOn != ((OpenGLAreaWidget)a_current)->openGLArea.doubleBufferOn) {
|
||||
// Can't change buffering here if X window is created.
|
||||
// With OpenGL, buffering fix parameter of the X window.
|
||||
// Buffering must be choosen before the execution of the
|
||||
// Realize method that create the window.
|
||||
if(XtIsRealized(a_this) && (athis.installColormap==True)) {
|
||||
CWarn("Can't change buffering after \"realization\" of the widget.\n");
|
||||
athis.doubleBufferOn = ((OpenGLAreaWidget)a_current)->openGLArea.doubleBufferOn;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static void change_widget_size(Widget a_this) {
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : change_widget_size : %s\n",XtName(a_this));
|
||||
#endif
|
||||
|
||||
// Call the Resize procedure (XtInheritResize) :
|
||||
if(widget_class()->core_class.superclass->core_class.resize!=NULL)
|
||||
(widget_class()->core_class.superclass->core_class.resize)(a_this);
|
||||
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : change_widget_size : end\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void draw_widget(Widget a_this,XEvent* a_event,Region a_region) {
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : draw_widget : %s\n",XtName(a_this));
|
||||
#endif
|
||||
|
||||
if(widget_class()->core_class.superclass->core_class.expose!=NULL)
|
||||
(widget_class()->core_class.superclass->core_class.expose)(a_this,a_event,a_region);
|
||||
|
||||
if(make_current(a_this)==1) {
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : draw_widget : %s : make_current ok : call paintCallback...\n",XtName(a_this));
|
||||
#endif
|
||||
XoAnyCallbackStruct value;
|
||||
value.reason = XoCR_PAINT;
|
||||
value.event = a_event;
|
||||
::XtCallCallbacks(a_this,XoNpaintCallback,(XtPointer)&value);
|
||||
::glXSwapBuffers(XtDisplay(a_this),XtWindow(a_this));
|
||||
::glXMakeCurrent(XtDisplay(a_this),None,NULL);
|
||||
}
|
||||
|
||||
#ifdef OPENGLAREA_DEBUG
|
||||
printf("debug : OpenGLArea : draw_widget : end\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
static OpenGLAreaPart& _athis(Widget a_this) {return *(&(((OpenGLAreaWidget)a_this)->openGLArea));}
|
||||
static void CWarn(const char* a_msg) {
|
||||
::printf("%s",a_msg);
|
||||
}
|
||||
static void CWarnF(const char* a_format,...) {
|
||||
va_list args;
|
||||
va_start(args,a_format);
|
||||
::vprintf(a_format,args);
|
||||
va_end(args);
|
||||
}
|
||||
static int make_current(Widget a_this) {
|
||||
if(!XtIsRealized(a_this)) return 0;
|
||||
OpenGLAreaPart& athis = _athis(a_this);
|
||||
if(athis.glContext==NULL) return 0;
|
||||
return (int)::glXMakeCurrent(XtDisplay(a_this),XtWindow(a_this),athis.glContext);
|
||||
}
|
||||
|
||||
static void event_handler(Widget a_this,XtPointer,XEvent* a_event ,Boolean*) {
|
||||
XoAnyCallbackStruct value;
|
||||
value.reason = XoCR_EVENT;
|
||||
value.event = a_event;
|
||||
::XtCallCallbacks(a_this,XoNeventCallback,(XtPointer)&value);
|
||||
}
|
||||
|
||||
static void install_colormap(Widget a_this) {
|
||||
// From Mesa/widgets/GLwDrawingArea.c/post_colormap routine.
|
||||
// Could use also XtSetWMColormapWindows.
|
||||
if( !XtIsWidget(a_this) || !XtIsRealized(a_this) ) return;
|
||||
Widget shell = get_shell(a_this);
|
||||
if(shell==NULL) return;
|
||||
Display* display = XtDisplay (a_this);
|
||||
Window wthis = XtWindow (a_this);
|
||||
Window wshell = XtWindow (shell);
|
||||
Window* ws = NULL;
|
||||
int wn = 0;
|
||||
::XGetWMColormapWindows (display,wshell, &ws, &wn);
|
||||
// Check if colormap of this is a colormap of a Window in list :
|
||||
XWindowAttributes watbs;
|
||||
XGetWindowAttributes (display,wthis,&watbs);
|
||||
Colormap cmapthis = watbs.colormap;
|
||||
int found = -1;
|
||||
for(int count=0;count<wn;count++) {
|
||||
Colormap cmap;
|
||||
XGetWindowAttributes (display,ws[count],&watbs);
|
||||
cmap = watbs.colormap;
|
||||
if(cmap==cmapthis) {
|
||||
::XFree (ws);
|
||||
return;
|
||||
}
|
||||
if(ws[count]==wshell) {
|
||||
found = count;
|
||||
}
|
||||
}
|
||||
// Have to add window of this in list :
|
||||
if(wn==0) {
|
||||
if(ws!=NULL) ::XFree(ws);
|
||||
ws = (Window*)::malloc( 2 * sizeof(Window));
|
||||
} else {
|
||||
ws = (Window*)::realloc(ws,(wn + 2) * sizeof(Window));
|
||||
}
|
||||
if(ws==NULL) return;
|
||||
if(found==-1) {
|
||||
// Window of shell not in list :
|
||||
ws[wn] = wthis; wn++;
|
||||
ws[wn] = wshell;wn++;
|
||||
} else {
|
||||
ws[found] = wthis;
|
||||
ws[wn] = wshell; wn++; // Shell must be last.
|
||||
}
|
||||
if (::XSetWMColormapWindows(display,wshell, ws, wn)==0) {
|
||||
CWarnF ("install_colormap: can't install colormap of %s in %s.\n",XtName(a_this),XtName(shell));
|
||||
}
|
||||
::free(ws);
|
||||
}
|
||||
|
||||
static void uninstall_colormap(Widget a_this) {
|
||||
if( !XtIsWidget(a_this) || !XtIsRealized(a_this) ) return;
|
||||
Widget shell = get_shell (a_this);
|
||||
if(shell==NULL) return;
|
||||
Display* display = XtDisplay (a_this);
|
||||
Window wthis = XtWindow (a_this);
|
||||
Window wshell = XtWindow (shell);
|
||||
Window* ws = NULL;
|
||||
int wn = 0;
|
||||
::XGetWMColormapWindows (display,wshell, &ws, &wn);
|
||||
if( (wn==0) || (ws==NULL) ) return;
|
||||
Window* nws = (Window*)::malloc( wn * sizeof(Window));
|
||||
if(nws==NULL) {
|
||||
::XFree (ws);
|
||||
return;
|
||||
}
|
||||
int nwn = 0;
|
||||
for(int count=0;count<wn;count++) {
|
||||
if(ws[count]!=wthis) {
|
||||
nws[nwn] = ws[count];
|
||||
nwn++;
|
||||
}
|
||||
}
|
||||
if(wn!=nwn) {
|
||||
if (::XSetWMColormapWindows(display,wshell, nws, nwn)==0) {
|
||||
CWarnF("uninstall_colormap: can't install colormap of %s in %s.\n",XtName(a_this),XtName(shell));
|
||||
}
|
||||
}
|
||||
::XFree (ws);
|
||||
::free (nws);
|
||||
}
|
||||
|
||||
static Widget get_shell(Widget a_this) {
|
||||
Widget widget = a_this;
|
||||
while(1) {
|
||||
if(widget==NULL) return NULL;
|
||||
if(XtIsShell(widget)) return widget;
|
||||
widget = XtParent(widget);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static WidgetClass widget_class() {
|
||||
static XtResource s_resources [] = {
|
||||
{(String)XoNdoubleBufferOn,(String)"DoubleBufferOn",XtRBoolean,sizeof(Boolean),
|
||||
XtOffset(OpenGLAreaWidget,openGLArea.doubleBufferOn),XtRImmediate,(XtPointer)True},
|
||||
{(String)XoNpaintCallback,XtCCallback,XtRCallback,sizeof(XtCallbackList),
|
||||
XtOffset(OpenGLAreaWidget,openGLArea.paintCallback),XtRImmediate,(XtPointer)NULL},
|
||||
{(String)XoNeventCallback,XtCCallback,XtRCallback,sizeof(XtCallbackList),
|
||||
XtOffset(OpenGLAreaWidget,openGLArea.eventCallback),XtRImmediate,(XtPointer)NULL}
|
||||
};
|
||||
|
||||
static OpenGLAreaClassRec s_openGLAreaClassRec = {
|
||||
// Core Class Part :
|
||||
{
|
||||
(WidgetClass) &compositeClassRec, // pointer to superclass ClassRec
|
||||
(String)"OpenGLArea", // widget resource class name
|
||||
sizeof(OpenGLAreaRec), // size in bytes of widget record
|
||||
initialize_class, // class_initialize
|
||||
NULL, // dynamic initialization
|
||||
FALSE, // has class been initialized?
|
||||
initialize_widget, // initialize
|
||||
NULL, // notify that initialize called
|
||||
realize_widget, // XCreateWindow for widget
|
||||
NULL, // widget semantics name to proc mapWidget
|
||||
0, // number of entries in actions
|
||||
s_resources, // resources for subclass fields
|
||||
XtNumber(s_resources), // number of entries in resources
|
||||
NULLQUARK, // resource class quarkified
|
||||
TRUE, // compress MotionNotify for widget
|
||||
TRUE, // compress Expose events for widget
|
||||
TRUE, // compress enter and leave events
|
||||
TRUE, // select for VisibilityNotify
|
||||
destroy_widget, // free data for subclass pointers
|
||||
change_widget_size, // geom manager changed widget size
|
||||
draw_widget, // rediplay window
|
||||
set_values, // set subclass resource values
|
||||
NULL, // notify that SetValues called
|
||||
XtInheritSetValuesAlmost, // SetValues got "Almost" geo reply
|
||||
NULL, // notify that get_values called
|
||||
XtInheritAcceptFocus, // assign input focus to widget
|
||||
XtVersion, // version of intrinsics used
|
||||
NULL, // list of callback offsets
|
||||
XtInheritTranslations, // translations
|
||||
XtInheritQueryGeometry, // return preferred geometry
|
||||
XtInheritDisplayAccelerator, // display your accelerator
|
||||
NULL // pointer to extension record
|
||||
},
|
||||
// Composite Class Part :
|
||||
{
|
||||
XtInheritGeometryManager, // geometry manager for children
|
||||
XtInheritChangeManaged, // change managed state of child
|
||||
XtInheritInsertChild, // physically add child to parent
|
||||
XtInheritDeleteChild, // physically remove child
|
||||
NULL // pointer to extension record
|
||||
},
|
||||
// OpenGLArea :
|
||||
{
|
||||
NULL
|
||||
}
|
||||
};
|
||||
return (WidgetClass)&s_openGLAreaClassRec;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
/*this*/
|
||||
#include "OpenGLAreaP.h"
|
||||
|
||||
#include <X11/StringDefs.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
static void InitializeClass(void);
|
||||
static void InitializeWidget(Widget, Widget,ArgList,Cardinal*);
|
||||
static void RealizeWidget(Widget, XtValueMask*, XSetWindowAttributes*);
|
||||
static void DestroyWidget(Widget);
|
||||
static void ChangeWidgetSize(Widget);
|
||||
static void DrawWidget(Widget, XEvent*, Region);
|
||||
static Boolean SetValues(Widget,Widget,Widget,ArgList,Cardinal *);
|
||||
|
||||
static void EventHandler(Widget,XtPointer,XEvent*,Boolean*);
|
||||
static int MakeCurrent(Widget);
|
||||
static void XWidgetInstallColormap(Widget);
|
||||
static void XWidgetUninstallColormap(Widget);
|
||||
static Widget XWidgetGetShell(Widget);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define athis ((OpenGLAreaWidget)This)->openGLArea
|
||||
#define acur ((OpenGLAreaWidget)a_current)->openGLArea
|
||||
#define CWarn printf
|
||||
#define CWarnF printf
|
||||
|
||||
static XtResource resources [] = {
|
||||
{XoNdoubleBufferOn,"DoubleBufferOn",XtRBoolean,sizeof(Boolean),
|
||||
XtOffset(OpenGLAreaWidget,openGLArea.doubleBufferOn),XtRImmediate,(XtPointer)True},
|
||||
{XoNpaintCallback,XtCCallback,XtRCallback,sizeof(XtCallbackList),
|
||||
XtOffset(OpenGLAreaWidget,openGLArea.paintCallback),XtRImmediate,(XtPointer)NULL},
|
||||
{XoNeventCallback,XtCCallback,XtRCallback,sizeof(XtCallbackList),
|
||||
XtOffset(OpenGLAreaWidget,openGLArea.eventCallback),XtRImmediate,(XtPointer)NULL}
|
||||
};
|
||||
|
||||
OpenGLAreaClassRec openGLAreaClassRec = {
|
||||
/* Core Class Part */
|
||||
{
|
||||
(WidgetClass) &compositeClassRec, /* pointer to superclass ClassRec */
|
||||
"OpenGLArea", /* widget resource class name */
|
||||
sizeof(OpenGLAreaRec), /* size in bytes of widget record */
|
||||
InitializeClass, /* class_initialize */
|
||||
NULL, /* dynamic initialization */
|
||||
FALSE, /* has class been initialized? */
|
||||
InitializeWidget, /* initialize */
|
||||
NULL, /* notify that initialize called */
|
||||
RealizeWidget, /* XCreateWindow for widget */
|
||||
NULL, /* widget semantics name to proc mapWidget*/
|
||||
0, /* number of entries in actions */
|
||||
resources, /* resources for subclass fields */
|
||||
XtNumber(resources), /* number of entries in resources */
|
||||
NULLQUARK, /* resource class quarkified */
|
||||
TRUE, /* compress MotionNotify for widget */
|
||||
TRUE, /* compress Expose events for widget*/
|
||||
TRUE, /* compress enter and leave events */
|
||||
TRUE, /* select for VisibilityNotify */
|
||||
DestroyWidget, /* free data for subclass pointers */
|
||||
ChangeWidgetSize, /* geom manager changed widget size */
|
||||
DrawWidget, /* rediplay window */
|
||||
SetValues, /* set subclass resource values */
|
||||
NULL, /* notify that SetValues called */
|
||||
XtInheritSetValuesAlmost, /* SetValues got "Almost" geo reply*/
|
||||
NULL, /* notify that get_values called */
|
||||
XtInheritAcceptFocus, /* assign input focus to widget */
|
||||
XtVersion, /* version of intrinsics used */
|
||||
NULL, /* list of callback offsets */
|
||||
XtInheritTranslations, /* translations */
|
||||
XtInheritQueryGeometry, /* return preferred geometry */
|
||||
XtInheritDisplayAccelerator, /* display your accelerator */
|
||||
NULL /* pointer to extension record */
|
||||
},
|
||||
/* Composite Class Part */
|
||||
{
|
||||
XtInheritGeometryManager, /* geometry manager for children */
|
||||
XtInheritChangeManaged, /* change managed state of child */
|
||||
XtInheritInsertChild, /* physically add child to parent */
|
||||
XtInheritDeleteChild, /* physically remove child */
|
||||
NULL /* pointer to extension record */
|
||||
},
|
||||
/* OpenGLArea */
|
||||
{
|
||||
NULL
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
WidgetClass openGLAreaWidgetClass = (WidgetClass) &openGLAreaClassRec;
|
||||
|
||||
static void InitializeClass(void) {}
|
||||
|
||||
static void InitializeWidget(Widget a_request,Widget This,ArgList a_args,Cardinal* a_argn) {
|
||||
if(a_request->core.width<=0) This->core.width = 100;
|
||||
if(a_request->core.height<=0) This->core.height = 100;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("debug : OpenGLArea : InitializeWidget : %s\n",XtName(This));
|
||||
#endif
|
||||
|
||||
athis.visual = CopyFromParent;
|
||||
athis.installColormap = False;
|
||||
athis.glContext = NULL;
|
||||
|
||||
{Display* display;
|
||||
Screen* screen;
|
||||
int iscreen;
|
||||
XVisualInfo* vinfo;
|
||||
display = XtDisplay(This);
|
||||
screen = XtScreen(This);
|
||||
iscreen = XScreenNumberOfScreen(screen);
|
||||
|
||||
{int error,event;
|
||||
if(glXQueryExtension(display,&error,&event)==0) {
|
||||
CWarn ("X server does not have OpenGL extensions.\n");
|
||||
}}
|
||||
|
||||
if(athis.doubleBufferOn==True) {
|
||||
int atbs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_ALPHA_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None
|
||||
};
|
||||
vinfo = glXChooseVisual (display,iscreen,atbs);
|
||||
if(vinfo==NULL) { /*GLX_ALPHA_SIZE : problem with Xming. Try without it.*/
|
||||
int atbs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None
|
||||
};
|
||||
vinfo = glXChooseVisual (display,iscreen,atbs);
|
||||
}
|
||||
} else {
|
||||
int atbs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_ALPHA_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None
|
||||
};
|
||||
vinfo = glXChooseVisual (display,iscreen,atbs);
|
||||
if(vinfo==NULL) { /*GLX_ALPHA_SIZE : problem with Xming. Try without it.*/
|
||||
int atbs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None
|
||||
};
|
||||
vinfo = glXChooseVisual (display,iscreen,atbs);
|
||||
}
|
||||
}
|
||||
|
||||
if(vinfo==NULL) {
|
||||
CWarn ("Can't choose a visual.\n");
|
||||
} else {
|
||||
This->core.depth = vinfo->depth;
|
||||
athis.visual = vinfo->visual;
|
||||
if( (vinfo->depth ==DefaultDepth (display,iscreen)) &&
|
||||
(vinfo->visual==DefaultVisual(display,iscreen)) ) {
|
||||
This->core.colormap = XDefaultColormap (display,iscreen);
|
||||
athis.installColormap = False;
|
||||
} else {
|
||||
This->core.colormap =
|
||||
XCreateColormap (display,XRootWindow(display,iscreen),vinfo->visual, AllocNone);
|
||||
athis.installColormap = True;
|
||||
}
|
||||
if(This->core.colormap==0L) {
|
||||
CWarn ("Can't get/create a X colormap.\n");
|
||||
}
|
||||
athis.glContext = glXCreateContext (display,vinfo,NULL,GL_FALSE);
|
||||
if(athis.glContext==NULL) {
|
||||
CWarn ("Can't create a GLX context.\n");
|
||||
}
|
||||
XFree(vinfo);
|
||||
}}
|
||||
|
||||
XtAddEventHandler(This,ButtonPressMask|ButtonReleaseMask|ButtonMotionMask,0,EventHandler,NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : InitializeWidget : end\n");
|
||||
#endif
|
||||
|
||||
/*avoid C++ warnings*/
|
||||
a_request = NULL;
|
||||
a_args = NULL;
|
||||
a_argn = 0;
|
||||
}
|
||||
|
||||
static void RealizeWidget(Widget This,XtValueMask* a_mask,XSetWindowAttributes* a_watbs) {
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : RealizeWidget : %s\n",XtName(This));
|
||||
#endif
|
||||
|
||||
/*Have to create window ourselves due to OpenGL that compells it's visual.*/
|
||||
/*In principle colormap is correctly set in a_watbs.*/
|
||||
|
||||
XtCreateWindow(This,(unsigned int)InputOutput,athis.visual,*a_mask,a_watbs);
|
||||
|
||||
/* Call the Realize procedure (XtInheritRealize) */
|
||||
if(openGLAreaWidgetClass->core_class.superclass->core_class.realize!=NULL)
|
||||
(openGLAreaWidgetClass->core_class.superclass->core_class.realize)(This, a_mask, a_watbs);
|
||||
|
||||
/*If window is delete, all seems ok.*/
|
||||
if(athis.installColormap==True) XWidgetInstallColormap(This);
|
||||
|
||||
/*MakeCurrent(This);*/
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : RealizeWidget : end\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DestroyWidget(Widget This) {
|
||||
if(athis.installColormap==True) {
|
||||
XWidgetUninstallColormap (This);
|
||||
athis.installColormap = False;
|
||||
XFreeColormap(XtDisplay(This),This->core.colormap);
|
||||
}
|
||||
if(athis.glContext!=NULL) {
|
||||
glXMakeCurrent(XtDisplay(This),None,NULL);
|
||||
glXDestroyContext(XtDisplay(This),athis.glContext);
|
||||
athis.glContext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define IFMOD(a_field) if(athis.a_field != acur.a_field)
|
||||
static Boolean SetValues(Widget a_current,Widget a_request,Widget This,ArgList a_args,Cardinal* a_argn) {
|
||||
IFMOD(doubleBufferOn) {
|
||||
/* Can't change buffering here if X window is created.
|
||||
With OpenGL, buffering fix parameter of the X window.
|
||||
Buffering must be choosen before the execution of the
|
||||
Realize method that create the window. */
|
||||
if(XtIsRealized(This) && (athis.installColormap==True)) {
|
||||
CWarn("Can't change buffering after \"realization\" of the widget.\n");
|
||||
athis.doubleBufferOn = acur.doubleBufferOn;
|
||||
}
|
||||
}
|
||||
/*avoid C++ warnings*/
|
||||
a_request = NULL;
|
||||
a_args = NULL;
|
||||
a_argn = 0;
|
||||
return False;
|
||||
}
|
||||
|
||||
static void ChangeWidgetSize(Widget This) {
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : ChangeWidgetSize : %s\n",XtName(This));
|
||||
#endif
|
||||
|
||||
/* Call the Resize procedure (XtInheritResize) */
|
||||
if(openGLAreaWidgetClass->core_class.superclass->core_class.resize!=NULL)
|
||||
(openGLAreaWidgetClass->core_class.superclass->core_class.resize)(This);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : ChangeWidgetSize : end\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DrawWidget(Widget This,XEvent* a_event,Region a_region) {
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : DrawWidget : %s\n",XtName(This));
|
||||
#endif
|
||||
|
||||
if(openGLAreaWidgetClass->core_class.superclass->core_class.expose!=NULL)
|
||||
(openGLAreaWidgetClass->core_class.superclass->core_class.expose)(This,a_event,a_region);
|
||||
|
||||
if(MakeCurrent(This)==1) {
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : DrawWidget : %s : MakeCurrent ok : call paintCallback...\n",XtName(This));
|
||||
#endif
|
||||
XoAnyCallbackStruct value;
|
||||
value.reason = XoCR_PAINT;
|
||||
value.event = a_event;
|
||||
XtCallCallbacks(This,XoNpaintCallback,(XtPointer)&value);
|
||||
glXSwapBuffers(XtDisplay(This),XtWindow(This));
|
||||
glXMakeCurrent(XtDisplay(This),None,NULL);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("debug : OpenGLArea : DrawWidget : end\n");
|
||||
#endif
|
||||
|
||||
/*avoid C++ warnings*/
|
||||
a_event = NULL;
|
||||
a_region = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void OpenGLAreaPaint(Widget This) {
|
||||
if(!XtIsRealized(This)) return;
|
||||
if(MakeCurrent(This)==1) {
|
||||
XoAnyCallbackStruct value;
|
||||
value.reason = XoCR_PAINT;
|
||||
value.event = 0;
|
||||
XtCallCallbacks(This,XoNpaintCallback,(XtPointer)&value);
|
||||
glXSwapBuffers(XtDisplay(This),XtWindow(This));
|
||||
glXMakeCurrent(XtDisplay(This),None,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TOOLS_XT_OPENGLAREA_HAS_GL2PS
|
||||
|
||||
#include <tools/c_gl2ps.h>
|
||||
|
||||
int OpenGLAreaWrite_gl2ps(Widget This,const char* aFileName,const char* opts) {
|
||||
FILE* file;
|
||||
int options;
|
||||
int sort;
|
||||
inlib_GLint vp[4];
|
||||
int bufsize = 0;
|
||||
static inlib_gl2ps_gl_funcs_t s_OpenGL_funcs = {
|
||||
glIsEnabled,
|
||||
glBegin,
|
||||
glEnd,
|
||||
glGetFloatv,
|
||||
glVertex3f,
|
||||
glGetBooleanv,
|
||||
glGetIntegerv,
|
||||
glRenderMode,
|
||||
glFeedbackBuffer,
|
||||
glPassThrough
|
||||
};
|
||||
|
||||
file = fopen(aFileName,"w");
|
||||
if(!file) return 1;
|
||||
|
||||
inlib_c_gl2ps_set_gl_funcs(&s_OpenGL_funcs);
|
||||
|
||||
options = TOOLS_GL2PS_OCCLUSION_CULL
|
||||
| TOOLS_GL2PS_BEST_ROOT
|
||||
| TOOLS_GL2PS_SILENT
|
||||
| TOOLS_GL2PS_DRAW_BACKGROUND;
|
||||
sort = TOOLS_GL2PS_BSP_SORT;
|
||||
//sort = TOOLS_GL2PS_SIMPLE_SORT;
|
||||
|
||||
vp[0] = 0;
|
||||
vp[1] = 0;
|
||||
vp[2] = This->core.width;
|
||||
vp[3] = This->core.height;
|
||||
|
||||
inlib_c_gl2psBeginPage("title","exlib_Xt_OpenGLArea",
|
||||
vp,TOOLS_GL2PS_EPS,sort,options,
|
||||
TOOLS_GL_RGBA,0, NULL,0,0,0,bufsize,
|
||||
file,aFileName);
|
||||
|
||||
{XoAnyCallbackStruct value;
|
||||
value.reason = XoCR_PAINT;
|
||||
value.event = 0;
|
||||
XtCallCallbacks(This,XoNpaintCallback,(XtPointer)&value);}
|
||||
|
||||
inlib_c_gl2psEndPage();
|
||||
|
||||
inlib_c_gl2ps_reset_gl_funcs();
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
int OpenGLAreaWrite_gl2ps(Widget,const char*,const char*) {return 1;}
|
||||
#else
|
||||
int OpenGLAreaWrite_gl2ps(Widget w,const char* f,const char* o) {return 1;}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int MakeCurrent(Widget This) {
|
||||
if(This==NULL) return 0;
|
||||
if(!XtIsRealized(This)) return 0;
|
||||
if(athis.glContext==NULL) return 0;
|
||||
return (int)glXMakeCurrent(XtDisplay(This),XtWindow(This),athis.glContext);
|
||||
}
|
||||
|
||||
static void EventHandler(Widget This,XtPointer a_tag,XEvent* a_event ,Boolean* a_continue) {
|
||||
XoAnyCallbackStruct value;
|
||||
value.reason = XoCR_EVENT;
|
||||
value.event = a_event;
|
||||
XtCallCallbacks(This,XoNeventCallback,(XtPointer)&value);
|
||||
a_tag = NULL;
|
||||
a_continue = NULL;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void XWidgetInstallColormap(Widget This) {
|
||||
/*
|
||||
From Mesa/widgets/GLwDrawingArea.c/post_colormap routine.
|
||||
Could use also XtSetWMColormapWindows.
|
||||
*/
|
||||
Display* display;
|
||||
XWindowAttributes watbs;
|
||||
Widget shell;
|
||||
Window* ws = NULL;
|
||||
int wn = 0,found,count;
|
||||
Window wshell,wthis;
|
||||
Colormap cmapthis;
|
||||
/*.........................................................................*/
|
||||
if(This==NULL) return;
|
||||
if( !XtIsWidget(This) || !XtIsRealized(This) ) return;
|
||||
shell = XWidgetGetShell (This);
|
||||
if(shell==NULL) return;
|
||||
display = XtDisplay (This);
|
||||
wthis = XtWindow (This);
|
||||
wshell = XtWindow (shell);
|
||||
XGetWMColormapWindows (display,wshell, &ws, &wn);
|
||||
/* Check if colormap of this is a colormap of a Window in list.*/
|
||||
XGetWindowAttributes (display,wthis,&watbs);
|
||||
cmapthis = watbs.colormap;
|
||||
found = -1;
|
||||
for(count=0;count<wn;count++) {
|
||||
Colormap cmap;
|
||||
XGetWindowAttributes (display,ws[count],&watbs);
|
||||
cmap = watbs.colormap;
|
||||
if(cmap==cmapthis) {
|
||||
XFree (ws);
|
||||
return; /*done*/
|
||||
}
|
||||
if(ws[count]==wshell) {
|
||||
found = count;
|
||||
}
|
||||
}
|
||||
/*Have to add window of this in list.*/
|
||||
if(wn==0) {
|
||||
if(ws!=NULL) XFree(ws);
|
||||
ws = (Window*)malloc ( 2 * sizeof(Window));
|
||||
} else {
|
||||
ws = (Window*)realloc (ws,(wn + 2) * sizeof(Window));
|
||||
}
|
||||
if(ws==NULL) return;
|
||||
if(found==-1) {
|
||||
/*Window of shell not in list.*/
|
||||
ws[wn] = wthis; wn++;
|
||||
ws[wn] = wshell;wn++;
|
||||
} else {
|
||||
ws[found] = wthis;
|
||||
ws[wn] = wshell; wn++; /*Shell must be last.*/
|
||||
}
|
||||
if (XSetWMColormapWindows(display,wshell, ws, wn)==0) {
|
||||
CWarnF ("XWidgetInstallColormap: can't install colormap of %s in %s.\n",XtName(This),XtName(shell));
|
||||
}
|
||||
XFree (ws);
|
||||
}
|
||||
|
||||
static void XWidgetUninstallColormap(Widget This) {
|
||||
int count;
|
||||
Widget shell;
|
||||
Display* display;
|
||||
Window wthis,wshell;
|
||||
Window* ws = NULL;
|
||||
int wn = 0;
|
||||
Window* nws = NULL;
|
||||
int nwn = 0;
|
||||
/*.........................................................................*/
|
||||
if(This==NULL) return;
|
||||
if( !XtIsWidget(This) || !XtIsRealized(This) ) return;
|
||||
shell = XWidgetGetShell (This);
|
||||
if(shell==NULL) return;
|
||||
display = XtDisplay (This);
|
||||
wthis = XtWindow (This);
|
||||
wshell = XtWindow (shell);
|
||||
XGetWMColormapWindows (display,wshell, &ws, &wn);
|
||||
if( (wn==0) || (ws==NULL) ) return;
|
||||
nws = (Window*)malloc ( wn * sizeof(Window));
|
||||
if(nws==NULL) {
|
||||
XFree (ws);
|
||||
return;
|
||||
}
|
||||
nwn = 0;
|
||||
for(count=0;count<wn;count++) {
|
||||
if(ws[count]!=wthis) {
|
||||
nws[nwn] = ws[count];
|
||||
nwn++;
|
||||
}
|
||||
}
|
||||
if(wn!=nwn) {
|
||||
if (XSetWMColormapWindows(display,wshell, nws, nwn)==0) {
|
||||
CWarnF("XWidgetUninstallColormap: can't install colormap of %s in %s.\n",XtName(This),XtName(shell));
|
||||
}
|
||||
}
|
||||
XFree (ws);
|
||||
XFree (nws);
|
||||
}
|
||||
|
||||
Widget XWidgetGetShell(Widget This) {
|
||||
Widget widget;
|
||||
if(This==NULL) return NULL;
|
||||
widget = This;
|
||||
while(1) {
|
||||
if(widget==NULL) return NULL;
|
||||
if(XtIsShell(widget)) return widget;
|
||||
widget = XtParent(widget);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
exlib_build_use Xt inlib
|
||||
*/
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef tools_Xt_OpenGLArea_h
|
||||
#define tools_Xt_OpenGLArea_h
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
typedef struct _OpenGLAreaClassRec* OpenGLAreaWidgetClass;
|
||||
typedef struct _OpenGLAreaRec* OpenGLAreaWidget;
|
||||
|
||||
typedef struct {
|
||||
int reason;
|
||||
XEvent* event;
|
||||
} XoAnyCallbackStruct;
|
||||
|
||||
/* OpenGLArea */
|
||||
#define XoNdoubleBufferOn "doubleBufferOn"
|
||||
#define XoNpaintCallback "paintCallback"
|
||||
#define XoNeventCallback "eventCallback"
|
||||
|
||||
#define XoCR_PAINT 1
|
||||
#define XoCR_EVENT 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
extern WidgetClass openGLAreaWidgetClass;
|
||||
|
||||
void OpenGLAreaPaint(Widget);
|
||||
int OpenGLAreaWrite_gl2ps(Widget,const char*,const char*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
exlib_build_use Xt
|
||||
*/
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef tools_Xt_OpenGLAreaP_h
|
||||
#define tools_Xt_OpenGLAreaP_h
|
||||
|
||||
#include "OpenGLArea.h"
|
||||
|
||||
#include <X11/IntrinsicP.h>
|
||||
#include <X11/CoreP.h>
|
||||
#include <X11/CompositeP.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void* extension;
|
||||
} OpenGLAreaClassPart;
|
||||
|
||||
typedef struct _OpenGLAreaClassRec
|
||||
{
|
||||
CoreClassPart core_class;
|
||||
CompositeClassPart composite_class;
|
||||
OpenGLAreaClassPart openGLArea_class;
|
||||
} OpenGLAreaClassRec;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
extern OpenGLAreaClassRec openGLAreaClassRec;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*Resources :*/
|
||||
Boolean doubleBufferOn;
|
||||
XtCallbackList paintCallback;
|
||||
XtCallbackList eventCallback;
|
||||
/**/
|
||||
Visual* visual;
|
||||
Boolean installColormap;
|
||||
GLXContext glContext;
|
||||
} OpenGLAreaPart;
|
||||
|
||||
typedef struct _OpenGLAreaRec
|
||||
{
|
||||
CorePart core;
|
||||
CompositePart composite;
|
||||
OpenGLAreaPart openGLArea;
|
||||
} OpenGLAreaRec;
|
||||
|
||||
#endif
|
||||
/*
|
||||
exlib_build_use Xt
|
||||
*/
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_Xt_session
|
||||
#define tools_Xt_session
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/Shell.h>
|
||||
#include <X11/StringDefs.h>
|
||||
|
||||
namespace tools {
|
||||
namespace Xt {
|
||||
|
||||
class session {
|
||||
public:
|
||||
session(std::ostream& a_out,int& a_argc,char** a_argv)
|
||||
:m_out(a_out),m_app_context(0),m_app_widget(0)
|
||||
{
|
||||
//LookDSM_Problem();
|
||||
Arg args[1];
|
||||
XtSetArg(args[0],XtNgeometry,XtNewString("100x100"));
|
||||
m_app_widget = ::XtAppInitialize(&m_app_context,"tools::Xt::session",NULL,(Cardinal)0,&a_argc,a_argv,NULL,args,1);
|
||||
if(!m_app_context || !m_app_widget) {
|
||||
m_app_context = 0;
|
||||
m_app_widget = 0;
|
||||
}
|
||||
}
|
||||
virtual ~session() {
|
||||
if(m_app_widget) {::XtDestroyWidget(m_app_widget);m_app_widget = 0;}
|
||||
if(m_app_context) {::XtDestroyApplicationContext(m_app_context);m_app_context = 0;}
|
||||
}
|
||||
protected:
|
||||
session(const session& a_from)
|
||||
:m_out(a_from.m_out),m_app_context(0),m_app_widget(0)
|
||||
{}
|
||||
session& operator=(const session&){return *this;}
|
||||
public:
|
||||
std::ostream& out() const {return m_out;}
|
||||
bool is_valid() {return m_app_context && m_app_widget?true:false;}
|
||||
bool steer() {
|
||||
if(!m_app_context) return false;
|
||||
while(true) {
|
||||
XEvent event;
|
||||
::XtAppNextEvent(m_app_context,&event);
|
||||
::XtDispatchEvent(&event);
|
||||
//if(m_exit) break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool sync() {
|
||||
//if(!m_app_widget) return false;
|
||||
//Display* display = XtDisplay(m_app_widget);
|
||||
//::XSync(display,False);
|
||||
if(!m_app_context) return false;
|
||||
while(true) {
|
||||
XtInputMask input = ::XtAppPending(m_app_context);
|
||||
if(input==0) break;
|
||||
XEvent event;
|
||||
::XtAppNextEvent(m_app_context,&event);
|
||||
::XtDispatchEvent(&event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
Widget get_app_widget() {return m_app_widget;}
|
||||
protected:
|
||||
std::ostream& m_out;
|
||||
bool m_app_owner;
|
||||
XtAppContext m_app_context;
|
||||
Widget m_app_widget;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_Xt_sg_viewer
|
||||
#define tools_Xt_sg_viewer
|
||||
|
||||
#include "session"
|
||||
|
||||
#include "../sg/GL_viewer"
|
||||
|
||||
#include "OpenGLArea"
|
||||
|
||||
#include <X11/Shell.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include <X11/IntrinsicP.h>
|
||||
|
||||
#include <tools/num2s>
|
||||
#include <tools/sg/device_interactor>
|
||||
#include <tools/sg/keys>
|
||||
|
||||
namespace tools {
|
||||
namespace Xt {
|
||||
|
||||
class sg_viewer : public sg::GL_viewer {
|
||||
typedef sg::GL_viewer parent;
|
||||
public:
|
||||
sg_viewer(session& a_session,
|
||||
int a_x = 0,int a_y = 0,
|
||||
unsigned int a_width = 500,unsigned int a_height = 500,
|
||||
const std::string& a_win_title = "")
|
||||
:parent(a_session.out(),a_width,a_height)
|
||||
,m_session(a_session)
|
||||
,m_shell(0)
|
||||
,m_glarea(0)
|
||||
,m_interactor(0)
|
||||
{
|
||||
Widget app_widget = a_session.get_app_widget();
|
||||
if(!app_widget) return;
|
||||
|
||||
std::string sgeom;
|
||||
tools::numas(a_width,sgeom);
|
||||
sgeom += "x";
|
||||
tools::numas(a_height,sgeom);
|
||||
sgeom += "+";
|
||||
tools::numas(a_x,sgeom);
|
||||
sgeom += "+";
|
||||
tools::numas(a_y,sgeom);
|
||||
|
||||
Arg args[2];
|
||||
XtSetArg(args[0],XtNgeometry,XtNewString(sgeom.c_str()));
|
||||
XtSetArg(args[1],XtNborderWidth,0);
|
||||
|
||||
m_shell = ::XtAppCreateShell((char*)a_win_title.c_str(),
|
||||
(char*)"sg_viewer_shell",
|
||||
topLevelShellWidgetClass,XtDisplay(app_widget),args,2);
|
||||
::XtSetMappedWhenManaged(m_shell,True);
|
||||
|
||||
m_glarea = ::XtCreateManagedWidget("glarea",OpenGLArea::widget_class(),m_shell,args,0);
|
||||
::XtAddCallback(m_glarea,XoNpaintCallback,paint_cbk,(XtPointer)this);
|
||||
::XtAddCallback(m_glarea,XoNeventCallback,event_cbk,(XtPointer)this);
|
||||
|
||||
::XtAddCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
|
||||
|
||||
::XtRealizeWidget(m_shell);
|
||||
|
||||
//Atom WM_DELETE_WINDOW_atom = ::XInternAtom(XtDisplay(m_shell),"WM_DELETE_WINDOW",False);
|
||||
//::XSetWMProtocols(XtDisplay(m_shell),XtWindow(m_shell),&WM_DELETE_WINDOW_atom,1);
|
||||
}
|
||||
virtual ~sg_viewer() {
|
||||
if(m_shell) {
|
||||
::XtRemoveCallback(m_glarea,XoNpaintCallback,paint_cbk,(XtPointer)this);
|
||||
::XtRemoveCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
|
||||
::XtDestroyWidget(m_shell);
|
||||
}
|
||||
m_shell = 0;
|
||||
m_glarea = 0;
|
||||
}
|
||||
protected:
|
||||
sg_viewer(const sg_viewer& a_from)
|
||||
:parent(a_from)
|
||||
,m_session(a_from.m_session)
|
||||
,m_shell(0)
|
||||
,m_glarea(0)
|
||||
,m_interactor(0)
|
||||
{}
|
||||
sg_viewer& operator=(const sg_viewer& a_from){
|
||||
parent::operator=(a_from);
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
bool has_window() const {return m_glarea?true:false;}
|
||||
|
||||
bool show() {
|
||||
if(!m_shell) return false;
|
||||
::XtRealizeWidget(m_shell);
|
||||
::XtMapWidget(m_shell);
|
||||
// Raise window :
|
||||
if(XtIsWidget(m_shell) && XtIsRealized(m_shell) ) {
|
||||
Display* display = XtDisplay(m_shell);
|
||||
Atom atom = ::XInternAtom(display,"WM_DELETE_WINDOW",False);
|
||||
::XSetWMProtocols(display,XtWindow(m_shell),&atom,1);
|
||||
::XRaiseWindow(display,XtWindow(m_shell));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void win_render() {
|
||||
if(m_glarea) OpenGLArea::paint(m_glarea);
|
||||
}
|
||||
|
||||
public:
|
||||
void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership.
|
||||
protected:
|
||||
static void paint_cbk(Widget a_widget,XtPointer a_tag,XtPointer){
|
||||
unsigned int width = a_widget->core.width;
|
||||
unsigned int height = a_widget->core.height;
|
||||
//::printf("debug : tools::Xt::sg_viewer::paint_cbk : %d %d\n",width,height);
|
||||
sg_viewer* _this = (sg_viewer*)a_tag;
|
||||
_this->set_size(width,height);
|
||||
_this->render();
|
||||
}
|
||||
static void event_cbk(Widget,XtPointer a_tag,XtPointer a_data){
|
||||
sg_viewer* _this = (sg_viewer*)a_tag;
|
||||
if(!_this->m_interactor) return;
|
||||
XoAnyCallbackStruct* data = (XoAnyCallbackStruct*)a_data;
|
||||
XEvent* xevent = data->event;
|
||||
switch( xevent->type ) {
|
||||
case KeyPress:{
|
||||
KeySym key_sym;
|
||||
::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
|
||||
tools::sg::key_down_event event(_this->convert(key_sym));
|
||||
_this->m_interactor->key_press(event);
|
||||
}return;
|
||||
case KeyRelease:{
|
||||
KeySym key_sym;
|
||||
::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
|
||||
tools::sg::key_up_event event(_this->convert(key_sym));
|
||||
_this->m_interactor->key_release(event);
|
||||
}return;
|
||||
case ButtonPress:{
|
||||
if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in.
|
||||
tools::sg::wheel_rotate_event event(8); //8=cooking.
|
||||
_this->m_interactor->wheel_rotate(event);
|
||||
} else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out.
|
||||
tools::sg::wheel_rotate_event event(-8); //8=cooking.
|
||||
_this->m_interactor->wheel_rotate(event);
|
||||
} else {
|
||||
tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y);
|
||||
_this->m_interactor->mouse_press(event);
|
||||
}
|
||||
}return;
|
||||
case ButtonRelease:{
|
||||
tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y);
|
||||
_this->m_interactor->mouse_release(event);
|
||||
}return;
|
||||
case MotionNotify:{
|
||||
tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,0,0,false);
|
||||
_this->m_interactor->mouse_move(event);
|
||||
}return;
|
||||
default:return;}
|
||||
}
|
||||
static void destroy_shell_callback(Widget,XtPointer a_tag,XtPointer) {
|
||||
sg_viewer* _this = (sg_viewer*)a_tag;
|
||||
_this->m_shell = 0;
|
||||
_this->m_glarea = 0;
|
||||
}
|
||||
protected:
|
||||
tools::key_code convert(KeySym a_key) {
|
||||
if(a_key==XK_Shift_L) return tools::sg::key_shift();
|
||||
if(a_key==XK_Shift_R) return tools::sg::key_shift();
|
||||
return a_key;
|
||||
}
|
||||
protected:
|
||||
session& m_session;
|
||||
Widget m_shell;
|
||||
Widget m_glarea;
|
||||
tools::sg::device_interactor* m_interactor;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_Xt_tools
|
||||
#define tools_Xt_tools
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include <string>
|
||||
|
||||
inline Widget XWidgetGetShell(Widget aWidget){
|
||||
Widget widget = aWidget;
|
||||
while(1) {
|
||||
if(!widget) return 0;
|
||||
if(XtIsShell(widget)) return widget;
|
||||
widget = XtParent(widget);
|
||||
}
|
||||
}
|
||||
|
||||
inline Pixel XWidgetGetPixelResource(Widget aWidget,const std::string& aName){
|
||||
Pixel pixel = 0L;
|
||||
Arg args[1];
|
||||
XtSetArg(args[0],(char*)aName.c_str(),&pixel);
|
||||
XtGetValues(aWidget,args,1);
|
||||
return pixel;
|
||||
}
|
||||
|
||||
inline Pixel XWidgetConvertStringToPixel(Widget aWidget,const std::string& aString){
|
||||
if(aString.empty()) return 0L;
|
||||
if( (aString=="None") || (aString=="none") )
|
||||
return XWidgetGetPixelResource(aWidget,std::string(XtNbackground));
|
||||
XrmValue from,to;
|
||||
from.size = aString.size()+1;
|
||||
from.addr = (XPointer)aString.c_str();
|
||||
XtConvert(aWidget,XtRString,&from,XtRPixel,&to);
|
||||
if(to.addr==NULL) return 0L;
|
||||
return (*((Pixel*)to.addr));
|
||||
}
|
||||
inline void XWidgetSetString(Widget aWidget,const std::string& aName,const std::string& aValue,bool aFreePrevious = false){
|
||||
if(aFreePrevious) {
|
||||
char* s = NULL;
|
||||
Arg args[1];
|
||||
XtSetArg(args[0],(char*)aName.c_str(),&s);
|
||||
XtGetValues(aWidget,args,1);
|
||||
if(s!=NULL) XtFree(s);
|
||||
}
|
||||
Arg args[1];
|
||||
XtSetArg(args[0],(char*)aName.c_str(),XtNewString(aValue.c_str()));
|
||||
XtSetValues(aWidget,args,1);
|
||||
}
|
||||
inline bool XWidgetGetString(Widget aWidget,const std::string& aName,std::string& a_value){
|
||||
// XtNgeometry, XtNtitle.
|
||||
char* s = NULL;
|
||||
Arg args[1];
|
||||
XtSetArg(args[0],(char*)aName.c_str(),&s);
|
||||
XtGetValues(aWidget,args,1);
|
||||
if(s==NULL) {a_value.clear();return false;}
|
||||
a_value = std::string(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
inline bool XWidgetSendMessage(Widget aWidget,long a_1,long a_2) {
|
||||
XClientMessageEvent event;
|
||||
if(!XtIsRealized(aWidget)) return 0;
|
||||
event.type = ClientMessage;
|
||||
event.display = XtDisplay(aWidget);
|
||||
event.window = XtWindow(aWidget);
|
||||
event.message_type = XA_INTEGER;
|
||||
event.format = 8;
|
||||
event.data.l[0] = a_1;
|
||||
event.data.l[1] = a_2;
|
||||
event.data.l[2] = 0L;
|
||||
event.data.l[3] = 0L;
|
||||
event.data.l[4] = 0L;
|
||||
if(XSendEvent(event.display,event.window,False,0L,(XEvent*)&event)==0)
|
||||
return false;
|
||||
XFlush(event.display);
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <X11/IntrinsicP.h>
|
||||
|
||||
inline void XClassGetName(WidgetClass aClass,std::string& a_value){
|
||||
a_value = std::string((char*)aClass->core_class.class_name);
|
||||
}
|
||||
inline Boolean XClassIsSubclass(WidgetClass aClass,WidgetClass aParent){
|
||||
for (WidgetClass wc = aClass; wc != NULL; wc = wc->core_class.superclass)
|
||||
if (wc == aParent) return True;
|
||||
return False;
|
||||
}
|
||||
|
||||
inline Position XWidgetGetX(Widget aWidget){return aWidget->core.x;}
|
||||
inline Position XWidgetGetY(Widget aWidget){return aWidget->core.y;}
|
||||
inline Dimension XWidgetGetWidth(Widget aWidget){return aWidget->core.width;}
|
||||
inline Dimension XWidgetGetHeight(Widget aWidget){return aWidget->core.height;}
|
||||
inline void XWidgetGetClassName(Widget aWidget,std::string& a_value) {
|
||||
WidgetClass wc = XtClass(aWidget);
|
||||
a_value = std::string((char*)wc->core_class.class_name);
|
||||
}
|
||||
inline void XWidgetCompellResize(Widget aWidget){
|
||||
if(aWidget->core.widget_class->core_class.resize==NULL) return;
|
||||
(aWidget->core.widget_class->core_class.resize)(aWidget);
|
||||
}
|
||||
|
||||
#include <X11/CompositeP.h>
|
||||
inline int XWidgetGetChildrenNumber(Widget aWidget){
|
||||
if(!XtIsComposite(aWidget)) return 0;
|
||||
CompositePart* cwp = &(((CompositeWidget)aWidget)->composite);
|
||||
return cwp->num_children;
|
||||
}
|
||||
inline Widget XWidgetGetChild(Widget aWidget,unsigned int aIndex){
|
||||
if(!XtIsComposite(aWidget)) return 0;
|
||||
CompositePart* cwp = &(((CompositeWidget)aWidget)->composite);
|
||||
if(aIndex>=cwp->num_children) return 0;
|
||||
return cwp->children[aIndex];
|
||||
}
|
||||
inline Widget XWidgetGetFirstChild(Widget aWidget){
|
||||
if(!XtIsComposite(aWidget)) return 0;
|
||||
CompositePart* cwp = &(((CompositeWidget)aWidget)->composite);
|
||||
return (cwp->num_children?cwp->children[0]:0);
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
|
||||
inline void XWidgetGetChildren(Widget aWidget,std::vector<Widget>& aList){
|
||||
aList.clear();
|
||||
if(!XtIsComposite(aWidget)) return;
|
||||
CompositePart* cwp = &(((CompositeWidget)aWidget)->composite);
|
||||
for (unsigned int count=0;count<cwp->num_children;count++)
|
||||
aList.push_back(cwp->children[count]);
|
||||
}
|
||||
inline void XWidgetGetPopupChildren(Widget aWidget,std::vector<Widget>& aList){
|
||||
aList.clear();
|
||||
if(!XtIsWidget(aWidget)) return;
|
||||
for(int count=0;count<aWidget->core.num_popups;count++) {
|
||||
aList.push_back(aWidget->core.popup_list[count]);
|
||||
}
|
||||
}
|
||||
inline Widget XWidgetFindChild(Widget aWidget,const std::string& aName){
|
||||
if(!XtIsComposite(aWidget)) return 0;
|
||||
CompositePart* cwp = &(((CompositeWidget)aWidget)->composite);
|
||||
for (unsigned int count=0;count<cwp->num_children;count++) {
|
||||
if(aName==std::string(XtName(cwp->children[count])))
|
||||
return cwp->children[count];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <ostream>
|
||||
|
||||
inline void XWidgetPrintChildren(Widget aWidget,std::ostream& a_out){
|
||||
int number = XWidgetGetChildrenNumber(aWidget);
|
||||
a_out << "XWidgetPrintChildren :"
|
||||
<< " " << (unsigned long)aWidget
|
||||
<< " number " << number
|
||||
<< std::endl;
|
||||
std::string scls;
|
||||
for(int index=0;index<number;index++) {
|
||||
Widget child = XWidgetGetChild(aWidget,index);
|
||||
XWidgetGetClassName(child,scls);
|
||||
a_out << " index = " << index
|
||||
<< ", child = " << (unsigned long)child
|
||||
<< ", class = " << scls
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
inline void XWidgetDumpPopupChildren(Widget aWidget,std::ostream& a_out){
|
||||
a_out << "XWidgetDumpPopupChildren :"
|
||||
<< " " << std::string(XtName(aWidget))
|
||||
<< std::endl;
|
||||
if(!XtIsWidget(aWidget)) return;
|
||||
a_out << " " << aWidget->core.num_popups << " popup children." << std::endl;
|
||||
std::string scls;
|
||||
for (unsigned int count=0;count<aWidget->core.num_popups;count++) {
|
||||
Widget w = aWidget->core.popup_list[count];
|
||||
XWidgetGetClassName(w,scls);
|
||||
a_out << " " << count
|
||||
<< " child class " << scls
|
||||
<< " name " << std::string(XtName(w))
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
inline void XWidgetDumpChildren(Widget aWidget,std::ostream& a_out){
|
||||
a_out << "XWidgetDumpChildren :"
|
||||
<< " " << std::string(XtName(aWidget))
|
||||
<< std::endl;
|
||||
if(!XtIsComposite(aWidget)) return;
|
||||
CompositePart* cwp = &(((CompositeWidget)aWidget)->composite);
|
||||
a_out << " " << cwp->num_children << " children." << std::endl;
|
||||
std::string scls;
|
||||
for (unsigned int count=0;count<cwp->num_children;count++) {
|
||||
Widget w = cwp->children[count];
|
||||
XWidgetGetClassName(w,scls);
|
||||
a_out << " " << count
|
||||
<< " child class " << scls
|
||||
<< " name " << std::string(XtName(w))
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user