Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
glut_overlay.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <assert.h>
00012 #include <X11/Xlib.h>
00013 #include <X11/Xutil.h>
00014 #include <X11/Xatom.h>
00015 #if defined (__vms)
00016 #include <X11/StdCmap.h>
00017 #else
00018 #include <X11/Xmu/StdCmap.h>
00019 #endif
00020
00021 #include <GL/glut.h>
00022 #include "glutint.h"
00023 #include "layerutil.h"
00024
00025 static int
00026 checkOverlayAcceptability(XVisualInfo * vi, unsigned int mode)
00027 {
00028 int value;
00029
00030
00031 glXGetConfig(__glutDisplay, vi, GLX_USE_GL, &value);
00032 if (!value)
00033 return 1;
00034
00035
00036 glXGetConfig(__glutDisplay, vi, GLX_RGBA, &value);
00037 if (value)
00038 return 1;
00039
00040
00041 glXGetConfig(__glutDisplay, vi, GLX_DOUBLEBUFFER, &value);
00042 if (GLUT_WIND_IS_DOUBLE(mode) != (value != 0))
00043 return 1;
00044
00045
00046 glXGetConfig(__glutDisplay, vi, GLX_STEREO, &value);
00047 if (GLUT_WIND_IS_STEREO(mode) != (value != 0))
00048 return 1;
00049
00050
00051
00052 if (GLUT_WIND_HAS_ALPHA(mode) || GLUT_WIND_HAS_ACCUM(mode))
00053 return 1;
00054
00055
00056 glXGetConfig(__glutDisplay, vi, GLX_DEPTH_SIZE, &value);
00057 if (GLUT_WIND_HAS_DEPTH(mode) && (value <= 0))
00058 return 1;
00059
00060
00061 glXGetConfig(__glutDisplay, vi, GLX_STENCIL_SIZE, &value);
00062 if (GLUT_WIND_HAS_STENCIL(mode) && (value <= 0))
00063 return 1;
00064
00065 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
00066
00067
00068 if (__glutIsSupportedByGLX("GLX_SGIS_multisample"))
00069 glXGetConfig(__glutDisplay, vi, GLX_SAMPLES_SGIS, &value);
00070 else
00071 value = 0;
00072 if (GLUT_WIND_IS_MULTISAMPLE(mode) && (value <= 0))
00073 return 1;
00074 #endif
00075
00076 return 0;
00077 }
00078
00079 static XVisualInfo *
00080 getOverlayVisualInfoCI(unsigned int mode)
00081 {
00082 XLayerVisualInfo *vi;
00083 XLayerVisualInfo template;
00084 XVisualInfo *goodVisual, *returnVisual;
00085 int nitems, i, j, bad;
00086
00087
00088
00089
00090
00091
00092
00093
00094 for (i = 1; i <= 3; i++) {
00095 template.vinfo.screen = __glutScreen;
00096 template.vinfo.class = PseudoColor;
00097 template.layer = i;
00098 template.type = TransparentPixel;
00099 vi = __glutXGetLayerVisualInfo(__glutDisplay,
00100 VisualTransparentType | VisualScreenMask | VisualClassMask | VisualLayerMask,
00101 &template, &nitems);
00102 if (vi) {
00103
00104
00105 for (j = 0; j < nitems; j++) {
00106 bad = checkOverlayAcceptability(&vi[j].vinfo, mode);
00107 if (bad) {
00108
00109 vi[j].vinfo.visual = NULL;
00110 }
00111 }
00112
00113
00114 goodVisual = NULL;
00115 for (j = 0; j < nitems; j++) {
00116 if (vi[j].vinfo.visual) {
00117 if (goodVisual == NULL) {
00118 goodVisual = &vi[j].vinfo;
00119 } else {
00120 if (goodVisual->depth < vi[j].vinfo.depth) {
00121 goodVisual = &vi[j].vinfo;
00122 }
00123 }
00124 }
00125 }
00126
00127
00128 if (goodVisual) {
00129 returnVisual = (XVisualInfo *) malloc(sizeof(XVisualInfo));
00130 if (returnVisual) {
00131 *returnVisual = *goodVisual;
00132 }
00133 XFree(vi);
00134 return returnVisual;
00135 }
00136 XFree(vi);
00137 }
00138 }
00139 return NULL;
00140 }
00141
00142 static XVisualInfo *
00143 getOverlayVisualInfoRGB(unsigned int mode)
00144 {
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 __glutWarning("RGBA overlays are not supported by GLUT (for now).");
00240 return NULL;
00241 }
00242
00243 static XVisualInfo *
00244 getOverlayVisualInfo(unsigned int mode)
00245 {
00246
00247 if (GLUT_WIND_IS_LUMINANCE(mode))
00248 return NULL;
00249
00250 if (GLUT_WIND_IS_RGB(mode))
00251 return getOverlayVisualInfoRGB(mode);
00252 else
00253 return getOverlayVisualInfoCI(mode);
00254 }
00255
00256 static void
00257 addStaleWindow(GLUTwindow * window, Window win)
00258 {
00259 GLUTstale *entry;
00260
00261 entry = (GLUTstale *) malloc(sizeof(GLUTstale));
00262 if (!entry)
00263 __glutFatalError("out of memory");
00264 entry->window = window;
00265 entry->win = win;
00266 entry->next = __glutStaleWindowList;
00267 __glutStaleWindowList = entry;
00268 }
00269
00270 void
00271 __glutFreeOverlay(GLUToverlay * overlay)
00272 {
00273 XFree(overlay->vis);
00274 XDestroyWindow(__glutDisplay, overlay->win);
00275 glXDestroyContext(__glutDisplay, overlay->ctx);
00276 if (overlay->colormap) {
00277
00278 __glutFreeColormap(overlay->colormap);
00279 }
00280 free(overlay);
00281 }
00282
00283 void
00284 glutEstablishOverlay(void)
00285 {
00286 GLUToverlay *overlay;
00287 GLUTwindow *window;
00288 XSetWindowAttributes wa;
00289
00290
00291
00292
00293
00294 __glutFreeOverlayFunc = __glutFreeOverlay;
00295
00296 window = __glutCurrentWindow;
00297
00298
00299
00300 if (window->overlay) {
00301 addStaleWindow(window, window->overlay->win);
00302 __glutFreeOverlay(window->overlay);
00303 }
00304 overlay = (GLUToverlay *) malloc(sizeof(GLUToverlay));
00305 if (!overlay)
00306 __glutFatalError("out of memory.");
00307
00308 overlay->vis = __glutDetermineVisual(__glutDisplayMode,
00309 &overlay->fakeSingle, getOverlayVisualInfo);
00310 if (!overlay->vis) {
00311 __glutFatalError("lacks overlay support.");
00312 }
00313 overlay->ctx = glXCreateContext(__glutDisplay, overlay->vis,
00314 None, __glutTryDirect);
00315 overlay->isDirect = glXIsDirect(__glutDisplay, overlay->ctx);
00316 if (__glutForceDirect) {
00317 if (!overlay->isDirect) {
00318 __glutFatalError("direct rendering not possible.");
00319 }
00320 }
00321 __glutSetupColormap(overlay->vis, &(overlay->colormap), &(overlay->cmap));
00322 overlay->transparentPixel = __glutGetTransparentPixel(__glutDisplay,
00323 overlay->vis);
00324
00325 wa.colormap = overlay->cmap;
00326 wa.background_pixel = overlay->transparentPixel;
00327 wa.event_mask = window->eventMask & GLUT_OVERLAY_EVENT_FILTER_MASK;
00328 wa.border_pixel = 0;
00329 overlay->win = XCreateWindow(__glutDisplay,
00330 window->win,
00331 0, 0, window->width, window->height, 0,
00332 overlay->vis->depth, InputOutput, overlay->vis->visual,
00333 CWBackPixel | CWBorderPixel | CWEventMask | CWColormap,
00334 &wa);
00335 if (window->children) {
00336
00337
00338 XLowerWindow(__glutDisplay, overlay->win);
00339 }
00340 XMapWindow(__glutDisplay, overlay->win);
00341 overlay->shownState = 1;
00342
00343 overlay->damaged = 0;
00344 overlay->display = NULL;
00345
00346
00347 window->forceReshape = True;
00348
00349 __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
00350
00351 window->overlay = overlay;
00352 glutUseLayer(GLUT_OVERLAY);
00353 }
00354
00355 void
00356 glutRemoveOverlay(void)
00357 {
00358 GLUTwindow *window = __glutCurrentWindow;
00359 GLUToverlay *overlay = __glutCurrentWindow->overlay;
00360
00361 if (!window->overlay)
00362 return;
00363
00364
00365 if (window->renderWin == overlay->win) {
00366 glutUseLayer(GLUT_NORMAL);
00367 }
00368 addStaleWindow(window, overlay->win);
00369 __glutFreeOverlay(overlay);
00370 window->overlay = NULL;
00371 __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
00372 }
00373
00374 void
00375 glutUseLayer(GLenum layer)
00376 {
00377 GLUTwindow *window = __glutCurrentWindow;
00378
00379 switch (layer) {
00380 case GLUT_NORMAL:
00381 window->renderWin = window->win;
00382 window->renderCtx = window->ctx;
00383 break;
00384 case GLUT_OVERLAY:
00385 window->renderWin = window->overlay->win;
00386 window->renderCtx = window->overlay->ctx;
00387 break;
00388 default:
00389 __glutWarning("glutUseLayer: unknown layer, %d.", layer);
00390 break;
00391 }
00392 __glutSetWindow(window);
00393 }
00394
00395 void
00396 glutPostOverlayRedisplay(void)
00397 {
00398 __glutPostRedisplay(__glutCurrentWindow, GLUT_OVERLAY_REDISPLAY_WORK);
00399 }
00400
00401 void
00402 glutOverlayDisplayFunc(GLUTdisplayCB displayFunc)
00403 {
00404 if (!__glutCurrentWindow->overlay) {
00405 __glutWarning("glutOverlayDisplayFunc: window has no overlay established");
00406 return;
00407 }
00408 __glutCurrentWindow->overlay->display = displayFunc;
00409 }
00410
00411 void
00412 glutHideOverlay(void)
00413 {
00414 if (!__glutCurrentWindow->overlay) {
00415 __glutWarning("glutHideOverlay: window has no overlay established");
00416 return;
00417 }
00418 XUnmapWindow(__glutDisplay, __glutCurrentWindow->overlay->win);
00419 __glutCurrentWindow->overlay->shownState = 0;
00420 }
00421
00422 void
00423 glutShowOverlay(void)
00424 {
00425 if (!__glutCurrentWindow->overlay) {
00426 __glutWarning("glutShowOverlay: window has no overlay established");
00427 return;
00428 }
00429 XMapWindow(__glutDisplay, __glutCurrentWindow->overlay->win);
00430 __glutCurrentWindow->overlay->shownState = 1;
00431 }
00432
00433 int
00434 glutLayerGet(GLenum param)
00435 {
00436 switch (param) {
00437 case GLUT_OVERLAY_POSSIBLE:
00438 {
00439 XVisualInfo *vi;
00440 Bool dummy;
00441
00442 vi = __glutDetermineVisual(__glutDisplayMode, &dummy, getOverlayVisualInfo);
00443 if (vi) {
00444 XFree(vi);
00445 return 1;
00446 }
00447 return 0;
00448 }
00449 case GLUT_LAYER_IN_USE:
00450 return __glutCurrentWindow->renderWin != __glutCurrentWindow->win;
00451 case GLUT_HAS_OVERLAY:
00452 return __glutCurrentWindow->overlay != NULL;
00453 case GLUT_TRANSPARENT_INDEX:
00454 if (__glutCurrentWindow->overlay) {
00455 return __glutCurrentWindow->overlay->transparentPixel;
00456 } else {
00457 return -1;
00458 }
00459 case GLUT_NORMAL_DAMAGED:
00460
00461
00462
00463
00464
00465
00466 return __glutCurrentWindow->damaged || __glutWindowDamaged;
00467 case GLUT_OVERLAY_DAMAGED:
00468 if (__glutCurrentWindow->overlay) {
00469 return __glutCurrentWindow->overlay->damaged || __glutWindowDamaged;
00470 } else {
00471 return -1;
00472 }
00473 default:
00474 __glutWarning("invalid glutLayerGet param: %d", param);
00475 return -1;
00476 }
00477 }