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 #include <GL/glut.h>
00021 #include "glutint.h"
00022
00023 GLUTwindow *__glutCurrentWindow = NULL;
00024 GLUTwindow **__glutWindowList = NULL;
00025 int __glutWindowListSize = 0;
00026 GLUTstale *__glutStaleWindowList = NULL;
00027
00028 void (*__glutFreeOverlayFunc) (GLUToverlay *);
00029
00030 static void
00031 cleanWindowWorkList(GLUTwindow * window)
00032 {
00033 GLUTwindow **pEntry = &__glutWindowWorkList;
00034 GLUTwindow *entry = __glutWindowWorkList;
00035
00036
00037
00038 while (entry) {
00039 if (entry == window) {
00040
00041 *pEntry = entry->prevWorkWin;
00042 return;
00043 } else {
00044 pEntry = &entry->prevWorkWin;
00045 entry = *pEntry;
00046 }
00047 }
00048 }
00049
00050 static void
00051 cleanStaleWindowList(GLUTwindow * window)
00052 {
00053 GLUTstale **pEntry = &__glutStaleWindowList;
00054 GLUTstale *entry = __glutStaleWindowList;
00055
00056
00057
00058 while (entry) {
00059 if (entry->window == window) {
00060
00061 *pEntry = entry->next;
00062 free(entry);
00063 return;
00064 } else {
00065 pEntry = &entry->next;
00066 entry = *pEntry;
00067 }
00068 }
00069 }
00070
00071 static GLUTwindow *__glutWindowCache = NULL;
00072
00073 GLUTwindow *
00074 __glutGetWindow(Window win)
00075 {
00076 GLUTstale *entry;
00077 int i;
00078
00079
00080 if (__glutWindowCache && (win == __glutWindowCache->win ||
00081 (__glutWindowCache->overlay && win ==
00082 __glutWindowCache->overlay->win))) {
00083 return
00084 __glutWindowCache;
00085 }
00086
00087 for (i = 0; i < __glutWindowListSize; i++) {
00088 if (__glutWindowList[i]) {
00089 if (win == __glutWindowList[i]->win) {
00090 __glutWindowCache = __glutWindowList[i];
00091 return __glutWindowCache;
00092 }
00093 if (__glutWindowList[i]->overlay) {
00094 if (win == __glutWindowList[i]->overlay->win) {
00095 __glutWindowCache = __glutWindowList[i];
00096 return __glutWindowCache;
00097 }
00098 }
00099 }
00100 }
00101
00102
00103 for (entry = __glutStaleWindowList; entry; entry = entry->next) {
00104 if (entry->win == win)
00105 return entry->window;
00106 }
00107 return NULL;
00108 }
00109
00110 int
00111 glutGetWindow(void)
00112 {
00113 if (__glutCurrentWindow) {
00114 return __glutCurrentWindow->num + 1;
00115 } else {
00116 return 0;
00117 }
00118 }
00119
00120 void
00121 __glutSetWindow(GLUTwindow * window)
00122 {
00123
00124
00125
00126
00127
00128
00129
00130
00131 __glutCurrentWindow = window;
00132 glXMakeCurrent(__glutDisplay, __glutCurrentWindow->renderWin,
00133 __glutCurrentWindow->renderCtx);
00134
00135
00136
00137
00138
00139
00140
00141 if (!__glutCurrentWindow->isDirect)
00142 __glutPutOnWorkList(__glutCurrentWindow, GLUT_FINISH_WORK);
00143
00144
00145
00146
00147
00148 if (__glutDebug)
00149 __glutPutOnWorkList(__glutCurrentWindow, GLUT_DEBUG_WORK);
00150 }
00151
00152 void
00153 glutSetWindow(int win)
00154 {
00155 GLUTwindow *window;
00156
00157 if (win < 1 || win > __glutWindowListSize) {
00158 __glutWarning("glutWindowSet attempted on bogus window.");
00159 return;
00160 }
00161 window = __glutWindowList[win - 1];
00162 if (!window) {
00163 __glutWarning("glutWindowSet attempted on bogus window.");
00164 return;
00165 }
00166 __glutSetWindow(window);
00167 }
00168
00169 static int
00170 getUnusedWindowSlot(void)
00171 {
00172 int i;
00173
00174
00175 for (i = 0; i < __glutWindowListSize; i++) {
00176 if (!__glutWindowList[i]) {
00177 return i;
00178 }
00179 }
00180
00181 __glutWindowListSize++;
00182 if (__glutWindowList) {
00183 __glutWindowList = (GLUTwindow **)
00184 realloc(__glutWindowList,
00185 __glutWindowListSize * sizeof(GLUTwindow *));
00186 } else {
00187
00188
00189
00190 __glutWindowList = (GLUTwindow **)
00191 malloc(sizeof(GLUTwindow *));
00192 }
00193 if (!__glutWindowList)
00194 __glutFatalError("out of memory.");
00195 __glutWindowList[__glutWindowListSize - 1] = NULL;
00196 return __glutWindowListSize - 1;
00197 }
00198
00199 static XVisualInfo *
00200 getVisualInfoCI(unsigned int mode)
00201 {
00202 static int bufSizeList[] =
00203 {16, 12, 8, 4, 2, 1, 0};
00204 XVisualInfo *vi;
00205 int list[32];
00206 int i, n = 0;
00207
00208 list[n++] = GLX_BUFFER_SIZE;
00209 list[n++] = 1;
00210 if (GLUT_WIND_IS_DOUBLE(mode)) {
00211 list[n++] = GLX_DOUBLEBUFFER;
00212 }
00213 if (GLUT_WIND_IS_STEREO(mode)) {
00214 list[n++] = GLX_STEREO;
00215 }
00216 if (GLUT_WIND_HAS_DEPTH(mode)) {
00217 list[n++] = GLX_DEPTH_SIZE;
00218 list[n++] = 1;
00219 }
00220 if (GLUT_WIND_HAS_STENCIL(mode)) {
00221 list[n++] = GLX_STENCIL_SIZE;
00222 list[n++] = 1;
00223 }
00224 list[n] = (int) None;
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 for (i = 0; bufSizeList[i]; i++) {
00235
00236
00237 list[1] = bufSizeList[i];
00238 vi = glXChooseVisual(__glutDisplay,
00239 __glutScreen, list);
00240 if (vi)
00241 return vi;
00242 }
00243 return NULL;
00244 }
00245
00246 static XVisualInfo *
00247 getVisualInfoRGB(unsigned int mode)
00248 {
00249 int list[32];
00250 int n = 0;
00251
00252
00253
00254
00255
00256 list[n++] = GLX_RGBA;
00257 list[n++] = GLX_RED_SIZE;
00258 list[n++] = 1;
00259 list[n++] = GLX_GREEN_SIZE;
00260 list[n++] = 1;
00261 list[n++] = GLX_BLUE_SIZE;
00262 list[n++] = 1;
00263 if (GLUT_WIND_HAS_ALPHA(mode)) {
00264 list[n++] = GLX_ALPHA_SIZE;
00265 list[n++] = 1;
00266 }
00267 if (GLUT_WIND_IS_DOUBLE(mode)) {
00268 list[n++] = GLX_DOUBLEBUFFER;
00269 }
00270 if (GLUT_WIND_IS_STEREO(mode)) {
00271 list[n++] = GLX_STEREO;
00272 }
00273 if (GLUT_WIND_HAS_DEPTH(mode)) {
00274 list[n++] = GLX_DEPTH_SIZE;
00275 list[n++] = 1;
00276 }
00277 if (GLUT_WIND_HAS_STENCIL(mode)) {
00278 list[n++] = GLX_STENCIL_SIZE;
00279 list[n++] = 1;
00280 }
00281 if (GLUT_WIND_HAS_ACCUM(mode)) {
00282 list[n++] = GLX_ACCUM_RED_SIZE;
00283 list[n++] = 1;
00284 list[n++] = GLX_ACCUM_GREEN_SIZE;
00285 list[n++] = 1;
00286 list[n++] = GLX_ACCUM_BLUE_SIZE;
00287 list[n++] = 1;
00288 if (GLUT_WIND_HAS_ALPHA(mode)) {
00289 list[n++] = GLX_ACCUM_ALPHA_SIZE;
00290 list[n++] = 1;
00291 }
00292 }
00293 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
00294 if (GLUT_WIND_IS_MULTISAMPLE(mode)) {
00295 if (!__glutIsSupportedByGLX("GLX_SGIS_multisample"))
00296 return NULL;
00297 list[n++] = GLX_SAMPLES_SGIS;
00298
00299
00300 list[n++] = 4;
00301 }
00302 #endif
00303 list[n] = (int) None;
00304
00305 return glXChooseVisual(__glutDisplay,
00306 __glutScreen, list);
00307 }
00308
00309 XVisualInfo *
00310 __glutGetVisualInfo(unsigned int mode)
00311 {
00312
00313 if (GLUT_WIND_IS_LUMINANCE(mode))
00314 return NULL;
00315
00316 if (GLUT_WIND_IS_RGB(mode))
00317 return getVisualInfoRGB(mode);
00318 else
00319 return getVisualInfoCI(mode);
00320 }
00321
00322 XVisualInfo *
00323 __glutDetermineVisual(
00324 unsigned int displayMode,
00325 Bool * singleFake,
00326 XVisualInfo * (getVisualInfo) (unsigned int))
00327 {
00328 XVisualInfo *vis;
00329
00330 *singleFake = False;
00331 vis = getVisualInfo(displayMode);
00332 if (!vis) {
00333
00334
00335 if (GLUT_WIND_IS_SINGLE(displayMode)) {
00336
00337
00338
00339
00340
00341 displayMode |= GLUT_DOUBLE;
00342 vis = getVisualInfo(displayMode);
00343 *singleFake = True;
00344 }
00345 if (!vis && GLUT_WIND_IS_MULTISAMPLE(displayMode)) {
00346
00347
00348
00349
00350
00351
00352 displayMode &= ~GLUT_MULTISAMPLE;
00353 vis = getVisualInfo(displayMode);
00354 }
00355 }
00356 return vis;
00357 }
00358
00359 void
00360 __glutSetupColormap(XVisualInfo * vi, GLUTcolormap ** colormap, Colormap * cmap)
00361 {
00362 Status status;
00363 XStandardColormap *standardCmaps;
00364 int i, numCmaps;
00365
00366 switch (vi->class) {
00367 case PseudoColor:
00368 if (GLUT_WIND_IS_RGB(__glutDisplayMode)) {
00369
00370 *colormap = NULL;
00371 if (MaxCmapsOfScreen(DefaultScreenOfDisplay(__glutDisplay)) == 1
00372 && vi->visual == DefaultVisual(__glutDisplay, __glutScreen)) {
00373 char *private = getenv("MESA_PRIVATE_CMAP");
00374
00375 if (private) {
00376
00377 *cmap = XCreateColormap(__glutDisplay, __glutRoot,
00378 vi->visual, AllocNone);
00379 } else {
00380
00381 *cmap = DefaultColormap(__glutDisplay, __glutScreen);
00382 }
00383 } else {
00384
00385 *cmap = XCreateColormap(__glutDisplay, __glutRoot,
00386 vi->visual, AllocNone);
00387 }
00388 } else {
00389
00390
00391 *colormap = __glutAssociateColormap(vi);
00392 *cmap = (*colormap)->cmap;
00393 }
00394 break;
00395 case TrueColor:
00396 case DirectColor:
00397 *colormap = NULL;
00398 #ifndef SOLARIS_2_4_BUG
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 status = XmuLookupStandardColormap(__glutDisplay,
00410 vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP,
00411 False, True);
00412 if (status == 1) {
00413 status = XGetRGBColormaps(__glutDisplay, __glutRoot,
00414 &standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP);
00415 if (status == 1)
00416 for (i = 0; i < numCmaps; i++)
00417 if (standardCmaps[i].visualid == vi->visualid) {
00418 *cmap = standardCmaps[i].colormap;
00419 XFree(standardCmaps);
00420 return;
00421 }
00422 }
00423 #endif
00424
00425
00426
00427
00428
00429 *cmap = XCreateColormap(__glutDisplay, __glutRoot,
00430 vi->visual, AllocNone);
00431 break;
00432 case StaticColor:
00433 case StaticGray:
00434 case GrayScale:
00435
00436 *colormap = NULL;
00437 *cmap = XCreateColormap(__glutDisplay, __glutRoot,
00438 vi->visual, AllocNone);
00439 break;
00440 default:
00441 __glutFatalError(
00442 "could not allocate colormap for visual type: %d.",
00443 vi->class);
00444 }
00445 return;
00446 }
00447
00448 void
00449 __glutDefaultDisplay(void)
00450 {
00451
00452 __glutWarning("The following is a new check for GLUT 3.0; update your code.");
00453 __glutFatalError(
00454 "display needed for window %d, but no display callback.",
00455 __glutCurrentWindow->num);
00456 }
00457
00458 void
00459 __glutDefaultReshape(int width, int height)
00460 {
00461 GLUToverlay *overlay;
00462
00463
00464
00465 glXMakeCurrent(__glutDisplay, __glutCurrentWindow->win,
00466 __glutCurrentWindow->ctx);
00467 glViewport(0, 0, (GLsizei) width, (GLsizei) height);
00468 overlay = __glutCurrentWindow->overlay;
00469 if (overlay) {
00470 glXMakeCurrent(__glutDisplay, overlay->win, overlay->ctx);
00471 glViewport(0, 0, (GLsizei) width, (GLsizei) height);
00472 }
00473
00474
00475
00476
00477 glXMakeCurrent(__glutDisplay, __glutCurrentWindow->renderWin,
00478 __glutCurrentWindow->renderCtx);
00479 }
00480
00481 GLUTwindow *
00482 __glutCreateWindow(GLUTwindow * parent,
00483 int x, int y, int width, int height)
00484 {
00485 GLUTwindow *window;
00486 XSetWindowAttributes wa;
00487 unsigned long attribMask;
00488 int winnum;
00489 int i;
00490
00491 if (!__glutDisplay)
00492 __glutOpenXConnection(NULL);
00493 winnum = getUnusedWindowSlot();
00494 window = (GLUTwindow *) malloc(sizeof(GLUTwindow));
00495 if (!window)
00496 __glutFatalError("out of memory.");
00497 window->num = winnum;
00498
00499 window->vis = __glutDetermineVisual(__glutDisplayMode,
00500 &window->fakeSingle, __glutGetVisualInfo);
00501 if (!window->vis) {
00502 __glutFatalError(
00503 "visual with necessary capabilities not found.");
00504 }
00505 window->ctx = glXCreateContext(__glutDisplay, window->vis,
00506 None, __glutTryDirect);
00507 window->renderCtx = window->ctx;
00508 window->isDirect = glXIsDirect(__glutDisplay, window->ctx);
00509 if (__glutForceDirect) {
00510 if (!window->isDirect)
00511 __glutFatalError("direct rendering not possible.");
00512 }
00513 __glutSetupColormap(window->vis, &(window->colormap), &(window->cmap));
00514 window->eventMask = StructureNotifyMask | ExposureMask;
00515
00516 attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
00517 wa.background_pixmap = None;
00518 wa.border_pixel = 0;
00519 wa.colormap = window->cmap;
00520 wa.event_mask = window->eventMask;
00521 if (parent) {
00522 if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)
00523 wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK;
00524 attribMask |= CWDontPropagate;
00525 wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;
00526 } else {
00527 wa.do_not_propagate_mask = 0;
00528 }
00529 window->win = XCreateWindow(__glutDisplay,
00530 parent == NULL ? __glutRoot : parent->win,
00531 x, y, width, height, 0,
00532 window->vis->depth, InputOutput, window->vis->visual,
00533 attribMask, &wa);
00534 window->renderWin = window->win;
00535
00536 window->width = width;
00537 window->height = height;
00538 window->forceReshape = True;
00539
00540 window->parent = parent;
00541 if (parent) {
00542 window->siblings = parent->children;
00543 parent->children = window;
00544 } else {
00545 window->siblings = NULL;
00546 }
00547 window->overlay = NULL;
00548 window->children = NULL;
00549 window->display = __glutDefaultDisplay;
00550 window->reshape = __glutDefaultReshape;
00551 window->mouse = NULL;
00552 window->motion = NULL;
00553 window->visibility = NULL;
00554 window->passive = NULL;
00555 window->entry = NULL;
00556 window->special = NULL;
00557 window->buttonBox = NULL;
00558 window->dials = NULL;
00559 window->spaceMotion = NULL;
00560 window->spaceRotate = NULL;
00561 window->spaceButton = NULL;
00562 window->tabletMotion = NULL;
00563 window->tabletButton = NULL;
00564 window->tabletPos[0] = -1;
00565 window->tabletPos[1] = -1;
00566 window->keyboard = NULL;
00567 window->shownState = 0;
00568 window->visState = -1;
00569
00570
00571 window->entryState = -1;
00572 window->damaged = 0;
00573 window->workMask = GLUT_MAP_WORK;
00574 window->desiredMapState = NormalState;
00575 window->desiredConfMask = 0;
00576 window->buttonUses = 0;
00577 window->cursor = GLUT_CURSOR_INHERIT;
00578 window->prevWorkWin = __glutWindowWorkList;
00579 __glutWindowWorkList = window;
00580 for (i = 0; i < GLUT_MAX_MENUS; i++) {
00581 window->menu[i] = 0;
00582 }
00583 __glutWindowList[winnum] = window;
00584 __glutSetWindow(window);
00585 if (window->fakeSingle) {
00586 glDrawBuffer(GL_FRONT);
00587 glReadBuffer(GL_FRONT);
00588 }
00589 return window;
00590 }
00591
00592 static int
00593 findColormaps(GLUTwindow * window,
00594 Window * winlist, Colormap * cmaplist, int num, int max)
00595 {
00596 GLUTwindow *child;
00597 int i;
00598
00599
00600
00601 if (num >= max)
00602 return num;
00603
00604 for (i = 0; i < num; i++) {
00605 if (cmaplist[i] == window->cmap)
00606 goto normalColormapAlreadyListed;
00607 }
00608
00609 winlist[num] = window->win;
00610 cmaplist[num] = window->cmap;
00611 num++;
00612
00613 normalColormapAlreadyListed:
00614
00615
00616 if (window->overlay) {
00617 if (num >= max)
00618 return num;
00619 for (i = 0; i < num; i++) {
00620 if (cmaplist[i] == window->overlay->cmap)
00621 goto overlayColormapAlreadyListed;
00622 }
00623 winlist[num] = window->overlay->win;
00624 cmaplist[num] = window->overlay->cmap;
00625 num++;
00626 }
00627 overlayColormapAlreadyListed:
00628
00629
00630 child = window->children;
00631 while (child) {
00632 num = findColormaps(child, winlist, cmaplist, num, max);
00633 child = child->siblings;
00634 }
00635 return num;
00636 }
00637
00638 void
00639 __glutEstablishColormapsProperty(GLUTwindow * window)
00640 {
00641 static Atom wmColormapWindows = None;
00642 Window *winlist;
00643 Colormap *cmaplist;
00644 Status status;
00645 int maxcmaps, num;
00646
00647 assert(!window->parent);
00648 maxcmaps = MaxCmapsOfScreen(ScreenOfDisplay(__glutDisplay,
00649 __glutScreen));
00650
00651
00652 winlist = (Window *) malloc(maxcmaps * sizeof(Window));
00653 cmaplist = (Colormap *) malloc(maxcmaps * sizeof(Colormap));
00654 num = findColormaps(window, winlist, cmaplist, 0, maxcmaps);
00655 if (num < 2) {
00656
00657 wmColormapWindows = XInternAtom(__glutDisplay,
00658 "WM_COLORMAP_WINDOWS", False);
00659 if (wmColormapWindows == None) {
00660 __glutWarning("Could not intern X atom for WM_COLORMAP_WINDOWS.");
00661 return;
00662 }
00663 XDeleteProperty(__glutDisplay, window->win, wmColormapWindows);
00664 } else {
00665 status = XSetWMColormapWindows(__glutDisplay, window->win,
00666 winlist, num);
00667
00668
00669
00670 if (status == False)
00671 __glutFatalError("XSetWMColormapWindows returned False");
00672 }
00673
00674
00675 free(winlist);
00676 free(cmaplist);
00677 }
00678
00679 GLUTwindow *
00680 __glutToplevelOf(GLUTwindow * window)
00681 {
00682 while (window->parent) {
00683 window = window->parent;
00684 }
00685 return window;
00686 }
00687
00688 int
00689 glutCreateWindow(char *title)
00690 {
00691 static int firstWindow = 1;
00692 GLUTwindow *window;
00693 XWMHints *wmHints;
00694 Window win;
00695 XTextProperty textprop;
00696
00697 window = __glutCreateWindow(NULL,
00698 __glutSizeHints.x, __glutSizeHints.y,
00699 __glutInitWidth, __glutInitHeight);
00700 win = window->win;
00701
00702 textprop.value = (unsigned char *) title;
00703 textprop.encoding = XA_STRING;
00704 textprop.format = 8;
00705 textprop.nitems = strlen(title);
00706 wmHints = XAllocWMHints();
00707 wmHints->initial_state =
00708 __glutIconic ? IconicState : NormalState;
00709 wmHints->flags = StateHint;
00710 XSetWMProperties(__glutDisplay, win, &textprop, &textprop,
00711
00712 firstWindow ? __glutArgv : NULL,
00713 firstWindow ? __glutArgc : 0,
00714 &__glutSizeHints, wmHints, NULL);
00715 firstWindow = 0;
00716 XFree(wmHints);
00717 XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1);
00718 return window->num + 1;
00719 }
00720
00721 int
00722 glutCreateSubWindow(int win, int x, int y, int width, int height)
00723 {
00724 GLUTwindow *window, *toplevel;
00725
00726 window = __glutCreateWindow(__glutWindowList[win - 1],
00727 x, y, width, height);
00728 toplevel = __glutToplevelOf(window);
00729 if (toplevel->cmap != window->cmap) {
00730 __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
00731 }
00732 return window->num + 1;
00733 }
00734
00735 static void
00736 destroyWindow(GLUTwindow * window,
00737 GLUTwindow * initialWindow)
00738 {
00739 GLUTwindow **prev, *cur, *parent, *siblings;
00740
00741
00742 cur = window->children;
00743 while (cur) {
00744 siblings = cur->siblings;
00745 destroyWindow(cur, initialWindow);
00746 cur = siblings;
00747 }
00748
00749
00750 parent = window->parent;
00751 if (parent && parent == initialWindow->parent) {
00752 prev = &parent->children;
00753 cur = parent->children;
00754 while (cur) {
00755 if (cur == window) {
00756 *prev = cur->siblings;
00757 break;
00758 }
00759 prev = &(cur->siblings);
00760 cur = cur->siblings;
00761 }
00762 }
00763
00764 if (window == __glutCurrentWindow) {
00765 glXMakeCurrent(__glutDisplay, None, NULL);
00766 __glutCurrentWindow = NULL;
00767 }
00768
00769 if (window->overlay) {
00770 __glutFreeOverlayFunc(window->overlay);
00771 }
00772 XDestroyWindow(__glutDisplay, window->win);
00773 glXDestroyContext(__glutDisplay, window->ctx);
00774 if (window->colormap) {
00775
00776 __glutFreeColormap(window->colormap);
00777 }
00778
00779
00780 __glutWindowList[window->num] = NULL;
00781
00782
00783 cleanWindowWorkList(window);
00784 cleanStaleWindowList(window);
00785
00786 if (__glutWindowCache == window)
00787 __glutWindowCache = NULL;
00788
00789 XFree(window->vis);
00790 free(window);
00791 }
00792
00793 void
00794 glutDestroyWindow(int win)
00795 {
00796 GLUTwindow *window = __glutWindowList[win - 1];
00797
00798 if (__glutMappedMenu && __glutMenuWindow == window) {
00799 __glutFatalUsage("destroying menu window not allowed while menus in use");
00800 }
00801
00802 if (window->parent) {
00803
00804
00805
00806 __glutPutOnWorkList(__glutToplevelOf(window->parent),
00807 GLUT_COLORMAP_WORK);
00808 }
00809 destroyWindow(window, window);
00810 }
00811
00812 void
00813 glutSwapBuffers(void)
00814 {
00815 GLUTwindow *window = __glutCurrentWindow;
00816
00817 if (window->renderWin == window->win) {
00818 if (__glutCurrentWindow->fakeSingle) {
00819
00820
00821 return;
00822 }
00823 } else {
00824 if (__glutCurrentWindow->overlay->fakeSingle) {
00825
00826
00827 return;
00828 }
00829 }
00830 glXSwapBuffers(__glutDisplay, __glutCurrentWindow->renderWin);
00831 }
00832
00833 void
00834 __glutChangeWindowEventMask(long eventMask, Bool add)
00835 {
00836 if (add) {
00837
00838 if ((__glutCurrentWindow->eventMask & eventMask) !=
00839 eventMask) {
00840 __glutCurrentWindow->eventMask |= eventMask;
00841 __glutPutOnWorkList(__glutCurrentWindow,
00842 GLUT_EVENT_MASK_WORK);
00843 }
00844 } else {
00845
00846 if (__glutCurrentWindow->eventMask & eventMask) {
00847 __glutCurrentWindow->eventMask &= ~eventMask;
00848 __glutPutOnWorkList(__glutCurrentWindow,
00849 GLUT_EVENT_MASK_WORK);
00850 }
00851 }
00852 }
00853
00854 void
00855 glutDisplayFunc(GLUTdisplayCB displayFunc)
00856 {
00857
00858 if (!displayFunc)
00859 __glutFatalError("NULL display callback not allowed in GLUT 3.0; update your code.");
00860 __glutCurrentWindow->display = displayFunc;
00861 }
00862
00863 void
00864 glutKeyboardFunc(GLUTkeyboardCB keyboardFunc)
00865 {
00866 __glutChangeWindowEventMask(KeyPressMask,
00867 keyboardFunc != NULL || __glutCurrentWindow->special != NULL);
00868 __glutCurrentWindow->keyboard = keyboardFunc;
00869 }
00870
00871 void
00872 glutSpecialFunc(GLUTspecialCB specialFunc)
00873 {
00874 __glutChangeWindowEventMask(KeyPressMask,
00875 specialFunc != NULL || __glutCurrentWindow->keyboard != NULL);
00876 __glutCurrentWindow->special = specialFunc;
00877 }
00878
00879 void
00880 glutMouseFunc(GLUTmouseCB mouseFunc)
00881 {
00882 if (__glutCurrentWindow->mouse) {
00883 if (!mouseFunc) {
00884
00885 __glutCurrentWindow->buttonUses--;
00886 __glutChangeWindowEventMask(
00887 ButtonPressMask | ButtonReleaseMask,
00888 __glutCurrentWindow->buttonUses > 0);
00889 }
00890 } else {
00891 if (mouseFunc) {
00892
00893 __glutCurrentWindow->buttonUses++;
00894 __glutChangeWindowEventMask(
00895 ButtonPressMask | ButtonReleaseMask, True);
00896 }
00897 }
00898 __glutCurrentWindow->mouse = mouseFunc;
00899 }
00900
00901 void
00902 glutMotionFunc(GLUTmotionCB motionFunc)
00903 {
00904
00905
00906
00907
00908
00909 if (__glutCurrentWindow->motion) {
00910 if (!motionFunc) {
00911
00912 __glutCurrentWindow->buttonUses--;
00913 __glutChangeWindowEventMask(
00914 ButtonPressMask | ButtonReleaseMask,
00915 __glutCurrentWindow->buttonUses > 0);
00916 }
00917 } else {
00918 if (motionFunc) {
00919
00920 __glutCurrentWindow->buttonUses++;
00921 __glutChangeWindowEventMask(
00922 ButtonPressMask | ButtonReleaseMask, True);
00923 }
00924 }
00925
00926 __glutChangeWindowEventMask(
00927 Button1MotionMask | Button2MotionMask | Button3MotionMask,
00928 motionFunc != NULL);
00929 __glutCurrentWindow->motion = motionFunc;
00930 }
00931
00932 void
00933 glutPassiveMotionFunc(GLUTpassiveCB passiveMotionFunc)
00934 {
00935 __glutChangeWindowEventMask(PointerMotionMask,
00936 passiveMotionFunc != NULL);
00937
00938
00939
00940
00941 __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask,
00942 __glutCurrentWindow->entry != NULL || passiveMotionFunc != NULL);
00943
00944 __glutCurrentWindow->passive = passiveMotionFunc;
00945 }
00946
00947 void
00948 glutEntryFunc(GLUTentryCB entryFunc)
00949 {
00950 __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask,
00951 entryFunc != NULL || __glutCurrentWindow->passive);
00952 __glutCurrentWindow->entry = entryFunc;
00953 if (!entryFunc) {
00954 __glutCurrentWindow->entryState = -1;
00955 }
00956 }
00957
00958 void
00959 glutVisibilityFunc(GLUTvisibilityCB visibilityFunc)
00960 {
00961 __glutChangeWindowEventMask(VisibilityChangeMask,
00962 visibilityFunc != NULL);
00963 __glutCurrentWindow->visibility = visibilityFunc;
00964 if (!visibilityFunc) {
00965
00966 __glutCurrentWindow->visState = -1;
00967 }
00968 }
00969
00970 void
00971 glutReshapeFunc(GLUTreshapeCB reshapeFunc)
00972 {
00973 if (reshapeFunc) {
00974 __glutCurrentWindow->reshape = reshapeFunc;
00975 } else {
00976 __glutCurrentWindow->reshape = __glutDefaultReshape;
00977 }
00978 }