togl.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 2,204 行 · 第 1/5 页
C
2,204 行
#endif /* X11 */#ifdef WIN32 parentWin = Tk_GetHWND(parent); hInstance = Tk_GetHINSTANCE(); if (ToglClassInitialized == 0) { ToglClassInitialized = 1; ToglClass.style = CS_HREDRAW | CS_VREDRAW; ToglClass.cbClsExtra = 0; ToglClass.cbWndExtra = 4; /* to save struct Togl* */ ToglClass.hInstance = hInstance; ToglClass.hbrBackground = NULL; ToglClass.lpszMenuName = NULL; ToglClass.lpszClassName = TOGL_CLASS_NAME; ToglClass.lpfnWndProc = Win32WinProc; ToglClass.hIcon = NULL; ToglClass.hCursor = NULL; if (!RegisterClass(&ToglClass)){ Tcl_SetResult(togl->Interp, "unable register Togl window class",TCL_STATIC); return DUMMY_WINDOW; } } hwnd = CreateWindow(TOGL_CLASS_NAME, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, togl->Width, togl->Height, parentWin, NULL, hInstance, NULL); SetWindowLong(hwnd, 0, (LONG) togl); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); togl->tglGLHdc = GetDC(hwnd); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; if (togl->DoubleFlag) { pfd.dwFlags |= PFD_DOUBLEBUFFER; } /* The stereo flag is not supported in the current generic OpenGL * implementation, but may be supported by specific hardware devices. */ if (togl->StereoFlag) { pfd.dwFlags |= PFD_STEREO; } pfd.cColorBits = togl->RgbaRed + togl->RgbaGreen + togl->RgbaBlue; pfd.iPixelType = togl->RgbaFlag ? PFD_TYPE_RGBA : PFD_TYPE_COLORINDEX; /* Alpha bitplanes are not supported in the current generic OpenGL * implementation, but may be supported by specific hardware devices. */ pfd.cAlphaBits = togl->AlphaFlag ? togl->AlphaSize : 0; pfd.cAccumBits = togl->AccumFlag ? (togl->AccumRed + togl->AccumGreen + togl->AccumBlue +togl->AccumAlpha) : 0; pfd.cDepthBits = togl->DepthFlag ? togl->DepthSize : 0; pfd.cStencilBits = togl->StencilFlag ? togl->StencilSize : 0; /* Auxiliary buffers are not supported in the current generic OpenGL * implementation, but may be supported by specific hardware devices. */ pfd.cAuxBuffers = togl->AuxNumber; pfd.iLayerType = PFD_MAIN_PLANE; if ( (pixelformat = ChoosePixelFormat(togl->tglGLHdc, &pfd)) == 0 ) { Tcl_SetResult(togl->Interp, "Togl: couldn't choose pixel format",TCL_STATIC); return DUMMY_WINDOW; } if (SetPixelFormat(togl->tglGLHdc, pixelformat, &pfd) == FALSE) { Tcl_SetResult(togl->Interp, "Togl: couldn't choose pixel format",TCL_STATIC); return DUMMY_WINDOW; } /* Get the actual pixel format */ DescribePixelFormat(togl->tglGLHdc, pixelformat, sizeof(pfd), &pfd); if (togl->ShareContext && FindTogl(togl->ShareContext)) { /* share OpenGL context with existing Togl widget */ struct Togl *shareWith = FindTogl(togl->ShareContext); assert(shareWith); assert(shareWith->tglGLHglrc); togl->tglGLHglrc = shareWith->tglGLHglrc; togl->VisInfo = shareWith->VisInfo; visinfo = togl->VisInfo; } else { /* * Create a new OpenGL rendering context. And check to share lists. */ togl->tglGLHglrc = wglCreateContext(togl->tglGLHdc); if (togl->ShareList) { /* share display lists with existing togl widget */ struct Togl *shareWith = FindTogl(togl->ShareList); if (shareWith) wglShareLists(shareWith->tglGLHglrc, togl->tglGLHglrc); } if (!togl->tglGLHglrc) { Tcl_SetResult(togl->Interp, "could not create rendering context",TCL_STATIC); return DUMMY_WINDOW; } /* Just for portability, define the simplest visinfo */ visinfo = &VisInf; visinfo->visual = DefaultVisual(dpy, DefaultScreen(dpy)); visinfo->depth = visinfo->visual->bits_per_rgb; }#endif /*WIN32 */ /* * find a colormap */ scrnum = Tk_ScreenNumber(togl->TkWin); if (togl->RgbaFlag) { /* Colormap for RGB mode */#if defined(X11) cmap = get_rgb_colormap( dpy, scrnum, visinfo, togl->TkWin );#elif defined(WIN32) if (pfd.dwFlags & PFD_NEED_PALETTE) { cmap = Win32CreateRgbColormap(pfd); } else { cmap = DefaultColormap(dpy,scrnum); } /* for EPS Output */ if ( togl->EpsRedMap) free( ( char *)togl->EpsRedMap); if ( togl->EpsGreenMap) free( ( char *)togl->EpsGreenMap); if ( togl->EpsBlueMap) free( ( char *)togl->EpsBlueMap); togl->EpsRedMap = togl->EpsGreenMap = togl->EpsBlueMap = NULL; togl->EpsMapSize = 0;#elif defined(macintosh) cmap = DefaultColormap(dpy, scrnum); /* for EPS Output */ if (togl->EpsRedMap) free((char *) togl->EpsRedMap); if (togl->EpsGreenMap) free((char *) togl->EpsGreenMap); if (togl->EpsBlueMap) free((char *) togl->EpsBlueMap); togl->EpsRedMap = togl->EpsGreenMap = togl->EpsBlueMap = NULL; togl->EpsMapSize = 0;#endif /* X11 */ } else { /* Colormap for CI mode */#ifdef WIN32 togl->CiColormapSize = 1 << pfd.cColorBits; togl->CiColormapSize = togl->CiColormapSize < MAX_CI_COLORMAP_SIZE ? togl->CiColormapSize : MAX_CI_COLORMAP_SIZE;#endif /* WIN32 */ if (togl->PrivateCmapFlag) { /* need read/write colormap so user can store own color entries */#if defined(X11) cmap = XCreateColormap(dpy, XRootWindow(dpy, visinfo->screen), visinfo->visual, AllocAll);#elif defined(WIN32) cmap = Win32CreateCiColormap(togl);#elif defined(macintosh) /* need to figure out how to do this correctly on Mac... */ cmap = DefaultColormap(dpy, scrnum);#endif /* X11 */ } else { if (visinfo->visual==DefaultVisual(dpy, scrnum)) { /* share default/root colormap */ cmap = Tk_Colormap(togl->TkWin); } else { /* make a new read-only colormap */ cmap = XCreateColormap(dpy, XRootWindow(dpy, visinfo->screen), visinfo->visual, AllocNone); } } } /* Make sure Tk knows to switch to the new colormap when the cursor * is over this window when running in color index mode. */ Tk_SetWindowVisual(togl->TkWin, visinfo->visual, visinfo->depth, cmap);#ifdef WIN32 /* Install the colormap */ SelectPalette(togl->tglGLHdc, ((TkWinColormap *)cmap)->palette, TRUE); RealizePalette(togl->tglGLHdc);#endif /* WIN32 */#if defined(X11) swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = ALL_EVENTS_MASK; window = XCreateWindow(dpy, parent, 0, 0, togl->Width, togl->Height, 0, visinfo->depth, InputOutput, visinfo->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); /* Make sure window manager installs our colormap */ XSetWMColormapWindows( dpy,window, &window, 1 );#elif defined(WIN32) window = Tk_AttachHWND((Tk_Window)winPtr, hwnd);#elif defined(macintosh) window = TkpMakeWindow(winPtr, parent);#endif /* X11 */#ifdef USE_OVERLAY if (togl->OverlayFlag) { if (SetupOverlay( togl )==TCL_ERROR) { fprintf(stderr,"Warning: couldn't setup overlay.\n"); togl->OverlayFlag = 0; } }#endif /* USE_OVERLAY */ /* Request the X window to be displayed */ XMapWindow(dpy, window);#ifdef macintosh if (togl->ShareContext && FindTogl(togl->ShareContext)) { /* share OpenGL context with existing Togl widget */ struct Togl *shareWith = FindTogl(togl->ShareContext); assert(shareWith); assert(shareWith->aglCtx); togl->aglCtx = shareWith->aglCtx; togl->VisInfo = shareWith->VisInfo; visinfo = togl->VisInfo; } else { AGLContext shareCtx = NULL; /* Need to do this after mapping window, so MacDrawable structure is more completely filled in */ na = 0; attribs[na++] = AGL_MINIMUM_POLICY; attribs[na++] = AGL_ROBUST; if (togl->RgbaFlag) { /* RGB[A] mode */ attribs[na++] = AGL_RGBA; attribs[na++] = AGL_RED_SIZE; attribs[na++] = togl->RgbaRed; attribs[na++] = AGL_GREEN_SIZE; attribs[na++] = togl->RgbaGreen; attribs[na++] = AGL_BLUE_SIZE; attribs[na++] = togl->RgbaBlue; if (togl->AlphaFlag) { attribs[na++] = AGL_ALPHA_SIZE; attribs[na++] = togl->AlphaSize; } } else { /* Color index mode */ attribs[na++] = AGL_BUFFER_SIZE; attribs[na++] = 8; } if (togl->DepthFlag) { attribs[na++] = AGL_DEPTH_SIZE; attribs[na++] = togl->DepthSize; } if (togl->DoubleFlag) { attribs[na++] = AGL_DOUBLEBUFFER; } if (togl->StencilFlag) { attribs[na++] = AGL_STENCIL_SIZE; attribs[na++] = togl->StencilSize; } if (togl->AccumFlag) { attribs[na++] = AGL_ACCUM_RED_SIZE; attribs[na++] = togl->AccumRed; attribs[na++] = AGL_ACCUM_GREEN_SIZE; attribs[na++] = togl->AccumGreen; attribs[na++] = AGL_ACCUM_BLUE_SIZE; attribs[na++] = togl->AccumBlue; if (togl->AlphaFlag) { attribs[na++] = AGL_ACCUM_ALPHA_SIZE; attribs[na++] = togl->AccumAlpha; } } if (togl->AuxNumber != 0) { attribs[na++] = AGL_AUX_BUFFERS; attribs[na++] = togl->AuxNumber; } attribs[na++] = AGL_NONE; if ((fmt = aglChoosePixelFormat(NULL, 0, attribs)) == NULL) { Tcl_SetResult(togl->Interp, "Togl: couldn't choose pixel format",TCL_STATIC); return DUMMY_WINDOW; } /* * Check whether to share lists. */ if (togl->ShareList) { /* share display lists with existing togl widget */ struct Togl *shareWith = FindTogl(togl->ShareList); if (shareWith) shareCtx = shareWith->aglCtx; } if ((togl->aglCtx = aglCreateContext(fmt, shareCtx)) == NULL) { aglDestroyPixelFormat(fmt); Tcl_SetResult(togl->Interp, "Togl: couldn't create context",TCL_STATIC); return DUMMY_WINDOW; } aglDestroyPixelFormat(fmt); if (!aglSetDrawable(togl->aglCtx, ((MacDrawable *) (window))->toplevel->portPtr)) { aglDestroyContext(togl->aglCtx); Tcl_SetResult(togl->Interp, "Togl: couldn't set drawable",TCL_STATIC); return DUMMY_WINDOW; } /* Just for portability, define the simplest visinfo */ visinfo = &VisInf; visinfo->visual = DefaultVisual(dpy, DefaultScreen(dpy)); visinfo->depth = visinfo->visual->bits_per_rgb; }#endif /* macintosh */#if defined(X11) /* Check for a single/double buffering snafu */ { int dbl_flag; if (glXGetConfig( dpy, visinfo, GLX_DOUBLEBUFFER, &dbl_flag )) { if (togl->DoubleFlag==0 && dbl_flag) { /* We requested single buffering but had to accept a */ /* double buffered visual. Set the GL draw buffer to */ /* be the front buffer to simulate single buffering. */ glDrawBuffer( GL_FRONT ); } } }#endif /* X11 */ /* for EPS Output */ if ( !togl->RgbaFlag) { int index_size;#if defined(X11) || defined(macintosh) GLint index_bits; glGetIntegerv( GL_INDEX_BITS, &index_bits ); index_size = 1 << index_bits;#elif defined(WIN32) index_size = togl->CiColormapSize;#endif /* X11 */ if ( togl->EpsMapSize != index_size) { if ( togl->EpsRedMap) free( ( char *)togl->EpsRedMap); if ( togl->EpsGreenMap) free( ( char *)togl->EpsGreenMap); if ( togl->EpsBlueMap) free( ( char *)togl->EpsBlueMap); togl->EpsMapSize = index_size; togl->EpsRedMap = ( GLfloat *)calloc( index_size, sizeof( GLfloat)); togl->EpsGreenMap = ( GLfloat *)calloc( index_size, sizeof( GLfloat)); togl->EpsBlueMap = ( GLfloat *)calloc( index_size, sizeof( GLfloat)); } } return window;}/* * ToglCmdDeletedProc * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *---------------------------------------------------------------------- */static void ToglCmdDeletedProc( ClientData clientData ){ struct Togl *togl = (struct Togl *)clientData; Tk_Window tkwin = togl->TkWin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ /* NEW in togl 1.5 beta 3 */ if (togl && tkwin) { Tk_DeleteEventHandler(tkwin, ExposureMask | StructureNotifyMask, Togl_EventProc, (ClientData)togl); } /* NEW in togl 1.5 beta 3 */#if defined(X11) if (togl->GlCtx) { /* XXX this might be bad if two or more Togl widgets share a context */ glXDestroyContext( togl->display, togl->GlCtx ); togl->GlCtx = NULL; }#ifdef USE_OVERLAY if (togl->OverlayCtx) { Tcl_HashEntry *entryPtr; TkWindow *winPtr = (TkWindow *) togl->TkWin; if (winPtr) { entryPtr = Tcl_FindHashEntry(&winPtr->dispPtr->winTable, (char *) togl->OverlayWindow ); Tcl_DeleteHashEntry(entryPtr); } glXDestroyContext( togl->display, togl->OverlayCtx ); togl->OverlayCtx = NULL; }#endif /* USE_OVERLAY */#endif if (tkwin != NULL) { togl->TkWin = NULL; Tk_DestroyWindow(tkwin); }}/* * Togl_Destroy * * Gets called when an Togl widget is destroyed. */#if (TK_MAJOR_VERSION * 100 + TK_MINOR_VERSION) >= 401static void Togl_Destroy( char *clientData )#elsestatic void Togl_Destroy( ClientData clientData )#endif{ struct Togl *togl = (struct Togl *)clientData; Tk_FreeOptions(configSpecs, (char *)togl, togl->display, 0);#ifndef NO_TK_CURSOR if (togl-
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?