togl.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 2,204 行 · 第 1/5 页
C
2,204 行
/* for EPS Output */ togl->EpsRedMap = togl->EpsGreenMap = togl->EpsBlueMap = NULL; togl->EpsMapSize = 0; /* Create command event handler */ togl->widgetCmd = Tcl_CreateCommand(interp, Tk_PathName(tkwin), (Tcl_CmdProc *) Togl_Widget, (ClientData) togl, (Tcl_CmdDeleteProc*) ToglCmdDeletedProc); /* Setup the Tk_ClassProcs callbacks to point at our own window creation function We need to check at runtime if we should use the new Tk_SetClassProcs() API or if we need to modify the window structure directly */#ifdef HAVE_TK_SETCLASSPROCS { /* use public API (Tk 8.4+) */ Tk_ClassProcs *procsPtr; procsPtr = (Tk_ClassProcs*) Tcl_Alloc(sizeof(Tk_ClassProcs)); procsPtr->size = sizeof(Tk_ClassProcs); procsPtr->createProc = Togl_CreateWindow; procsPtr->worldChangedProc = NULL; procsPtr->modalProc = NULL; Tk_SetClassProcs(togl->TkWin,procsPtr,(ClientData)togl); }#else { /* use private API */ /* We need to set these fields in the Tk_FakeWin structure: dummy17 = classProcsPtr dummy18 = instanceData */ TkClassProcs *procsPtr; Tk_FakeWin *winPtr = (Tk_FakeWin*)(togl->TkWin); procsPtr = (TkClassProcs*)Tcl_Alloc(sizeof(TkClassProcs)); procsPtr->createProc = Togl_CreateWindow; procsPtr->geometryProc = NULL; procsPtr->modalProc = NULL; winPtr->dummy17 = (char*)procsPtr; winPtr->dummy18 = (ClientData)togl; }#endif Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, Togl_EventProc, (ClientData)togl); /* Configure Togl widget */ if (Togl_Configure(interp, togl, argc-2, argv+2, 0) == TCL_ERROR) { Tk_DestroyWindow(tkwin); goto error; } /* * If OpenGL window wasn't already created by Togl_Configure() we * create it now. We can tell by checking if the GLX context has * been initialized. */ if (!#if defined(WIN32) togl->tglGLHdc#elif defined(X11) togl->GlCtx#elif defined(macintosh) togl->aglCtx#endif ) { Tk_MakeWindowExist(togl->TkWin); if (Tk_WindowId(togl->TkWin)==DUMMY_WINDOW) { return TCL_ERROR; } Togl_MakeCurrent(togl); } /* If defined, call create callback */ if (togl->CreateProc) { togl->CreateProc(togl); } /* If defined, call reshape proc */ if (togl->ReshapeProc) { togl->ReshapeProc(togl); } /* If defined, setup timer */ if (togl->TimerProc){ Tk_CreateTimerHandler( togl->TimerInterval, Togl_Timer, (ClientData)togl ); } Tcl_AppendResult(interp, Tk_PathName(tkwin), NULL); /* Add to linked list */ AddToList(togl); return TCL_OK;error: Tcl_DeleteCommand(interp, "togl"); /*free(togl); Don't free it, if we do a crash occurs later...*/ return TCL_ERROR;}#ifdef USE_OVERLAY/* * Do all the setup for overlay planes * Return: TCL_OK or TCL_ERROR */static int SetupOverlay( struct Togl *togl ){#if defined(X11)#ifdef GLX_TRANSPARENT_TYPE_EXT static int ovAttributeList[] = { GLX_BUFFER_SIZE, 2, GLX_LEVEL, 1, GLX_TRANSPARENT_TYPE_EXT, GLX_TRANSPARENT_INDEX_EXT, None };#else static int ovAttributeList[] = { GLX_BUFFER_SIZE, 2, GLX_LEVEL, 1, None };#endif Display *dpy; XVisualInfo *visinfo; TkWindow *winPtr = (TkWindow *) togl->TkWin; XSetWindowAttributes swa; Tcl_HashEntry *hPtr; int new_flag; dpy = Tk_Display(togl->TkWin); visinfo = glXChooseVisual( dpy, Tk_ScreenNumber(winPtr), ovAttributeList ); if (!visinfo){ Tcl_AppendResult(togl->Interp,Tk_PathName(winPtr), ": No suitable overlay index visual available", (char *) NULL); togl->OverlayCtx = 0; togl->OverlayWindow = 0; togl->OverlayCmap = 0; return TCL_ERROR; }#ifdef GLX_TRANSPARENT_INDEX_EXT { int fail = glXGetConfig(dpy, visinfo,GLX_TRANSPARENT_INDEX_VALUE_EXT, &togl->OverlayTransparentPixel); if (fail) togl->OverlayTransparentPixel=0; /* maybe, maybe ... */ }#else togl->OverlayTransparentPixel=0; /* maybe, maybe ... */#endif /* togl->OverlayCtx = glXCreateContext( dpy, visinfo, None, GL_TRUE ); */ /* NEW in Togl 1.5 beta 3 */ /* share display lists with normal layer context */ togl->OverlayCtx = glXCreateContext( dpy, visinfo, togl->GlCtx, !togl->Indirect ); swa.colormap = XCreateColormap( dpy, XRootWindow(dpy, visinfo->screen), visinfo->visual, AllocNone ); togl->OverlayCmap = swa.colormap; swa.border_pixel = 0; swa.event_mask = ALL_EVENTS_MASK; togl->OverlayWindow = XCreateWindow( dpy, Tk_WindowId(togl->TkWin), 0, 0, togl->Width, togl->Height, 0, visinfo->depth, InputOutput, visinfo->visual, CWBorderPixel|CWColormap|CWEventMask, &swa ); hPtr = Tcl_CreateHashEntry( &winPtr->dispPtr->winTable, (char *) togl->OverlayWindow, &new_flag ); Tcl_SetHashValue( hPtr, winPtr );/* XMapWindow( dpy, togl->OverlayWindow );*/ togl->OverlayIsMapped = 0; /* Make sure window manager installs our colormap */ XSetWMColormapWindows( dpy, togl->OverlayWindow, &togl->OverlayWindow, 1 ); return TCL_OK;#elif defined(WIN32) || defined(macintosh) /* not yet implemented on these */ return TCL_ERROR;#endif /* X11 */}#endif /* USE_OVERLAY */#ifdef WIN32#define TOGL_CLASS_NAME "Togl Class"static ToglClassInitialized = 0;static LRESULT CALLBACK Win32WinProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ LONG result; struct Togl *togl = (struct Togl*) GetWindowLong(hwnd, 0); WNDCLASS childClass; switch( message ){ case WM_WINDOWPOSCHANGED: /* Should be processed by DefWindowProc, otherwise a double buffered context is not properly resized when the corresponding window is resized.*/ break; case WM_DESTROY: if (togl->tglGLHglrc) { wglDeleteContext(togl->tglGLHglrc); } if (togl->tglGLHdc) { ReleaseDC(hwnd, togl->tglGLHdc); } free(togl); break; default:#if USE_STATIC_LIB return TkWinChildProc(hwnd, message, wParam, lParam);#else /* * OK, since TkWinChildProc is not explicitly exported in the * dynamic libraries, we have to retrieve it from the class info * registered with windows. * */ if (tkWinChildProc == NULL) { GetClassInfo(Tk_GetHINSTANCE(),TK_WIN_CHILD_CLASS_NAME, &childClass); tkWinChildProc = childClass.lpfnWndProc; } return tkWinChildProc(hwnd, message, wParam, lParam);#endif } result = DefWindowProc(hwnd, message, wParam, lParam); Tcl_ServiceAll(); return result;}#endif /* WIN32 *//* * Togl_CreateWindow * * Window creation function, invoked as a callback from Tk_MakeWindowExist. * Creates an OpenGL window for the Togl widget. */static Window Togl_CreateWindow(Tk_Window tkwin, Window parent, ClientData instanceData) { struct Togl *togl = (struct Togl*) instanceData; XVisualInfo *visinfo = NULL; Display *dpy; Colormap cmap; int scrnum; int directCtx = GL_TRUE; Window window;#if defined(X11) int attrib_list[1000]; int attrib_count; int dummy; XSetWindowAttributes swa;#define MAX_ATTEMPTS 12 static int ci_depths[MAX_ATTEMPTS] = { 8, 4, 2, 1, 12, 16, 8, 4, 2, 1, 12, 16 }; static int dbl_flags[MAX_ATTEMPTS] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 };#elif defined(WIN32) HWND hwnd, parentWin; int pixelformat; HANDLE hInstance; WNDCLASS ToglClass; PIXELFORMATDESCRIPTOR pfd; XVisualInfo VisInf;#elif defined(macintosh) GLint attribs[20]; int na; AGLPixelFormat fmt; XVisualInfo VisInf;#endif /* X11 */ dpy = Tk_Display(togl->TkWin);#if defined(X11) /* Make sure OpenGL's GLX extension supported */ if (!glXQueryExtension(dpy, &dummy, &dummy)) { Tcl_SetResult(togl->Interp, "Togl: X server has no OpenGL GLX extension",TCL_STATIC); return DUMMY_WINDOW; } if (togl->ShareContext && FindTogl(togl->ShareContext)) { /* share OpenGL context with existing Togl widget */ struct Togl *shareWith = FindTogl(togl->ShareContext); assert(shareWith); assert(shareWith->GlCtx); togl->GlCtx = shareWith->GlCtx; togl->VisInfo = shareWith->VisInfo; visinfo = togl->VisInfo; printf("SHARE CTX\n"); } else { int attempt; /* It may take a few tries to get a visual */ for (attempt=0; attempt<MAX_ATTEMPTS; attempt++) { attrib_count = 0; attrib_list[attrib_count++] = GLX_USE_GL; if (togl->RgbaFlag) { /* RGB[A] mode */ attrib_list[attrib_count++] = GLX_RGBA; attrib_list[attrib_count++] = GLX_RED_SIZE; attrib_list[attrib_count++] = togl->RgbaRed; attrib_list[attrib_count++] = GLX_GREEN_SIZE; attrib_list[attrib_count++] = togl->RgbaGreen; attrib_list[attrib_count++] = GLX_BLUE_SIZE; attrib_list[attrib_count++] = togl->RgbaBlue; if (togl->AlphaFlag) { attrib_list[attrib_count++] = GLX_ALPHA_SIZE; attrib_list[attrib_count++] = togl->AlphaSize; } /* 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; } else { /* Color index mode */ int depth; attrib_list[attrib_count++] = GLX_BUFFER_SIZE; depth = ci_depths[attempt]; attrib_list[attrib_count++] = depth; } if (togl->DepthFlag) { attrib_list[attrib_count++] = GLX_DEPTH_SIZE; attrib_list[attrib_count++] = togl->DepthSize; } if (togl->DoubleFlag || dbl_flags[attempt]) { attrib_list[attrib_count++] = GLX_DOUBLEBUFFER; } if (togl->StencilFlag) { attrib_list[attrib_count++] = GLX_STENCIL_SIZE; attrib_list[attrib_count++] = togl->StencilSize; } if (togl->AccumFlag) { attrib_list[attrib_count++] = GLX_ACCUM_RED_SIZE; attrib_list[attrib_count++] = togl->AccumRed; attrib_list[attrib_count++] = GLX_ACCUM_GREEN_SIZE; attrib_list[attrib_count++] = togl->AccumGreen; attrib_list[attrib_count++] = GLX_ACCUM_BLUE_SIZE; attrib_list[attrib_count++] = togl->AccumBlue; if (togl->AlphaFlag) { attrib_list[attrib_count++] = GLX_ACCUM_ALPHA_SIZE; attrib_list[attrib_count++] = togl->AccumAlpha; } } if (togl->AuxNumber != 0) { attrib_list[attrib_count++] = GLX_AUX_BUFFERS; attrib_list[attrib_count++] = togl->AuxNumber; } if (togl->Indirect) { directCtx = GL_FALSE; } /* stereo hack */ /* if (togl->StereoFlag) { attrib_list[attrib_count++] = GLX_STEREO; } */ attrib_list[attrib_count++] = None; visinfo = glXChooseVisual(dpy, Tk_ScreenNumber(togl->TkWin), attrib_list); if (visinfo) { /* found a GLX visual! */ break; } } togl->VisInfo = visinfo; if (visinfo==NULL) { Tcl_SetResult(togl->Interp,"Togl: couldn't get visual",TCL_STATIC); return DUMMY_WINDOW; } /* * Create a new OpenGL rendering context. */ if (togl->ShareList) { /* share display lists with existing togl widget */ struct Togl *shareWith = FindTogl(togl->ShareList); GLXContext shareCtx; if (shareWith) shareCtx = shareWith->GlCtx; else shareCtx = None; togl->GlCtx = glXCreateContext(dpy, visinfo, shareCtx, directCtx); } else { /* don't share display lists */ togl->GlCtx = glXCreateContext(dpy, visinfo, None, directCtx); } if (togl->GlCtx == NULL) { Tcl_SetResult(togl->Interp, "could not create rendering context",TCL_STATIC); return DUMMY_WINDOW; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?