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 + -
显示快捷键?