#include #include #include #include "tk.h" #include "private.h" /******************************************************************************/ Display *xDisplay = 0; int xScreen = 0; Window wRoot = 0; Atom deleteWindowAtom; WINDOW_REC w = { 0, 0, 300, 300, TK_RGB|TK_SINGLE|TK_DIRECT, TK_MINIMUM_CRITERIA }; float colorMaps[] = { 0.000000, 1.000000, 0.000000, 1.000000, 0.000000, 1.000000, 0.000000, 1.000000, 0.333333, 0.776471, 0.443137, 0.556863, 0.443137, 0.556863, 0.219608, 0.666667, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.039216, 0.078431, 0.117647, 0.156863, 0.200000, 0.239216, 0.278431, 0.317647, 0.356863, 0.400000, 0.439216, 0.478431, 0.517647, 0.556863, 0.600000, 0.639216, 0.678431, 0.717647, 0.756863, 0.800000, 0.839216, 0.878431, 0.917647, 0.956863, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.000000, 0.000000, 1.000000, 1.000000, 0.000000, 0.000000, 1.000000, 1.000000, 0.333333, 0.443137, 0.776471, 0.556863, 0.443137, 0.219608, 0.556863, 0.666667, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.039216, 0.078431, 0.117647, 0.156863, 0.200000, 0.239216, 0.278431, 0.317647, 0.356863, 0.400000, 0.439216, 0.478431, 0.517647, 0.556863, 0.600000, 0.639216, 0.678431, 0.717647, 0.756863, 0.800000, 0.839216, 0.878431, 0.917647, 0.956863, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.141176, 0.282353, 0.427451, 0.568627, 0.713726, 0.854902, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.333333, 0.443137, 0.443137, 0.219608, 0.776471, 0.556863, 0.556863, 0.666667, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.666667, 0.333333, 0.039216, 0.078431, 0.117647, 0.156863, 0.200000, 0.239216, 0.278431, 0.317647, 0.356863, 0.400000, 0.439216, 0.478431, 0.517647, 0.556863, 0.600000, 0.639216, 0.678431, 0.717647, 0.756863, 0.800000, 0.839216, 0.878431, 0.917647, 0.956863, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.247059, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.498039, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 0.749020, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }; float tkRGBMap[8][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 1, 1, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }; /******************************************************************************/ void tkCloseWindow(void) { if (xDisplay) { cursorNum = 0; ExposeFunc = 0; ReshapeFunc = 0; IdleFunc = 0; DisplayFunc = 0; KeyDownFunc = 0; MouseDownFunc = 0; MouseUpFunc = 0; MouseMoveFunc = 0; glFlush(); glFinish(); if (TK_HAS_OVERLAY(w.type)) { XDestroyWindow(xDisplay, w.wOverlay); glXDestroyContext(xDisplay, w.cOverlay); XFreeColormap(xDisplay, w.cMapOverlay); XFree((char *)w.vInfoOverlay); } XDestroyWindow(xDisplay, w.wMain); glXDestroyContext(xDisplay, w.cMain); XFreeColormap(xDisplay, w.cMapMain); XFree((char *)w.vInfoMain); XCloseDisplay(xDisplay); xDisplay = 0; } } /******************************************************************************/ static int ErrorHandler(Display *xDisplay, XErrorEvent *event) { char buf[80]; printf("\nReceived X error!\n"); printf("\tError code : %d\n", event->error_code); printf("\tRequest code : %d\n", event->request_code); printf("\tMinor code : %d\n\n", event->minor_code); XGetErrorText(xDisplay, event->error_code, buf, 80); printf("\tError text : '%s'\n\n", buf); return 0; } /******************************************************************************/ void tkInitDisplayMode(GLenum type) { w.type = type; } /******************************************************************************/ void tkInitDisplayModePolicy(GLenum type) { w.dmPolicy = type; } /******************************************************************************/ GLenum tkInitDisplayModeID(GLint id) { XVisualInfo sampleVis; int nvis; if (!xDisplay && !tkInitDisplay()) return(GL_FALSE); sampleVis.visualid = id; w.vInfoMain = XGetVisualInfo(xDisplay, VisualIDMask, &sampleVis, &nvis); if (w.vInfoMain) return GL_TRUE; else return GL_FALSE; } /******************************************************************************/ void tkInitPosition(int x, int y, int width, int height) { w.x = x; w.y = y; w.w = width; w.h = height; } /******************************************************************************/ static XVisualInfo *FindBestMainVisual(GLenum type) { int list[32], i; i = 0; list[i++] = GLX_LEVEL; list[i++] = 0; if (TK_IS_DOUBLE(type)) { list[i++] = GLX_DOUBLEBUFFER; } if (TK_IS_RGB(type)) { list[i++] = GLX_RGBA; list[i++] = GLX_RED_SIZE; list[i++] = 1; list[i++] = GLX_GREEN_SIZE; list[i++] = 1; list[i++] = GLX_BLUE_SIZE; list[i++] = 1; if (TK_HAS_ALPHA(type)) { list[i++] = GLX_ALPHA_SIZE; list[i++] = 1; } if (TK_HAS_ACCUM(type)) { list[i++] = GLX_ACCUM_RED_SIZE; list[i++] = 1; list[i++] = GLX_ACCUM_GREEN_SIZE; list[i++] = 1; list[i++] = GLX_ACCUM_BLUE_SIZE; list[i++] = 1; if (TK_HAS_ALPHA(type)) { list[i++] = GLX_ACCUM_ALPHA_SIZE; list[i++] = 1; } } } else if (TK_IS_INDEX(type)) { list[i++] = GLX_BUFFER_SIZE; list[i++] = 1; } if (TK_HAS_DEPTH(type)) { list[i++] = GLX_DEPTH_SIZE; list[i++] = 1; } if (TK_HAS_STENCIL(type)) { list[i++] = GLX_STENCIL_SIZE; list[i++] = 1; } list[i] = (int)None; return glXChooseVisual(xDisplay, xScreen, list); } /******************************************************************************/ static XVisualInfo *FindExactMainVisual(GLenum type) { int i, nvis, val, rval, gval, bval, aval; XVisualInfo *vis_list, *this_vis, *best_vis, sampleVis; int this_score, best_score; /* Get list of visuals for this screen */ sampleVis.screen = xScreen; vis_list = XGetVisualInfo( xDisplay, VisualScreenMask, &sampleVis, &nvis); /* * Loop through the visuals; find first one that matches the attr * specified in type */ best_score = -1; best_vis = NULL; for ( i = 0; i < nvis; i++ ) { this_vis = &vis_list[i]; /* Visual must be supported by GLX */ if ( glXGetConfig(xDisplay, this_vis, GLX_USE_GL, &val) ) continue; if ( !val ) continue; /* Visual must be in main planes which is level 0 */ glXGetConfig(xDisplay, this_vis, GLX_LEVEL, &val); if ( val != 0 ) continue; /* Color Index or RGBA? It must match the requested value */ glXGetConfig(xDisplay, this_vis, GLX_RGBA, &val); if ( TK_IS_RGB(type) && !val ) continue; if ( TK_IS_INDEX(type) && val ) continue; /* Double buffered or Single buffered? */ glXGetConfig( xDisplay, this_vis, GLX_DOUBLEBUFFER, &val); if ( TK_IS_DOUBLE(type) && !val ) continue; if ( TK_IS_SINGLE(type) && val ) continue; /* If accum requested then accum rgb size must be > 0 */ /* If alpha requested then alpha size must be > 0 */ /* if accum & alpha requested then accum alpha size must be > 0 */ if ( TK_IS_RGB(type) ) { glXGetConfig(xDisplay, this_vis, GLX_ACCUM_RED_SIZE, &rval); glXGetConfig(xDisplay, this_vis, GLX_ACCUM_GREEN_SIZE, &gval); glXGetConfig(xDisplay, this_vis, GLX_ACCUM_BLUE_SIZE, &bval); glXGetConfig(xDisplay, this_vis, GLX_ACCUM_ALPHA_SIZE, &aval); if ( TK_HAS_ACCUM(type) ) { if ( rval <= 0 || gval <= 0 || bval <= 0 ) continue; } else { if ( rval > 0 || gval > 0 || bval > 0 || aval > 0 ) continue; } glXGetConfig(xDisplay, this_vis, GLX_ALPHA_SIZE, &val); if ( TK_HAS_ALPHA(type) ) { if ( val <= 0 ) continue; if ( TK_HAS_ACCUM(type) && aval <= 0 ) continue; } else { if ( val > 0 ) continue; } } /* Check depth buffer */ glXGetConfig(xDisplay, this_vis, GLX_DEPTH_SIZE, &val); if ( TK_HAS_DEPTH(type) ) { if ( val <= 0 ) continue; } else { if ( val > 0 ) continue; } /* Check stencil buffer */ glXGetConfig( xDisplay, this_vis, GLX_STENCIL_SIZE, &val); if ( TK_HAS_STENCIL(type) ) { if ( val <= 0 ) continue; } else { if ( val > 0 ) continue; } glXGetConfig(xDisplay, this_vis, GLX_BUFFER_SIZE, &this_score); if (this_score > best_score ) { best_score = this_score; best_vis = this_vis; } } if ( best_vis ) { sampleVis.visualid = best_vis->visualid; sampleVis.screen = xScreen; if ( nvis > 0 ) XFree(vis_list); return XGetVisualInfo(xDisplay, VisualIDMask|VisualScreenMask, &sampleVis, &nvis); } else { if ( nvis > 0 ) XFree(vis_list); return None; } } static XVisualInfo *FindOverlayVisual(void) { int list[3]; list[0] = GLX_LEVEL; list[1] = 1; list[2] = (int)None; return glXChooseVisual(xDisplay, xScreen, list); } static GLenum GetMainWindowType(XVisualInfo *vi) { GLenum mask; int x, y, z; mask = 0; glXGetConfig(xDisplay, vi, GLX_DOUBLEBUFFER, &x); if (x) { mask |= TK_DOUBLE; } else { mask |= TK_SINGLE; } glXGetConfig(xDisplay, vi, GLX_RGBA, &x); if (x) { mask |= TK_RGB; glXGetConfig(xDisplay, vi, GLX_ALPHA_SIZE, &x); if (x > 0) { mask |= TK_ALPHA; } glXGetConfig(xDisplay, vi, GLX_ACCUM_RED_SIZE, &x); glXGetConfig(xDisplay, vi, GLX_ACCUM_GREEN_SIZE, &y); glXGetConfig(xDisplay, vi, GLX_ACCUM_BLUE_SIZE, &z); if (x > 0 && y > 0 && z > 0) { mask |= TK_ACCUM; } } else { mask |= TK_INDEX; } glXGetConfig(xDisplay, vi, GLX_DEPTH_SIZE, &x); if (x > 0) { mask |= TK_DEPTH; } glXGetConfig(xDisplay, vi, GLX_STENCIL_SIZE, &x); if (x > 0) { mask |= TK_STENCIL; } if (glXIsDirect(xDisplay, w.cMain)) { mask |= TK_DIRECT; } else { mask |= TK_INDIRECT; } return mask; } static int WaitForMainWindow(Display *d, XEvent *e, char *arg) { if (e->type == MapNotify && e->xmap.window == w.wMain) { return GL_TRUE; } else { return GL_FALSE; } } static int WaitForOverlayWindow(Display *d, XEvent *e, char *arg) { if (e->type == MapNotify && e->xmap.window == w.wOverlay) { return GL_TRUE; } else { return GL_FALSE; } } GLenum tkInitDisplay(void) { int erb, evb; xDisplay = XOpenDisplay(0); if (!xDisplay) { fprintf(stderr, "Can't connect to xDisplay!\n"); return GL_FALSE; } if (!glXQueryExtension(xDisplay, &erb, &evb)) { fprintf(stderr, "No glx extension!\n"); return GL_FALSE; } xScreen = DefaultScreen(xDisplay); wRoot = RootWindow(xDisplay, xScreen); XSetErrorHandler(ErrorHandler); return(GL_TRUE); } GLenum tkInitWindow(char *title) { XSetWindowAttributes wa; XTextProperty tp; XSizeHints sh; XEvent e; GLenum overlayFlag; if (!xDisplay && !tkInitDisplay()) return(GL_FALSE); if (TK_HAS_OVERLAY(w.type)) { overlayFlag = GL_TRUE; } else { overlayFlag = GL_FALSE; } w.type &= ~TK_OVERLAY; if (w.dmPolicy == TK_MINIMUM_CRITERIA) w.vInfoMain = FindBestMainVisual(w.type); else if (w.dmPolicy == TK_EXACT_MATCH) w.vInfoMain = FindExactMainVisual(w.type); if (!w.vInfoMain) { fprintf(stderr, "Window type not found!\n"); return GL_FALSE; } w.cMain = glXCreateContext(xDisplay, w.vInfoMain, None, (TK_IS_DIRECT(w.type))?GL_TRUE:GL_FALSE); if (!w.cMain) { fprintf(stderr, "Can't create a context!\n"); return GL_FALSE; } w.type = GetMainWindowType(w.vInfoMain); if (TK_IS_INDEX(w.type)) { if (w.vInfoMain->class != StaticColor && w.vInfoMain->class != StaticGray) { w.cMapMain = XCreateColormap(xDisplay, wRoot, w.vInfoMain->visual, AllocAll); } else { w.cMapMain = XCreateColormap(xDisplay, wRoot, w.vInfoMain->visual, AllocNone); } } else { w.cMapMain = XCreateColormap(xDisplay, wRoot, w.vInfoMain->visual, AllocNone); } tkSetRGBMap(256, colorMaps); wa.colormap = w.cMapMain; wa.background_pixmap = None; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; w.wMain = XCreateWindow(xDisplay, wRoot, w.x, w.y, w.w, w.h, 0, w.vInfoMain->depth, InputOutput, w.vInfoMain->visual, CWBackPixmap|CWBorderPixel|CWEventMask|CWColormap, &wa); XStringListToTextProperty(&title, 1, &tp); sh.flags = USPosition | USSize; XSetWMProperties(xDisplay, w.wMain, &tp, &tp, 0, 0, &sh, 0, 0); deleteWindowAtom = XInternAtom(xDisplay, "WM_DELETE_WINDOW", False); XSetWMProtocols(xDisplay, w.wMain, &deleteWindowAtom, 1); XMapWindow(xDisplay, w.wMain); drawAllowFlag = GL_FALSE; XIfEvent(xDisplay, &e, WaitForMainWindow, 0); if (overlayFlag == GL_TRUE) { w.vInfoOverlay = FindOverlayVisual(); if (w.vInfoOverlay) { w.cOverlay = glXCreateContext(xDisplay, w.vInfoOverlay, None, GL_TRUE); w.cMapOverlay = XCreateColormap(xDisplay, wRoot, w.vInfoOverlay->visual, AllocNone); tkSetOverlayMap(256, colorMaps); wa.colormap = w.cMapOverlay; wa.background_pixmap = None; wa.border_pixel = 0; w.wOverlay = XCreateWindow(xDisplay, w.wMain, 0, 0, w.w, w.h, 0, w.vInfoOverlay->depth, InputOutput, w.vInfoOverlay->visual, CWBackPixmap|CWBorderPixel|CWColormap, &wa); XMapWindow(xDisplay, w.wOverlay); XSetWMColormapWindows(xDisplay, w.wMain, &w.wOverlay, 1); w.type |= TK_OVERLAY; } else { fprintf(stderr, "Can't create a overlay plane!\n"); } } if (!glXMakeCurrent(xDisplay, w.wMain, w.cMain)) { fprintf(stderr, "Can't make window current drawable!\n"); return GL_FALSE; } XFlush(xDisplay); return GL_TRUE; } /******************************************************************************/ void tkQuit(void) { tkCloseWindow(); exit(0); } /******************************************************************************/ void tkSwapBuffers(void) { if (xDisplay) { glXSwapBuffers(xDisplay, w.wMain); } } /******************************************************************************/