mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-24 21:28:10 +02:00
232 lines
7.1 KiB
C++
232 lines
7.1 KiB
C++
|
|
/* 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>
|
|
|
|
#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. */
|
|
#if 0
|
|
#ifdef GLX_SYNC_FRAME_SGIX
|
|
#define GLX_SGIX_video_resize 1
|
|
#endif
|
|
#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 int
|
|
catchXSGIvcErrors(Display * dpy, XErrorEvent * event)
|
|
{
|
|
errorCaught = 1;
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/* CENTRY */
|
|
|
|
int GLUTAPIENTRY
|
|
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 defined(__sgi) && __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;
|
|
|
|
#if defined(GLX_GLXEXT_PROTOTYPES)
|
|
#endif
|
|
|
|
__glut_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;
|
|
|
|
__glut_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 GLUTAPIENTRY
|
|
glutSetupVideoResizing(void)
|
|
{
|
|
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
|
if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
|
|
__glut_glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
|
|
videoResizeChannel, __glutCurrentWindow->win);
|
|
videoResizeInUse = 1;
|
|
} else
|
|
#endif
|
|
__glutFatalError("glutEstablishVideoResizing: video resizing not possible.\n");
|
|
}
|
|
|
|
void GLUTAPIENTRY
|
|
glutStopVideoResizing(void)
|
|
{
|
|
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
|
if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
|
|
if (videoResizeInUse) {
|
|
__glut_glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
|
|
videoResizeChannel, None);
|
|
videoResizeInUse = 0;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
void GLUTAPIENTRY
|
|
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. */
|
|
__glut_glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
|
|
videoResizeChannel, GLX_SYNC_SWAP_SGIX);
|
|
#endif
|
|
__glut_glXChannelRectSGIX(__glutDisplay, __glutScreen,
|
|
videoResizeChannel, x, y, width, height);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
void GLUTAPIENTRY
|
|
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. */
|
|
__glut_glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
|
|
videoResizeChannel, GLX_SYNC_FRAME_SGIX);
|
|
#endif
|
|
__glut_glXChannelRectSGIX(__glutDisplay, __glutScreen,
|
|
videoResizeChannel, x, y, width, height);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* ENDCENTRY */
|