📄 glut_win.c
字号:
attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; wa.background_pixmap = None; wa.border_pixel = 0; wa.colormap = window->cmap; wa.event_mask = window->eventMask; if (parent) { if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK; attribMask |= CWDontPropagate; wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK; } else { wa.do_not_propagate_mask = 0; } /* Stash width and height before Win32's __glutAdjustCoords possibly overwrites the values. */ window->width = width; window->height = height; window->forceReshape = True; window->ignoreKeyRepeat = False;#if defined(_WIN32) __glutAdjustCoords(parent ? parent->win : NULL, &x, &y, &width, &height); if (parent) { style = WS_CHILD; } else { if (gameMode) { /* Game mode window should be a WS_POPUP window to ensure that the taskbar is hidden by it. A standard WS_OVERLAPPEDWINDOW does not hide the task bar. */ style = WS_POPUP | WS_MAXIMIZE; } else { /* A standard toplevel window with borders and such. */ style = WS_OVERLAPPEDWINDOW; } } window->win = CreateWindow("GLUT", "GLUT", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, x, y, width, height, parent ? parent->win : __glutRoot, NULL, GetModuleHandle(NULL), 0); window->hdc = GetDC(window->win); /* Must set the XHDC for fake glXChooseVisual & fake glXCreateContext & fake XAllocColorCells. */ XHDC = window->hdc; window->vis = __glutDetermineWindowVisual(&window->treatAsSingle, &window->visAlloced, &fbc); if (!window->vis) { __glutFatalError( "pixel format with necessary capabilities not found."); } if (!SetPixelFormat(window->hdc, ChoosePixelFormat(window->hdc, window->vis), window->vis)) { __glutFatalError("SetPixelFormat failed during window create."); } __glutSetupColormap(window->vis, &window->colormap, &window->cmap); /* Make sure subwindows get a windowStatus callback. */ if (parent) { PostMessage(parent->win, WM_ACTIVATE, 0, 0); } window->renderDc = window->hdc;#else window->win = XCreateWindow(__glutDisplay, parent == NULL ? __glutRoot : parent->win, x, y, width, height, 0, window->vis->depth, InputOutput, window->vis->visual, attribMask, &wa);#endif window->renderWin = window->win;#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) if (fbc) { window->ctx = __glut_glXCreateContextWithConfigSGIX(__glutDisplay, fbc, GLX_RGBA_TYPE_SGIX, None, __glutTryDirect); } else#endif { window->ctx = glXCreateContext(__glutDisplay, window->vis, None, __glutTryDirect); } if (!window->ctx) { __glutFatalError( "failed to create OpenGL rendering context."); } window->renderCtx = window->ctx;#if !defined(_WIN32) window->isDirect = glXIsDirect(__glutDisplay, window->ctx); if (__glutForceDirect) { if (!window->isDirect) __glutFatalError("direct rendering not possible."); }#endif window->parent = parent; if (parent) { window->siblings = parent->children; parent->children = window; } else { window->siblings = NULL; } window->overlay = NULL; window->children = NULL; window->display = __glutDefaultDisplay; window->reshape = __glutDefaultReshape; window->mouse = NULL; window->motion = NULL; window->passive = NULL; window->entry = NULL; window->keyboard = NULL; window->keyboardUp = NULL; window->windowStatus = NULL; window->visibility = NULL; window->special = NULL; window->specialUp = NULL; window->buttonBox = NULL; window->dials = NULL; window->spaceMotion = NULL; window->spaceRotate = NULL; window->spaceButton = NULL; window->tabletMotion = NULL; window->tabletButton = NULL;#ifdef _WIN32 window->joystick = NULL; window->joyPollInterval = 0;#endif window->tabletPos[0] = -1; window->tabletPos[1] = -1; window->shownState = 0; window->visState = -1; /* not VisibilityUnobscured, VisibilityPartiallyObscured, or VisibilityFullyObscured */ window->entryState = -1; /* not EnterNotify or LeaveNotify */ window->desiredConfMask = 0; window->buttonUses = 0; window->cursor = GLUT_CURSOR_INHERIT; /* Setup window to be mapped when glutMainLoop starts. */ window->workMask = GLUT_MAP_WORK;#ifdef _WIN32 if (gameMode) { /* When mapping a game mode window, just show the window. We have already created the game mode window with a maximize flag at creation time. Doing a ShowWindow(window->win, SW_SHOWNORMAL) would be wrong for a game mode window since it would unmaximize the window. */ window->desiredMapState = GameModeState; } else { window->desiredMapState = NormalState; }#else window->desiredMapState = NormalState;#endif window->prevWorkWin = __glutWindowWorkList; __glutWindowWorkList = window; /* Initially, no menus attached. */ for (i = 0; i < GLUT_MAX_MENUS; i++) { window->menu[i] = 0; } /* Add this new window to the window list. */ __glutWindowList[winnum] = window; /* Make the new window the current window. */ __glutSetWindow(window); __glutDetermineMesaSwapHackSupport(); if (window->treatAsSingle) { /* We do this because either the window really is single buffered (in which case this is redundant, but harmless, because this is the initial single-buffered context state); or we are treating a double buffered window as a single-buffered window because the system does not appear to export any suitable single- buffered visuals (in which the following are necessary). */ glDrawBuffer(GL_FRONT); glReadBuffer(GL_FRONT); } return window;}/* CENTRY */int GLUTAPIENTRYglutCreateWindow(const char *title){ static int firstWindow = 1; GLUTwindow *window;#if !defined(_WIN32) XWMHints *wmHints;#endif Window win; XTextProperty textprop; if (__glutGameModeWindow) { __glutFatalError("cannot create windows in game mode."); } window = __glutCreateWindow(NULL, __glutSizeHints.x, __glutSizeHints.y, __glutInitWidth, __glutInitHeight, /* not game mode */ 0); win = window->win; /* Setup ICCCM properties. */ textprop.value = (unsigned char *) title; textprop.encoding = XA_STRING; textprop.format = 8; textprop.nitems = strlen(title);#if defined(_WIN32) SetWindowText(win, title); if (__glutIconic) { window->desiredMapState = IconicState; }#else wmHints = XAllocWMHints(); wmHints->initial_state = __glutIconic ? IconicState : NormalState; wmHints->flags = StateHint; XSetWMProperties(__glutDisplay, win, &textprop, &textprop, /* Only put WM_COMMAND property on first window. */ firstWindow ? __glutArgv : NULL, firstWindow ? __glutArgc : 0, &__glutSizeHints, wmHints, NULL); XFree(wmHints); XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1);#endif firstWindow = 0; return window->num + 1;}#ifdef _WIN32int GLUTAPIENTRY__glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)){ __glutExitFunc = exitfunc; return glutCreateWindow(title);}#endifint GLUTAPIENTRYglutCreateSubWindow(int win, int x, int y, int width, int height){ GLUTwindow *window; window = __glutCreateWindow(__glutWindowList[win - 1], x, y, width, height, /* not game mode */ 0);#if !defined(_WIN32) { GLUTwindow *toplevel; toplevel = __glutToplevelOf(window); if (toplevel->cmap != window->cmap) { __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK); } }#endif return window->num + 1;}/* ENDCENTRY */void__glutDestroyWindow(GLUTwindow * window, GLUTwindow * initialWindow){ GLUTwindow **prev, *cur, *parent, *siblings; /* Recursively destroy any children. */ cur = window->children; while (cur) { siblings = cur->siblings; __glutDestroyWindow(cur, initialWindow); cur = siblings; } /* Remove from parent's children list (only necessary for non-initial windows and subwindows!). */ parent = window->parent; if (parent && parent == initialWindow->parent) { prev = &parent->children; cur = parent->children; while (cur) { if (cur == window) { *prev = cur->siblings; break; } prev = &(cur->siblings); cur = cur->siblings; } } /* Unbind if bound to this window. */ if (window == __glutCurrentWindow) { UNMAKE_CURRENT(); __glutCurrentWindow = NULL; } /* Begin tearing down window itself. */ if (window->overlay) { __glutFreeOverlayFunc(window->overlay); } XDestroyWindow(__glutDisplay, window->win); glXDestroyContext(__glutDisplay, window->ctx); if (window->colormap) { /* Only color index windows have colormap data structure. */ __glutFreeColormap(window->colormap); } /* NULLing the __glutWindowList helps detect is a window instance has been destroyed, given a window number. */ __glutWindowList[window->num] = NULL; /* Cleanup data structures that might contain window. */ cleanWindowWorkList(window);#if !defined(_WIN32) cleanStaleWindowList(window);#endif /* Remove window from the "get window cache" if it is there. */ if (__glutWindowCache == window) __glutWindowCache = NULL; if (window->visAlloced) { /* Only free XVisualInfo* gotten from glXChooseVisual. */ XFree(window->vis); } if (window == __glutGameModeWindow) { /* Destroying the game mode window should implicitly have GLUT leave game mode. */ __glutCloseDownGameMode(); } free(window);}/* CENTRY */void GLUTAPIENTRYglutDestroyWindow(int win){ GLUTwindow *window = __glutWindowList[win - 1]; if (__glutMappedMenu && __glutMenuWindow == window) { __glutFatalUsage("destroying menu window not allowed while menus in use"); }#if !defined(_WIN32) /* If not a toplevel window... */ if (window->parent) { /* Destroying subwindows may change colormap requirements; recalculate toplevel window's WM_COLORMAP_WINDOWS property. */ __glutPutOnWorkList(__glutToplevelOf(window->parent), GLUT_COLORMAP_WORK); }#endif __glutDestroyWindow(window, window); XFlush(__glutDisplay);}/* ENDCENTRY */void__glutChangeWindowEventMask(long eventMask, Bool add){ if (add) { /* Add eventMask to window's event mask. */ if ((__glutCurrentWindow->eventMask & eventMask) != eventMask) { __glutCurrentWindow->eventMask |= eventMask; __glutPutOnWorkList(__glutCurrentWindow, GLUT_EVENT_MASK_WORK); } } else { /* Remove eventMask from window's event mask. */ if (__glutCurrentWindow->eventMask & eventMask) { __glutCurrentWindow->eventMask &= ~eventMask; __glutPutOnWorkList(__glutCurrentWindow, GLUT_EVENT_MASK_WORK); } }}void GLUTAPIENTRYglutDisplayFunc(GLUTdisplayCB displayFunc){ /* XXX Remove the warning after GLUT 3.0. */ if (!displayFunc) __glutFatalError("NULL display callback not allowed in GLUT 3.0; update your code."); __glutCurrentWindow->display = displayFunc;}void GLUTAPIENTRYglutMouseFunc(GLUTmouseCB mouseFunc){ if (__glutCurrentWindow->mouse) { if (!mouseFunc) { /* Previous mouseFunc being disabled. */ __glutCurrentWindow->buttonUses--; __glutChangeWindowEventMask( ButtonPressMask | ButtonReleaseMask, __glutCurrentWindow->buttonUses > 0); } } else { if (mouseFunc) { /* Previously no mouseFunc, new one being installed. */ __glutCurrentWindow->buttonUses++; __glutChangeWindowEventMask( ButtonPressMask | ButtonReleaseMask, True); } } __glutCurrentWindow->mouse = mouseFunc;}void GLUTAPIENTRYglutMotionFunc(GLUTmotionCB motionFunc){ /* Hack. Some window managers (4Dwm by default) will mask motion events if the client is not selecting for button press and release events. So we select for press and release events too (being careful to use reference counting). */ if (__glutCurrentWindow->motion) { if (!motionFunc) { /* previous mouseFunc being disabled */ __glutCurrentWindow->buttonUses--; __glutChangeWindowEventMask( ButtonPressMask | ButtonReleaseMask, __glutCurrentWindow->buttonUses > 0); } } else { if (motionFunc) { /* Previously no mouseFunc, new one being installed. */ __glutCurrentWindow->buttonUses++; __glutChangeWindowEventMask( ButtonPressMask | ButtonReleaseMask, True); } } /* Real work of selecting for passive mouse motion. */ __glutChangeWindowEventMask( Button1MotionMask | Button2MotionMask | Button3MotionMask, motionFunc != NULL); __glutCurrentWindow->motion = motionFunc;}void GLUTAPIENTRYglutPassiveMotionFunc(GLUTpassiveCB passiveMotionFunc){ __glutChangeWindowEventMask(PointerMotionMask, passiveMotionFunc != NULL); /* Passive motion also requires watching enters and leaves so that a fake passive motion event can be generated on an enter. */ __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask, __glutCurrentWindow->entry != NULL || passiveMotionFunc != NULL); __glutCurrentWindow->passive = passiveMotionFunc;}void GLUTAPIENTRYglutEntryFunc(GLUTentryCB entryFunc){ __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask, entryFunc != NULL || __glutCurrentWindow->passive); __glutCurrentWindow->entry = entryFunc; if (!entryFunc) { __glutCurrentWindow->entryState = -1; }}void GLUTAPIENTRYglutWindowStatusFunc(GLUTwindowStatusCB windowStatusFunc){ __glutChangeWindowEventMask(VisibilityChangeMask, windowStatusFunc != NULL); __glutCurrentWindow->windowStatus = windowStatusFunc; if (!windowStatusFunc) { /* Make state invalid. */ __glutCurrentWindow->visState = -1; }}static void GLUTCALLBACKvisibilityHelper(int status){ if (status == GLUT_HIDDEN || status == GLUT_FULLY_COVERED) __glutCurrentWindow->visibility(GLUT_NOT_VISIBLE); else __glutCurrentWindow->visibility(GLUT_VISIBLE);}void GLUTAPIENTRYglutVisibilityFunc(GLUTvisibilityCB visibilityFunc){ __glutCurrentWindow->visibility = visibilityFunc; if (visibilityFunc) glutWindowStatusFunc(visibilityHelper); else glutWindowStatusFunc(NULL);}void GLUTAPIENTRYglutReshapeFunc(GLUTreshapeCB reshapeFunc){ if (reshapeFunc) { __glutCurrentWindow->reshape = reshapeFunc; } else { __glutCurrentWindow->reshape = __glutDefaultReshape; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -