123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- #include <stdio.h>
- #include <GL/gl.h>
- #include <GL/glx.h>
- #include <X11/extensions/xf86vmode.h>
- #include <assert.h>
- /* Added by BaH */
- #include <brl.mod/blitz.mod/blitz.h>
- #include <X11/Xutil.h>
- extern void bbSystemPoll();
- extern Display *bbSystemDisplay();
- extern void bbSetSystemWindow(int window);
- static XF86VidModeModeInfo **modes,*mode;
- static Display *xdisplay;
- static int xscreen,xwindow,xfullscreen;
- typedef int (* GLXSWAPINTERVALEXT) (int);
- GLXSWAPINTERVALEXT glXSwapIntervalEXT;
- void *glXExtension(Display *dpy,int screen,const char *catagory,const char *name){
- const char *extensions;
- extensions=glXQueryExtensionsString(dpy,screen);
- if (strstr(extensions,catagory)) {
- return (void*)glXGetProcAddressARB(name);
- }
- return (void*)0;
- }
- enum{
- MODE_SHARED=0,
- MODE_WIDGET=1,
- MODE_WINDOW=2,
- MODE_DISPLAY=3
- };
- enum{
- FLAGS_BACKBUFFER= 0x2,
- FLAGS_ALPHABUFFER= 0x4,
- FLAGS_DEPTHBUFFER= 0x8,
- FLAGS_STENCILBUFFER=0x10,
- FLAGS_ACCUMBUFFER= 0x20,
- FLAGS_BORDERLESS= 0x40,
- FLAGS_FULLSCREEN_DESKTOP=0x80
- };
- typedef struct BBGLContext BBGLContext;
- struct BBGLContext{
- int mode,width,height,depth,hertz;
- BBInt64 flags;
- int sync;
- Window window;
- GLXContext glContext;
- };
- // glgraphics.bmx interface
- int bbGLGraphicsGraphicsModes( int *imodes,int maxcount );
- BBGLContext *bbGLGraphicsAttachGraphics( void * window,BBInt64 flags );
- BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hz,BBInt64 flags, int x, int y );
- void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hz,BBInt64 *flags );
- void bbGLGraphicsClose( BBGLContext *context );
- void bbGLGraphicsSetGraphics( BBGLContext *context );
- void bbGLGraphicsFlip( int sync );
- void bbGLExit();
- static BBGLContext *_currentContext;
- static BBGLContext *_activeContext;
- static BBGLContext *_sharedContext;
- #define INTERLACE 0x010
- #define DBLSCAN 0x020
- static XF86VidModeModeInfo _oldMode;
- int _calchertz(XF86VidModeModeInfo *m){
- int freq;
- freq=(m->dotclock*1000.0)/(m->htotal*m->vtotal)+.5;
- if (m->flags&INTERLACE) freq<<=1;
- if (m->flags&DBLSCAN) freq>>=1;
- return freq;
- }
- int _initDisplay(){
- int major,minor;
- if (xdisplay) return 0;
- xdisplay=bbSystemDisplay();
- if (!xdisplay) return -1;
- if (glXQueryVersion(xdisplay,&major,&minor)==0) return -1;
-
- // printf("glXVersion=%d.%d\n",major,minor);fflush(stdout);
- XF86VidModeQueryVersion(xdisplay,&major,&minor);
-
- // printf("XF86VidModeExtension-Version %d.%d\n", major,minor);
- xscreen=DefaultScreen(xdisplay);
-
- // glXSwapIntervalEXT=(GLXSWAPINTERVALEXT)glXGetProcAddressARB("glXSwapIntervalSGI");
- glXSwapIntervalEXT=(GLXSWAPINTERVALEXT)glXExtension(xdisplay,xscreen,"GLX_SGI_swap_control","glXSwapIntervalSGI");
- atexit( bbGLExit );
- return 0;
- }
- int bbGLGraphicsGraphicsModes( int *imodes,int maxcount ){
- XF86VidModeModeInfo **xmodes,*m;
- int count,i;
- if (_initDisplay()) return 0;
- XF86VidModeGetAllModeLines(xdisplay,xscreen,&count,&xmodes);
- if (count>maxcount) count=maxcount;
- for (i=0;i<count;i++)
- {
- m=xmodes[i];
- *imodes++=m->hdisplay; //width
- *imodes++=m->vdisplay; //height;
- *imodes++=24;
- *imodes++=_calchertz(m);
- }
- XFree(xmodes);
- return count;
- }
- static void _swapBuffers( BBGLContext *context ){
- if( !context ) return;
- glXSwapBuffers(xdisplay,context->window);
- bbSystemPoll();
- }
- BBGLContext *bbGLGraphicsAttachGraphics( void * window,BBInt64 flags ){
- BBGLContext *context=(BBGLContext*)malloc( sizeof(BBGLContext) );
- memset( context,0,sizeof(BBGLContext) );
- context->mode=MODE_WIDGET;
- context->flags=flags;
- context->sync=-1;
- context->window=(Window)window;
- return context;
- }
- XVisualInfo *_chooseVisual(BBInt64 flags){
- int glspec[32],*s;
- s=glspec;
- *s++=GLX_RGBA;
- if (flags&FLAGS_BACKBUFFER) *s++=GLX_DOUBLEBUFFER;
- if (flags&FLAGS_ALPHABUFFER) {*s++=GLX_ALPHA_SIZE;*s++=1;}
- if (flags&FLAGS_DEPTHBUFFER) {*s++=GLX_DEPTH_SIZE;*s++=1;}
- if (flags&FLAGS_STENCILBUFFER) {*s++=GLX_STENCIL_SIZE;*s++=1;}
- if (flags&FLAGS_ACCUMBUFFER)
- {
- *s++=GLX_ACCUM_RED_SIZE;*s++=1;
- *s++=GLX_ACCUM_GREEN_SIZE;*s++=1;
- *s++=GLX_ACCUM_BLUE_SIZE;*s++=1;
- *s++=GLX_ACCUM_ALPHA_SIZE;*s++=1;
- }
- *s++=None;
- return glXChooseVisual(xdisplay,xscreen,glspec);
- }
- void _makeCurrent( BBGLContext *context ){
- glXMakeCurrent(xdisplay,context->window,context->glContext);
- _currentContext=context;
- }
- static void _validateSize( BBGLContext *context ){
- Window root_return;
- int x,y;
- unsigned int w,h,border,d;
- if( !context || context->mode!=MODE_WIDGET ) return;
- if (_initDisplay()) return;
- XGetGeometry(xdisplay,context->window,&root_return,&x,&y,&w,&h,&border,&d);
- context->width=w;
- context->height=h;
- }
- static void _validateContext( BBGLContext *context ){
- GLXContext sharedcontext=0;
- XVisualInfo *vizinfo;
- if( !context || context->glContext ) return;
- if (_initDisplay()) return;
- //_initSharedContext();
- if( _sharedContext ) sharedcontext=_sharedContext->glContext;
-
- vizinfo=_chooseVisual(context->flags);
- context->glContext=glXCreateContext(xdisplay,vizinfo,sharedcontext,True);
- glXMakeCurrent(xdisplay,context->window,context->glContext);
- bbSetSystemWindow(context->window);
- }
- void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,BBInt64 *flags ){
- _validateSize( context );
- *width=context->width;
- *height=context->height;
- *depth=context->depth;
- *hertz=context->hertz;
- *flags=context->flags;
- }
- static Bool WaitForNotify(Display *display,XEvent *event,XPointer arg){
- return (event->type==MapNotify) && (event->xmap.window==(Window)arg);
- }
- void bbGLGraphicsShareContexts(){
- if( _sharedContext ) return;
- _sharedContext=bbGLGraphicsCreateGraphics(0,0,0,0,0,0,0);
- }
- BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hz,BBInt64 flags, int x, int y ){
- XSetWindowAttributes swa;
- XVisualInfo *vizinfo;
- XEvent event;
- GLXContext context;
- int window;
- int count,i;
- int displaymode;
- int initingShared=0;
- GLXContext sharedcontext=0;
- char *appTitle;
- if (_initDisplay()) return 0;
-
- if( width==0 && height==0 )
- {
- width=100;
- height=100;
- initingShared=1;
- }
- else
- {
- if( _sharedContext ) sharedcontext=_sharedContext->glContext;
-
- //_initSharedContext();
- //sharedcontext=_sharedContext->glContext;
- }
- vizinfo=_chooseVisual(flags);
- int border = (flags & FLAGS_BORDERLESS) ? 0 : CWBorderPixel;
- if (depth)
- {
- XF86VidModeGetModeLine(xdisplay,xscreen,&_oldMode.dotclock,(XF86VidModeModeLine*)&_oldMode.hdisplay );
- XF86VidModeGetAllModeLines(xdisplay,xscreen,&count,&modes);
- mode=0;
- for (i=0;i<count;i++)
- {
- if (width==modes[i]->hdisplay && height==modes[i]->vdisplay && hz==_calchertz(modes[i]))
- {
- mode=modes[i];
- break;
- }
- }
- if (mode==0)
- {
- for (i=0;i<count;i++)
- {
- if (width==modes[i]->hdisplay && height==modes[i]->vdisplay)
- {
- mode=modes[i];
- break;
- }
- }
- }
- if (mode==0) return;
- width=mode->hdisplay;
- height=mode->vdisplay;
- vizinfo=_chooseVisual(flags);
-
- swa.border_pixel=0;
- swa.event_mask=StructureNotifyMask;
- swa.colormap=XCreateColormap(xdisplay,RootWindow(xdisplay,0),vizinfo->visual,AllocNone);
- swa.override_redirect=True;
- XF86VidModeSwitchToMode(xdisplay,xscreen,mode);
- XF86VidModeSetViewPort(xdisplay,xscreen,0,0);
- window=XCreateWindow(
- xdisplay,
- RootWindow(xdisplay,xscreen),
- 0,
- 0,
- width,height,
- 0,
- vizinfo->depth,
- InputOutput,
- vizinfo->visual,
- border|CWEventMask|CWColormap|CWOverrideRedirect,
- &swa
- );
- xfullscreen=1;
- displaymode=MODE_DISPLAY;
- }
- else
- {
- Atom atom;
- XSizeHints *hints;
-
- if (x < 0) x = 0 ;
- if (y < 0) y = 0 ;
-
- swa.border_pixel=0;
- swa.event_mask=StructureNotifyMask;
- swa.colormap=XCreateColormap( xdisplay,RootWindow(xdisplay,0),vizinfo->visual,AllocNone );
- window=XCreateWindow(
- xdisplay,
- RootWindow(xdisplay,xscreen),
- x,
- y,
- width,height,
- 0,
- vizinfo->depth,
- InputOutput,
- vizinfo->visual,
- border|CWColormap|CWEventMask,
- &swa
- );
- //Tell window to send us 'close window events'
- atom=XInternAtom( xdisplay,"WM_DELETE_WINDOW",True );
- XSetWMProtocols( xdisplay,window,&atom,1 );
- //Set window min/max size
- hints=XAllocSizeHints();
- hints->flags=PMinSize|PMaxSize|PPosition;
- hints->x = x;
- hints->y = y;
- hints->min_width=hints->max_width=width;
- hints->min_height=hints->max_height=height;
- XSetWMNormalHints( xdisplay,window,hints );
-
- displaymode=MODE_WINDOW;
- }
-
- context=glXCreateContext(xdisplay,vizinfo,sharedcontext,True);
-
- if( !initingShared )
- {
- XMapRaised(xdisplay,window);
- if (xfullscreen)
- {
- XWarpPointer(xdisplay,None,window,0,0,0,0,0,0);
- XGrabKeyboard(xdisplay,window,True,GrabModeAsync,GrabModeAsync,CurrentTime);
- XGrabPointer(xdisplay,window,True,ButtonPressMask,GrabModeAsync,GrabModeAsync,window,None,CurrentTime);
- }
- glXMakeCurrent(xdisplay,window,context);
- XIfEvent(xdisplay,&event,WaitForNotify,(XPointer)window);
- XSelectInput(xdisplay,window,ResizeRedirectMask|FocusChangeMask|PointerMotionMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask);
- xwindow=window;
- bbSetSystemWindow(xwindow);
- }
- appTitle=bbStringToUTF8String( bbAppTitle );
-
- XChangeProperty( xdisplay,window, XInternAtom( xdisplay,"_NET_WM_NAME",True ),
- XInternAtom( xdisplay,"UTF8_STRING",True ), 8,PropModeReplace,appTitle,strlen( appTitle ) );
- bbMemFree(appTitle);
- // XStoreName( xdisplay,window,appTitle );
-
- bbSystemPoll();
- BBGLContext *bbcontext=(BBGLContext*)malloc( sizeof(BBGLContext) );
- memset( bbcontext,0,sizeof(BBGLContext) );
- bbcontext->mode=displaymode;
- bbcontext->width=width;
- bbcontext->height=height;
- bbcontext->depth=24;
- bbcontext->hertz=hz;
- bbcontext->flags=flags;
- bbcontext->sync=-1;
- bbcontext->window=window;
- bbcontext->glContext=context;
- return bbcontext;
- }
- void bbGLGraphicsSetGraphics( BBGLContext *context ){
- if( context ){
- _validateSize( context );
- _validateContext( context );
- }
- if( !context || context==_currentContext ) return;
- _makeCurrent(context);
- _activeContext=context;
- }
- void bbGLGraphicsFlip( int sync ){
- if( !_currentContext ) return;
- sync=sync ? 1 : 0;
- if( sync!=_currentContext->sync ){
- _currentContext->sync=sync;
- if ( glXSwapIntervalEXT ) {
- glXSwapIntervalEXT( sync );
- }
- }
- _swapBuffers( _currentContext );
- }
- void bbGLGraphicsClose( BBGLContext *context ){
- if (context){
- if (_currentContext==context) _currentContext=0;
- if (context->glContext)
- {
- glXMakeCurrent(xdisplay,None,NULL);
- glXDestroyContext(xdisplay,context->glContext);
- }
- if (context->window && context->mode!=MODE_WIDGET){
- XDestroyWindow(xdisplay,context->window);
- }
- if (context->mode==MODE_DISPLAY){
- XF86VidModeSwitchToMode(xdisplay,xscreen,&_oldMode);
- XF86VidModeSetViewPort(xdisplay,xscreen,0,0);
- XFlush(xdisplay);
- XFree(modes);
- modes=0;
- mode=0;
- xfullscreen=0;
- }
- free( context );
- }
- }
- void bbGLExit(){
- bbGLGraphicsClose( _currentContext );
- bbGLGraphicsClose( _sharedContext );
- _currentContext=0;
- _sharedContext=0;
- }
|