togl.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 2,204 行 · 第 1/5 页
C
2,204 行
/* * Togl_CreateCommand * * Declares a new C sub-command of Togl callable from Tcl. * Every time the sub-command is called from Tcl, the * C routine will be called with all the arguments from Tcl. */void Togl_CreateCommand( char *cmd_name, Togl_CmdProc *cmd_proc){ int new_item; Tcl_HashEntry *entry; entry = Tcl_CreateHashEntry(&CommandTable, cmd_name, &new_item); Tcl_SetHashValue(entry, cmd_proc);}/* * Togl_MakeCurrent * * Bind the OpenGL rendering context to the specified * Togl widget. */void Togl_MakeCurrent( const struct Togl *togl ){#if defined(WIN32) int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLHglrc); assert(res == TRUE);#elif defined(X11) glXMakeCurrent( Tk_Display(togl->TkWin), Tk_WindowId(togl->TkWin), togl->GlCtx );#if defined(__sgi) && defined(STEREO) stereoMakeCurrent( Tk_Display(togl->TkWin), Tk_WindowId(togl->TkWin), togl->GlCtx );#endif /*__sgi STEREO */#elif defined(macintosh) aglSetCurrentContext(togl->aglCtx);#endif /* WIN32 */}#ifdef macintosh/* tell OpenGL which part of the Mac window to render to */static void SetMacBufRect(struct Togl *togl){ GLint wrect[4]; /* set wrect[0,1] to lower left corner of widget */ wrect[2] = ((TkWindow *) (togl->TkWin))->changes.width; wrect[3] = ((TkWindow *) (togl->TkWin))->changes.height; wrect[0] = ((TkWindow *) (togl->TkWin))->privatePtr->xOff; wrect[1] = ((TkWindow *) (togl->TkWin))->privatePtr->toplevel->portPtr->portRect.bottom - wrect[3] - ((TkWindow *) (togl->TkWin))->privatePtr->yOff; aglSetInteger(togl->aglCtx, AGL_BUFFER_RECT, wrect); aglEnable(togl->aglCtx, AGL_BUFFER_RECT); aglUpdateContext(togl->aglCtx);}#endif/* * Called when the widget's contents must be redrawn. Basically, we * just call the user's render callback function. * * Note that the parameter type is ClientData so this function can be * passed to Tk_DoWhenIdle(). */static void Togl_Render( ClientData clientData ){ struct Togl *togl = (struct Togl *)clientData; if (togl->DisplayProc) {#ifdef macintosh /* Mac is complicated here because OpenGL needs to know what part of the parent window to render into, and it seems that region need to be invalidated before drawing, so that QuickDraw will allow OpenGL to transfer pixels into that part of the window. I'm not even totally sure how or why this works as it does, since this aspect of Mac OpenGL seems to be totally undocumented. This was put together by trial and error! (thiessen) */ MacRegion r; RgnPtr rp = &r; GrafPtr curPort, parentWin; parentWin = (GrafPtr) (((MacDrawable *) (Tk_WindowId(togl->TkWin)))->toplevel->portPtr); if (!parentWin) return;#endif Togl_MakeCurrent(togl);#ifdef macintosh /* Set QuickDraw port and clipping region */ GetPort(&curPort); SetPort(parentWin); r.rgnBBox.left = ((TkWindow *) (togl->TkWin))->privatePtr->xOff; r.rgnBBox.right = r.rgnBBox.left + ((TkWindow *) (togl->TkWin))->changes.width - 1; r.rgnBBox.top = ((TkWindow *) (togl->TkWin))->privatePtr->yOff; r.rgnBBox.bottom = r.rgnBBox.top + ((TkWindow *) (togl->TkWin))->changes.height - 1; r.rgnSize = sizeof(Region); InvalRgn(&rp); SetClip(&rp); /* this may seem an odd place to put this, with possibly redundant calls to aglSetInteger(AGL_BUFFER_RECT...), but for some reason performance is actually a lot better if this is called before every render... */ SetMacBufRect(togl);#endif togl->DisplayProc(togl);#ifdef macintosh SetPort(curPort); /* restore previous port */#endif } togl->UpdatePending = GL_FALSE;}static void RenderOverlay( ClientData clientData ){ struct Togl *togl = (struct Togl *)clientData; if (togl->OverlayFlag && togl->OverlayDisplayProc) {#if defined(WIN32) int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLHglrc); assert(res == TRUE);#elif defined(X11) glXMakeCurrent( Tk_Display(togl->TkWin), togl->OverlayWindow, togl->OverlayCtx );#if defined(__sgi) && defined(STEREO) stereoMakeCurrent( Tk_Display(togl->TkWin), togl->OverlayWindow, togl->OverlayCtx );#endif /*__sgi STEREO */#endif /* WIN32 */ togl->OverlayDisplayProc(togl); } togl->OverlayUpdatePending = GL_FALSE;}/* * It's possible to change with this function or in a script some * options like RGBA - ColorIndex ; Z-buffer and so on */int Togl_Configure(Tcl_Interp *interp, struct Togl *togl, int argc, char *argv[], int flags){ int oldRgbaFlag = togl->RgbaFlag; int oldRgbaRed = togl->RgbaRed; int oldRgbaGreen = togl->RgbaGreen; int oldRgbaBlue = togl->RgbaBlue; int oldDoubleFlag = togl->DoubleFlag; int oldDepthFlag = togl->DepthFlag; int oldDepthSize = togl->DepthSize; int oldAccumFlag = togl->AccumFlag; int oldAccumRed = togl->AccumRed; int oldAccumGreen = togl->AccumGreen; int oldAccumBlue = togl->AccumBlue; int oldAccumAlpha = togl->AccumAlpha; int oldAlphaFlag = togl->AlphaFlag; int oldAlphaSize = togl->AlphaSize; int oldStencilFlag = togl->StencilFlag; int oldStencilSize = togl->StencilSize; int oldAuxNumber = togl->AuxNumber;#ifndef CONST84#define CONST84#endif if (Tk_ConfigureWidget(interp, togl->TkWin, configSpecs, argc, (CONST84 char**)argv, (char *)togl, flags) == TCL_ERROR) { return(TCL_ERROR); }#ifndef USE_OVERLAY if (togl->OverlayFlag) { TCL_ERR(interp,"Sorry, overlay was disabled"); }#endif Tk_GeometryRequest(togl->TkWin, togl->Width, togl->Height); /* this added per Lou Arata <arata@enya.picker.com> */ Tk_ResizeWindow(togl->TkWin, togl->Width, togl->Height); if (togl->ReshapeProc &&#if defined(WIN32) togl->tglGLHglrc#elif defined(X11) togl->GlCtx#elif defined(macintosh) togl->aglCtx#endif ) { Togl_MakeCurrent(togl); togl->ReshapeProc(togl); } if (togl->RgbaFlag != oldRgbaFlag || togl->RgbaRed != oldRgbaRed || togl->RgbaGreen != oldRgbaGreen || togl->RgbaBlue != oldRgbaBlue || togl->DoubleFlag != oldDoubleFlag || togl->DepthFlag != oldDepthFlag || togl->DepthSize != oldDepthSize || togl->AccumFlag != oldAccumFlag || togl->AccumRed != oldAccumRed || togl->AccumGreen != oldAccumGreen || togl->AccumBlue != oldAccumBlue || togl->AccumAlpha != oldAccumAlpha || togl->AlphaFlag != oldAlphaFlag || togl->AlphaSize != oldAlphaSize || togl->StencilFlag != oldStencilFlag || togl->StencilSize != oldStencilSize || togl->AuxNumber != oldAuxNumber) {#ifdef MESA_COLOR_HACK free_default_color_cells( Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin) );#endif }#if defined(__sgi) && defined(STEREO) stereoInit(togl,togl->StereoFlag);#endif return TCL_OK;}int Togl_Widget(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ struct Togl *togl = (struct Togl *)clientData; int result = TCL_OK; Tcl_HashEntry *entry; Tcl_HashSearch search; Togl_CmdProc *cmd_proc; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ?options?\"", NULL); return TCL_ERROR; } Tk_Preserve((ClientData)togl); if (!strncmp(argv[1], "configure", MAX(1, strlen(argv[1])))) { if (argc == 2) { /* Return list of all configuration parameters */ result = Tk_ConfigureInfo(interp, togl->TkWin, configSpecs, (char *)togl, (char *)NULL, 0); } else if (argc == 3) { if (strcmp(argv[2],"-extensions")==0) { /* Return a list of OpenGL extensions available */ char *extensions; extensions = (char *) glGetString(GL_EXTENSIONS); Tcl_SetResult( interp, extensions, TCL_STATIC ); result = TCL_OK; } else { /* Return a specific configuration parameter */ result = Tk_ConfigureInfo(interp, togl->TkWin, configSpecs, (char *)togl, argv[2], 0); } } else { /* Execute a configuration change */ result = Togl_Configure(interp, togl, argc-2, argv+2, TK_CONFIG_ARGV_ONLY); } } else if (!strncmp(argv[1], "render", MAX(1, strlen(argv[1])))) { /* force the widget to be redrawn */ Togl_Render((ClientData) togl); } else if (!strncmp(argv[1], "swapbuffers", MAX(1, strlen(argv[1])))) { /* force the widget to be redrawn */ Togl_SwapBuffers(togl); } else if (!strncmp(argv[1], "makecurrent", MAX(1, strlen(argv[1])))) { /* force the widget to be redrawn */ Togl_MakeCurrent(togl); } else if (!strncmp(argv[1], "loadbitmapfont", MAX(1, strlen(argv[1])))){ if (argc == 3){ GLuint fontbase; Tcl_Obj * fontbaseAsTclObject; fontbase = Togl_LoadBitmapFont(togl,argv[2]); if (fontbase) { fontbaseAsTclObject = Tcl_NewIntObj(fontbase); Tcl_SetObjResult(interp, fontbaseAsTclObject); result = TCL_OK; } else { Tcl_AppendResult(interp, "Could not allocate font",NULL); result = TCL_ERROR; } } else { Tcl_AppendResult(interp, "wrong # args",NULL); result=TCL_ERROR; } } else if (!strncmp(argv[1], "unloadbitmapfont", MAX(1, strlen(argv[1])))) { if (argc == 3) { Togl_UnloadBitmapFont(togl, atoi(argv[2])); result = TCL_OK; } else { Tcl_AppendResult(interp, "wrong # args",NULL); result = TCL_ERROR; } } else { /* Probably a user-defined function */ entry = Tcl_FindHashEntry(&CommandTable, argv[1]); if (entry != NULL) { cmd_proc = (Togl_CmdProc *)Tcl_GetHashValue(entry); result = cmd_proc(togl, argc, argv); } else { Tcl_AppendResult(interp, "Togl: Unknown option: ", argv[1], "\n", "Try: configure or render\n", "or one of the user-defined commands:\n", NULL); entry = Tcl_FirstHashEntry(&CommandTable, &search); while (entry) { Tcl_AppendResult(interp, " ", Tcl_GetHashKey(&CommandTable, entry), "\n", NULL); entry = Tcl_NextHashEntry(&search); } result = TCL_ERROR; } } Tk_Release((ClientData)togl); return result;}/* * Togl_Cmd * * Called when Togl is executed - creation of a Togl widget. * * Creates a new window * * Creates an 'Togl' data structure * * Creates an event handler for this window * * Creates a command that handles this object * * Configures this Togl for the given arguments */static int Togl_Cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv){ char *name; Tk_Window mainwindow = (Tk_Window)clientData; Tk_Window tkwin; struct Togl *togl; if (argc <= 1) { TCL_ERR(interp, "wrong # args: should be \"pathName read filename\""); } /* Create the window. */ name = argv[1]; tkwin = Tk_CreateWindowFromPath(interp, mainwindow, name, (char *) NULL); if (tkwin == NULL) { return TCL_ERROR; } Tk_SetClass(tkwin, "Togl"); /* Create Togl data structure */ togl = (struct Togl *)malloc(sizeof(struct Togl)); if (!togl) { return TCL_ERROR; } togl->Next = NULL;#if defined(WIN32) togl->tglGLHdc = NULL; togl->tglGLHglrc = NULL;#elif defined(X11) togl->GlCtx = NULL; togl->OverlayCtx = NULL;#elif defined(macintosh) togl->aglCtx = NULL;#endif /* WIN32 */ togl->display = Tk_Display( tkwin ); togl->TkWin = tkwin; togl->Interp = interp;#ifndef NO_TK_CURSOR togl->Cursor = None;#endif togl->Width = 0; togl->Height = 0; togl->TimerInterval = 0; togl->RgbaFlag = 1; togl->RgbaRed = 1; togl->RgbaGreen = 1; togl->RgbaBlue = 1; togl->DoubleFlag = 0; togl->DepthFlag = 0; togl->DepthSize = 1; togl->AccumFlag = 0; togl->AccumRed = 1; togl->AccumGreen = 1; togl->AccumBlue = 1; togl->AccumAlpha = 1; togl->AlphaFlag = 0; togl->AlphaSize = 1; togl->StencilFlag = 0; togl->StencilSize = 1; togl->OverlayFlag = 0; togl->StereoFlag = 0; togl->AuxNumber = 0; togl->Indirect = GL_FALSE; togl->UpdatePending = GL_FALSE; togl->OverlayUpdatePending = GL_FALSE; togl->CreateProc = DefaultCreateProc; togl->DisplayProc = DefaultDisplayProc; togl->ReshapeProc = DefaultReshapeProc; togl->DestroyProc = DefaultDestroyProc; togl->TimerProc = DefaultTimerProc; togl->OverlayDisplayProc = DefaultOverlayDisplayProc; togl->ShareList = NULL; togl->ShareContext = NULL; togl->Ident = NULL; togl->Client_Data = DefaultClientData;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?