glut_vidresize.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:7k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1996. */
  2. /* This program is freely distributable without licensing fees 
  3.    and is provided without guarantee or warrantee expressed or 
  4.    implied. This program is -not- in the public domain. */
  5. #include <stdlib.h>
  6. #if !defined(_WIN32)
  7. #include <GL/glx.h>
  8. #endif
  9. #ifdef __sgi
  10. #include <dlfcn.h>
  11. #endif
  12. #include "glutint.h"
  13. /* Grumble.  The IRIX 6.3 and early IRIX 6.4 OpenGL headers
  14.    support the video resize extension, but failed to define
  15.    GLX_SGIX_video_resize. */
  16. #ifdef GLX_SYNC_FRAME_SGIX
  17. #define GLX_SGIX_video_resize 1
  18. #endif
  19. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  20. static int canVideoResize = -1;
  21. static int videoResizeChannel;
  22. #else
  23. static int canVideoResize = 0;
  24. #endif
  25. static int videoResizeInUse = 0;
  26. static int dx = -1, dy = -1, dw = -1, dh = -1;
  27. /* XXX Note that IRIX 6.2, 6.3, and some 6.4 versions have a
  28.    bug where programs seg-fault when they attempt video
  29.    resizing from an indirect OpenGL context (either local or
  30.    over a network). */
  31. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  32. static volatile int errorCaught;
  33. /* ARGSUSED */
  34. static
  35. catchXSGIvcErrors(Display * dpy, XErrorEvent * event)
  36. {
  37.   errorCaught = 1;
  38.   return 0;
  39. }
  40. #endif
  41. /* CENTRY */
  42. int APIENTRY 
  43. glutVideoResizeGet(GLenum param)
  44. {
  45. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  46.   if (canVideoResize < 0) {
  47.     canVideoResize = __glutIsSupportedByGLX("GLX_SGIX_video_resize");
  48.     if (canVideoResize) {
  49. #if __sgi
  50.       /* This is a hack because IRIX 6.2, 6.3, and some 6.4
  51.          versions were released with GLX_SGIX_video_resize
  52.          being advertised by the X server though the video
  53.          resize extension is not actually supported.  We try to
  54.          determine if the libGL.so we are using actually has a
  55.          video resize entrypoint before we try to use the
  56.          feature. */
  57.       void (*func) (void);
  58.       void *glxDso = dlopen("libGL.so", RTLD_LAZY);
  59.       func = (void (*)(void)) dlsym(glxDso, "glXQueryChannelDeltasSGIX");
  60.       if (!func) {
  61.         canVideoResize = 0;
  62.       } else
  63. #endif
  64.       {
  65.         char *channelString;
  66.         int (*handler) (Display *, XErrorEvent *);
  67.         channelString = getenv("GLUT_VIDEO_RESIZE_CHANNEL");
  68.         videoResizeChannel = channelString ? atoi(channelString) : 0;
  69.         /* Work around another annoying problem with SGI's
  70.            GLX_SGIX_video_resize implementation.  Early IRIX
  71.            6.4 OpenGL's advertise the extension and have the
  72.            video resize API, but an XSGIvc X protocol errors
  73.            result trying to use the API.  Set up an error
  74.            handler to intercept what would otherwise be a fatal
  75.            error.  If an error was recieved, do not report that
  76.            video resize is possible. */
  77.         handler = XSetErrorHandler(catchXSGIvcErrors);
  78.         errorCaught = 0;
  79.         glXQueryChannelDeltasSGIX(__glutDisplay, __glutScreen,
  80.           videoResizeChannel, &dx, &dy, &dw, &dh);
  81.         /* glXQueryChannelDeltasSGIX is an inherent X server
  82.            round-trip so we know we will have gotten either the
  83.            correct reply or and error by this time. */
  84.         XSetErrorHandler(handler);
  85.         /* Still yet another work around.  In IRIX 6.4 betas,
  86.            glXQueryChannelDeltasSGIX will return as if it
  87.            succeeded, but the values are filled with junk.
  88.            Watch to make sure the delta variables really make
  89.            sense. */
  90.         if (errorCaught ||
  91.           dx < 0 || dy < 0 || dw < 0 || dh < 0 ||
  92.           dx > 2048 || dy > 2048 || dw > 2048 || dh > 2048) {
  93.           canVideoResize = 0;
  94.         }
  95.       }
  96.     }
  97.   }
  98. #endif /* GLX_SGIX_video_resize */
  99.   switch (param) {
  100.   case GLUT_VIDEO_RESIZE_POSSIBLE:
  101.     return canVideoResize;
  102.   case GLUT_VIDEO_RESIZE_IN_USE:
  103.     return videoResizeInUse;
  104.   case GLUT_VIDEO_RESIZE_X_DELTA:
  105.     return dx;
  106.   case GLUT_VIDEO_RESIZE_Y_DELTA:
  107.     return dy;
  108.   case GLUT_VIDEO_RESIZE_WIDTH_DELTA:
  109.     return dw;
  110.   case GLUT_VIDEO_RESIZE_HEIGHT_DELTA:
  111.     return dh;
  112.   case GLUT_VIDEO_RESIZE_X:
  113.   case GLUT_VIDEO_RESIZE_Y:
  114.   case GLUT_VIDEO_RESIZE_WIDTH:
  115.   case GLUT_VIDEO_RESIZE_HEIGHT:
  116. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  117.     if (videoResizeInUse) {
  118.       int x, y, width, height;
  119.       glXQueryChannelRectSGIX(__glutDisplay, __glutScreen,
  120.         videoResizeChannel, &x, &y, &width, &height);
  121.       switch (param) {
  122.       case GLUT_VIDEO_RESIZE_X:
  123.         return x;
  124.       case GLUT_VIDEO_RESIZE_Y:
  125.         return y;
  126.       case GLUT_VIDEO_RESIZE_WIDTH:
  127.         return width;
  128.       case GLUT_VIDEO_RESIZE_HEIGHT:
  129.         return height;
  130.       }
  131.     }
  132. #endif
  133.     return -1;
  134.   default:
  135.     __glutWarning("invalid glutVideoResizeGet parameter: %d", param);
  136.     return -1;
  137.   }
  138. }
  139. void APIENTRY 
  140. glutSetupVideoResizing(void)
  141. {
  142. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  143.   if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
  144.     glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
  145.       videoResizeChannel, __glutCurrentWindow->win);
  146.     videoResizeInUse = 1;
  147.   } else
  148. #endif
  149.     __glutFatalError("glutEstablishVideoResizing: video resizing not possible.n");
  150. }
  151. void APIENTRY 
  152. glutStopVideoResizing(void)
  153. {
  154. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  155.   if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
  156.     if (videoResizeInUse) {
  157.       glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
  158.         videoResizeChannel, None);
  159.       videoResizeInUse = 0;
  160.     }
  161.   }
  162. #endif
  163. }
  164. /* ARGSUSED */
  165. void APIENTRY 
  166. glutVideoResize(int x, int y, int width, int height)
  167. {
  168. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  169.   if (videoResizeInUse) {
  170. #ifdef GLX_SYNC_SWAP_SGIX
  171.     /* glXChannelRectSyncSGIX introduced in a patch to IRIX
  172.        6.2; the original unpatched IRIX 6.2 behavior is always
  173.        GLX_SYNC_SWAP_SGIX. */
  174.     glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
  175.       videoResizeChannel, GLX_SYNC_SWAP_SGIX);
  176. #endif
  177.     glXChannelRectSGIX(__glutDisplay, __glutScreen,
  178.       videoResizeChannel, x, y, width, height);
  179.   }
  180. #endif
  181. }
  182. /* ARGSUSED */
  183. void APIENTRY 
  184. glutVideoPan(int x, int y, int width, int height)
  185. {
  186. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
  187.   if (videoResizeInUse) {
  188. #ifdef GLX_SYNC_FRAME_SGIX
  189.     /* glXChannelRectSyncSGIX introduced in a patch to IRIX
  190.        6.2; the original unpatched IRIX 6.2 behavior is always
  191.        GLX_SYNC_SWAP_SGIX.  We just ignore that we cannot
  192.        accomplish GLX_SYNC_FRAME_SGIX on IRIX unpatched 6.2;
  193.        this means you'd need a glutSwapBuffers to actually
  194.        realize the video resize. */
  195.     glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
  196.       videoResizeChannel, GLX_SYNC_FRAME_SGIX);
  197. #endif
  198.     glXChannelRectSGIX(__glutDisplay, __glutScreen,
  199.       videoResizeChannel, x, y, width, height);
  200.   }
  201. #endif
  202. }
  203. /* ENDCENTRY */