glut_vidresize.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:7k
- /* Copyright (c) Mark J. Kilgard, 1996. */
- /* 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. */
- #include <stdlib.h>
- #if !defined(_WIN32)
- #include <GL/glx.h>
- #endif
- #ifdef __sgi
- #include <dlfcn.h>
- #endif
- #include "glutint.h"
- /* Grumble. The IRIX 6.3 and early IRIX 6.4 OpenGL headers
- support the video resize extension, but failed to define
- GLX_SGIX_video_resize. */
- #ifdef GLX_SYNC_FRAME_SGIX
- #define GLX_SGIX_video_resize 1
- #endif
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- static int canVideoResize = -1;
- static int videoResizeChannel;
- #else
- static int canVideoResize = 0;
- #endif
- static int videoResizeInUse = 0;
- static int dx = -1, dy = -1, dw = -1, dh = -1;
- /* XXX Note that IRIX 6.2, 6.3, and some 6.4 versions have a
- bug where programs seg-fault when they attempt video
- resizing from an indirect OpenGL context (either local or
- over a network). */
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- static volatile int errorCaught;
- /* ARGSUSED */
- static
- catchXSGIvcErrors(Display * dpy, XErrorEvent * event)
- {
- errorCaught = 1;
- return 0;
- }
- #endif
- /* CENTRY */
- int APIENTRY
- glutVideoResizeGet(GLenum param)
- {
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- if (canVideoResize < 0) {
- canVideoResize = __glutIsSupportedByGLX("GLX_SGIX_video_resize");
- if (canVideoResize) {
- #if __sgi
- /* This is a hack because IRIX 6.2, 6.3, and some 6.4
- versions were released with GLX_SGIX_video_resize
- being advertised by the X server though the video
- resize extension is not actually supported. We try to
- determine if the libGL.so we are using actually has a
- video resize entrypoint before we try to use the
- feature. */
- void (*func) (void);
- void *glxDso = dlopen("libGL.so", RTLD_LAZY);
- func = (void (*)(void)) dlsym(glxDso, "glXQueryChannelDeltasSGIX");
- if (!func) {
- canVideoResize = 0;
- } else
- #endif
- {
- char *channelString;
- int (*handler) (Display *, XErrorEvent *);
- channelString = getenv("GLUT_VIDEO_RESIZE_CHANNEL");
- videoResizeChannel = channelString ? atoi(channelString) : 0;
- /* Work around another annoying problem with SGI's
- GLX_SGIX_video_resize implementation. Early IRIX
- 6.4 OpenGL's advertise the extension and have the
- video resize API, but an XSGIvc X protocol errors
- result trying to use the API. Set up an error
- handler to intercept what would otherwise be a fatal
- error. If an error was recieved, do not report that
- video resize is possible. */
- handler = XSetErrorHandler(catchXSGIvcErrors);
- errorCaught = 0;
- glXQueryChannelDeltasSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, &dx, &dy, &dw, &dh);
- /* glXQueryChannelDeltasSGIX is an inherent X server
- round-trip so we know we will have gotten either the
- correct reply or and error by this time. */
- XSetErrorHandler(handler);
- /* Still yet another work around. In IRIX 6.4 betas,
- glXQueryChannelDeltasSGIX will return as if it
- succeeded, but the values are filled with junk.
- Watch to make sure the delta variables really make
- sense. */
- if (errorCaught ||
- dx < 0 || dy < 0 || dw < 0 || dh < 0 ||
- dx > 2048 || dy > 2048 || dw > 2048 || dh > 2048) {
- canVideoResize = 0;
- }
- }
- }
- }
- #endif /* GLX_SGIX_video_resize */
- switch (param) {
- case GLUT_VIDEO_RESIZE_POSSIBLE:
- return canVideoResize;
- case GLUT_VIDEO_RESIZE_IN_USE:
- return videoResizeInUse;
- case GLUT_VIDEO_RESIZE_X_DELTA:
- return dx;
- case GLUT_VIDEO_RESIZE_Y_DELTA:
- return dy;
- case GLUT_VIDEO_RESIZE_WIDTH_DELTA:
- return dw;
- case GLUT_VIDEO_RESIZE_HEIGHT_DELTA:
- return dh;
- case GLUT_VIDEO_RESIZE_X:
- case GLUT_VIDEO_RESIZE_Y:
- case GLUT_VIDEO_RESIZE_WIDTH:
- case GLUT_VIDEO_RESIZE_HEIGHT:
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- if (videoResizeInUse) {
- int x, y, width, height;
- glXQueryChannelRectSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, &x, &y, &width, &height);
- switch (param) {
- case GLUT_VIDEO_RESIZE_X:
- return x;
- case GLUT_VIDEO_RESIZE_Y:
- return y;
- case GLUT_VIDEO_RESIZE_WIDTH:
- return width;
- case GLUT_VIDEO_RESIZE_HEIGHT:
- return height;
- }
- }
- #endif
- return -1;
- default:
- __glutWarning("invalid glutVideoResizeGet parameter: %d", param);
- return -1;
- }
- }
- void APIENTRY
- glutSetupVideoResizing(void)
- {
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
- glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, __glutCurrentWindow->win);
- videoResizeInUse = 1;
- } else
- #endif
- __glutFatalError("glutEstablishVideoResizing: video resizing not possible.n");
- }
- void APIENTRY
- glutStopVideoResizing(void)
- {
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
- if (videoResizeInUse) {
- glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, None);
- videoResizeInUse = 0;
- }
- }
- #endif
- }
- /* ARGSUSED */
- void APIENTRY
- glutVideoResize(int x, int y, int width, int height)
- {
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- if (videoResizeInUse) {
- #ifdef GLX_SYNC_SWAP_SGIX
- /* glXChannelRectSyncSGIX introduced in a patch to IRIX
- 6.2; the original unpatched IRIX 6.2 behavior is always
- GLX_SYNC_SWAP_SGIX. */
- glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, GLX_SYNC_SWAP_SGIX);
- #endif
- glXChannelRectSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, x, y, width, height);
- }
- #endif
- }
- /* ARGSUSED */
- void APIENTRY
- glutVideoPan(int x, int y, int width, int height)
- {
- #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
- if (videoResizeInUse) {
- #ifdef GLX_SYNC_FRAME_SGIX
- /* glXChannelRectSyncSGIX introduced in a patch to IRIX
- 6.2; the original unpatched IRIX 6.2 behavior is always
- GLX_SYNC_SWAP_SGIX. We just ignore that we cannot
- accomplish GLX_SYNC_FRAME_SGIX on IRIX unpatched 6.2;
- this means you'd need a glutSwapBuffers to actually
- realize the video resize. */
- glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, GLX_SYNC_FRAME_SGIX);
- #endif
- glXChannelRectSGIX(__glutDisplay, __glutScreen,
- videoResizeChannel, x, y, width, height);
- }
- #endif
- }
- /* ENDCENTRY */