⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glut_win.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) Mark J. Kilgard, 1994, 1997.  *//* This program is freely distributable without licensing fees   and is provided without guarantee or warrantee expressed or   implied. This program is -not- in the public domain. */#ifdef __VMS#include <GL/vms_x_fix.h>#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#include <assert.h>#if !defined(_WIN32)#include <X11/Xlib.h>#include <X11/Xatom.h>#endif#include "glutint.h"GLUTwindow *__glutCurrentWindow = NULL;GLUTwindow **__glutWindowList = NULL;int __glutWindowListSize = 0;#if !defined(_WIN32)GLUTstale *__glutStaleWindowList = NULL;#endifGLUTwindow *__glutMenuWindow = NULL;void (*__glutFreeOverlayFunc) (GLUToverlay *);XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle,  Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc) = NULL;static Criterion requiredWindowCriteria[] ={  {LEVEL, EQ, 0},  {TRANSPARENT, EQ, 0}};static int numRequiredWindowCriteria = sizeof(requiredWindowCriteria) / sizeof(Criterion);static int requiredWindowCriteriaMask = (1 << LEVEL) | (1 << TRANSPARENT);static voidcleanWindowWorkList(GLUTwindow * window){  GLUTwindow **pEntry = &__glutWindowWorkList;  GLUTwindow *entry = __glutWindowWorkList;  /* Tranverse singly-linked window work list look for the     window. */  while (entry) {    if (entry == window) {      /* Found it; delete it. */      *pEntry = entry->prevWorkWin;      return;    } else {      pEntry = &entry->prevWorkWin;      entry = *pEntry;    }  }}#if !defined(_WIN32)static voidcleanStaleWindowList(GLUTwindow * window){  GLUTstale **pEntry = &__glutStaleWindowList;  GLUTstale *entry = __glutStaleWindowList;  /* Tranverse singly-linked stale window list look for the     window ID. */  while (entry) {    if (entry->window == window) {      /* Found it; delete it. */      *pEntry = entry->next;      free(entry);      return;    } else {      pEntry = &entry->next;      entry = *pEntry;    }  }}#endifstatic GLUTwindow *__glutWindowCache = NULL;GLUTwindow *__glutGetWindow(Window win){  int i;  /* Does win belong to the last window ID looked up? */  if (__glutWindowCache && (win == __glutWindowCache->win ||      (__glutWindowCache->overlay && win ==        __glutWindowCache->overlay->win))) {    return      __glutWindowCache;  }  /* Otherwise scan the window list looking for the window ID. */  for (i = 0; i < __glutWindowListSize; i++) {    if (__glutWindowList[i]) {      if (win == __glutWindowList[i]->win) {        __glutWindowCache = __glutWindowList[i];        return __glutWindowCache;      }      if (__glutWindowList[i]->overlay) {        if (win == __glutWindowList[i]->overlay->win) {          __glutWindowCache = __glutWindowList[i];          return __glutWindowCache;        }      }    }  }#if !defined(_WIN32)  {    GLUTstale *entry;    /* Scan through destroyed overlay window IDs for which no       DestroyNotify has yet been received. */    for (entry = __glutStaleWindowList; entry; entry = entry->next) {      if (entry->win == win)        return entry->window;    }  }#endif  return NULL;}/* CENTRY */int GLUTAPIENTRYglutGetWindow(void){  if (__glutCurrentWindow) {    return __glutCurrentWindow->num + 1;  } else {    return 0;  }}/* ENDCENTRY */void__glutSetWindow(GLUTwindow * window){  /* It is tempting to try to short-circuit the call to     glXMakeCurrent if we "know" we are going to make current     to a window we are already current to.  In fact, this     assumption breaks when GLUT is expected to integrated with     other OpenGL windowing APIs that also make current to     OpenGL contexts.  Since glXMakeCurrent short-circuits the     "already bound" case, GLUT avoids the temptation to do so     too. */  __glutCurrentWindow = window;  MAKE_CURRENT_LAYER(__glutCurrentWindow);#if !defined(_WIN32)  /* We should be careful to force a finish between each     iteration through the GLUT main loop if indirect OpenGL      contexts are in use; indirect contexts tend to have  much     longer latency because lots of OpenGL extension requests     can queue up in the X protocol stream.  We accomplish this     by posting GLUT_FINISH_WORK to be done. */  if (!__glutCurrentWindow->isDirect)    __glutPutOnWorkList(__glutCurrentWindow, GLUT_FINISH_WORK);#endif  /* If debugging is enabled, we'll want to check this window     for any OpenGL errors every iteration through the GLUT     main loop.  To accomplish this, we post the     GLUT_DEBUG_WORK to be done on this window. */  if (__glutDebug) {    __glutPutOnWorkList(__glutCurrentWindow, GLUT_DEBUG_WORK);  }}/* CENTRY */void GLUTAPIENTRYglutSetWindow(int win){  GLUTwindow *window;  if (win < 1 || win > __glutWindowListSize) {    __glutWarning("glutSetWindow attempted on bogus window.");    return;  }  window = __glutWindowList[win - 1];  if (!window) {    __glutWarning("glutSetWindow attempted on bogus window.");    return;  }  __glutSetWindow(window);}/* ENDCENTRY */static intgetUnusedWindowSlot(void){  int i;  /* Look for allocated, unused slot. */  for (i = 0; i < __glutWindowListSize; i++) {    if (!__glutWindowList[i]) {      return i;    }  }  /* Allocate a new slot. */  __glutWindowListSize++;  if (__glutWindowList) {    __glutWindowList = (GLUTwindow **)      realloc(__glutWindowList,      __glutWindowListSize * sizeof(GLUTwindow *));  } else {    /* XXX Some realloc's do not correctly perform a malloc       when asked to perform a realloc on a NULL pointer,       though the ANSI C library spec requires this. */    __glutWindowList = (GLUTwindow **)      malloc(sizeof(GLUTwindow *));  }  if (!__glutWindowList)    __glutFatalError("out of memory.");  __glutWindowList[__glutWindowListSize - 1] = NULL;  return __glutWindowListSize - 1;}static XVisualInfo *getVisualInfoCI(unsigned int mode){  static int bufSizeList[] =  {16, 12, 8, 4, 2, 1, 0};  XVisualInfo *vi;  int list[32];  int i, n = 0;  /* Should not be looking at display mode mask if     __glutDisplayString is non-NULL. */  assert(!__glutDisplayString);  list[n++] = GLX_BUFFER_SIZE;  list[n++] = 1;  if (GLUT_WIND_IS_DOUBLE(mode)) {    list[n++] = GLX_DOUBLEBUFFER;  }  if (GLUT_WIND_IS_STEREO(mode)) {    list[n++] = GLX_STEREO;  }  if (GLUT_WIND_HAS_DEPTH(mode)) {    list[n++] = GLX_DEPTH_SIZE;    list[n++] = 1;  }  if (GLUT_WIND_HAS_STENCIL(mode)) {    list[n++] = GLX_STENCIL_SIZE;    list[n++] = 1;  }  list[n] = (int) None; /* terminate list */  /* glXChooseVisual specify GLX_BUFFER_SIZE prefers the     "smallest index buffer of at least the specified size".     This would be reasonable if GLUT allowed the user to     specify the required buffe size, but GLUT's display mode     is too simplistic (easy to use?). GLUT should try to find     the "largest".  So start with a large buffer size and     shrink until we find a matching one that exists. */  for (i = 0; bufSizeList[i]; i++) {    /* XXX Assumes list[1] is where GLX_BUFFER_SIZE parameter       is. */    list[1] = bufSizeList[i];    vi = glXChooseVisual(__glutDisplay,      __glutScreen, list);    if (vi)      return vi;  }  return NULL;}static XVisualInfo *getVisualInfoRGB(unsigned int mode){  int list[32];  int n = 0;  /* Should not be looking at display mode mask if     __glutDisplayString is non-NULL. */  assert(!__glutDisplayString);  /* XXX Would a caching mechanism to minize the calls to     glXChooseVisual? You'd have to reference count     XVisualInfo* pointers.  Would also have to properly     interact with glutInitDisplayString. */  list[n++] = GLX_RGBA;  list[n++] = GLX_RED_SIZE;  list[n++] = 1;  list[n++] = GLX_GREEN_SIZE;  list[n++] = 1;  list[n++] = GLX_BLUE_SIZE;  list[n++] = 1;  if (GLUT_WIND_HAS_ALPHA(mode)) {    list[n++] = GLX_ALPHA_SIZE;    list[n++] = 1;  }  if (GLUT_WIND_IS_DOUBLE(mode)) {    list[n++] = GLX_DOUBLEBUFFER;  }  if (GLUT_WIND_IS_STEREO(mode)) {    list[n++] = GLX_STEREO;  }  if (GLUT_WIND_HAS_DEPTH(mode)) {    list[n++] = GLX_DEPTH_SIZE;    list[n++] = 1;  }  if (GLUT_WIND_HAS_STENCIL(mode)) {    list[n++] = GLX_STENCIL_SIZE;    list[n++] = 1;  }  if (GLUT_WIND_HAS_ACCUM(mode)) {    list[n++] = GLX_ACCUM_RED_SIZE;    list[n++] = 1;    list[n++] = GLX_ACCUM_GREEN_SIZE;    list[n++] = 1;    list[n++] = GLX_ACCUM_BLUE_SIZE;    list[n++] = 1;    if (GLUT_WIND_HAS_ALPHA(mode)) {      list[n++] = GLX_ACCUM_ALPHA_SIZE;      list[n++] = 1;    }  }#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample))  if (GLUT_WIND_IS_MULTISAMPLE(mode)) {    if (!__glutIsSupportedByGLX("GLX_SGIS_multisample") &&        !__glutIsSupportedByGLX("GLX_ARB_multisample"))      return NULL;#if defined(GLX_ARB_multisample)    list[n++] = GLX_SAMPLES_ARB;#elif defined(GLX_SGIS_multisample)    list[n++] = GLX_SAMPLES_SGIS;#endif    /* XXX Is 4 a reasonable minimum acceptable number of       samples? */    list[n++] = 4;  }#endif  list[n] = (int) None; /* terminate list */  return glXChooseVisual(__glutDisplay,    __glutScreen, list);}XVisualInfo *__glutGetVisualInfo(unsigned int mode){  /* XXX GLUT_LUMINANCE not implemented for GLUT 3.0. */  if (GLUT_WIND_IS_LUMINANCE(mode))    return NULL;  if (GLUT_WIND_IS_RGB(mode))    return getVisualInfoRGB(mode);  else    return getVisualInfoCI(mode);}XVisualInfo *__glutDetermineVisual(  unsigned int displayMode,  Bool * treatAsSingle,  XVisualInfo * (getVisualInfo) (unsigned int)){  XVisualInfo *vis;  /* Should not be looking at display mode mask if     __glutDisplayString is non-NULL. */  assert(!__glutDisplayString);  *treatAsSingle = GLUT_WIND_IS_SINGLE(displayMode);  vis = getVisualInfo(displayMode);  if (!vis) {    /* Fallback cases when can't get exactly what was asked       for... */    if (GLUT_WIND_IS_SINGLE(displayMode)) {      /* If we can't find a single buffered visual, try looking         for a double buffered visual.  We can treat a double         buffered visual as a single buffer visual by changing         the draw buffer to GL_FRONT and treating any swap         buffers as no-ops. */      displayMode |= GLUT_DOUBLE;      vis = getVisualInfo(displayMode);      *treatAsSingle = True;    }    if (!vis && GLUT_WIND_IS_MULTISAMPLE(displayMode)) {      /* If we can't seem to get multisampling (ie, not Reality         Engine class graphics!), go without multisampling.  It         is up to the application to query how many multisamples         were allocated (0 equals no multisampling) if the         application is going to use multisampling for more than         just antialiasing. */      displayMode &= ~GLUT_MULTISAMPLE;      vis = getVisualInfo(displayMode);    }  }  return vis;}static void GLUTCALLBACK__glutDefaultDisplay(void){  /* XXX Remove the warning after GLUT 3.0. */  __glutWarning("The following is a new check for GLUT 3.0; update your code.");  __glutFatalError(    "redisplay needed for window %d, but no display callback.",    __glutCurrentWindow->num + 1);}void GLUTCALLBACK__glutDefaultReshape(int width, int height){  GLUToverlay *overlay;  /* Adjust the viewport of the window (and overlay if one     exists). */  MAKE_CURRENT_WINDOW(__glutCurrentWindow);  glViewport(0, 0, (GLsizei) width, (GLsizei) height);  overlay = __glutCurrentWindow->overlay;  if (overlay) {    MAKE_CURRENT_OVERLAY(overlay);    glViewport(0, 0, (GLsizei) width, (GLsizei) height);  }  /* Make sure we are current to the current layer (application     should be able to count on the current layer not changing     unless the application explicitly calls glutUseLayer). */  MAKE_CURRENT_LAYER(__glutCurrentWindow);}XVisualInfo *__glutDetermineWindowVisual(Bool * treatAsSingle, Bool * visAlloced, void **fbc){  if (__glutDisplayString) {    /* __glutDisplayString should be NULL except if       glutInitDisplayString has been called to register a       different display string.  Calling glutInitDisplayString       means using a string instead of an integer mask determine       the visual to use. Using the function pointer variable       __glutDetermineVisualFromString below avoids linking in       the code for implementing glutInitDisplayString (ie,       glut_dstr.o) unless glutInitDisplayString gets called by       the application. */    assert(__glutDetermineVisualFromString);    *visAlloced = False;    *fbc = NULL;    return __glutDetermineVisualFromString(__glutDisplayString, treatAsSingle,      requiredWindowCriteria, numRequiredWindowCriteria, requiredWindowCriteriaMask, fbc);  } else {    *visAlloced = True;    *fbc = NULL;    return __glutDetermineVisual(__glutDisplayMode,      treatAsSingle, __glutGetVisualInfo);  }}/* ARGSUSED5 */  /* Only Win32 uses gameMode parameter. */GLUTwindow *__glutCreateWindow(GLUTwindow * parent,  int x, int y, int width, int height, int gameMode){  GLUTwindow *window;  XSetWindowAttributes wa;  unsigned long attribMask;  int winnum;  int i;  void *fbc;#if defined(_WIN32)  WNDCLASS wc;  int style;  if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc)) {    __glutOpenWin32Connection(NULL);  }#else  if (!__glutDisplay) {    __glutOpenXConnection(NULL);  }#endif  if (__glutGameModeWindow) {    __glutFatalError("cannot create windows in game mode.");  }  winnum = getUnusedWindowSlot();  window = (GLUTwindow *) malloc(sizeof(GLUTwindow));  if (!window) {    __glutFatalError("out of memory.");  }  window->num = winnum;#if !defined(_WIN32)  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,    &window->visAlloced, &fbc);  if (!window->vis) {    __glutFatalError(      "visual with necessary capabilities not found.");  }  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);#endif  window->eventMask = StructureNotifyMask | ExposureMask;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -