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