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