2 * Copyright 1994-1997 Mark Kilgard, All rights reserved.
3 * Distributed under the terms of the MIT License.
13 #if !defined(_WIN32) && !(defined(__BEOS__) || defined(__HAIKU__))
23 /* Grumble. The IRIX 6.3 and early IRIX 6.4 OpenGL headers
24 support the video resize extension, but failed to define
25 GLX_SGIX_video_resize. */
26 #ifdef GLX_SYNC_FRAME_SGIX
27 #define GLX_SGIX_video_resize 1
30 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
31 static int canVideoResize
= -1;
32 static int videoResizeChannel
;
34 static int canVideoResize
= 0;
36 static int videoResizeInUse
= 0;
37 static int dx
= -1, dy
= -1, dw
= -1, dh
= -1;
39 /* XXX Note that IRIX 6.2, 6.3, and some 6.4 versions have a
40 bug where programs seg-fault when they attempt video
41 resizing from an indirect OpenGL context (either local or
44 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
46 static volatile int errorCaught
;
50 catchXSGIvcErrors(Display
* dpy
, XErrorEvent
* event
)
59 glutVideoResizeGet(GLenum param
)
61 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
62 if (canVideoResize
< 0) {
63 canVideoResize
= __glutIsSupportedByGLX("GLX_SGIX_video_resize");
66 /* This is a hack because IRIX 6.2, 6.3, and some 6.4
67 versions were released with GLX_SGIX_video_resize
68 being advertised by the X server though the video
69 resize extension is not actually supported. We try to
70 determine if the libGL.so we are using actually has a
71 video resize entrypoint before we try to use the
74 void *glxDso
= dlopen("libGL.so", RTLD_LAZY
);
76 func
= (void (*)(void)) dlsym(glxDso
, "glXQueryChannelDeltasSGIX");
83 int (*handler
) (Display
*, XErrorEvent
*);
85 channelString
= getenv("GLUT_VIDEO_RESIZE_CHANNEL");
86 videoResizeChannel
= channelString
? atoi(channelString
) : 0;
88 /* Work around another annoying problem with SGI's
89 GLX_SGIX_video_resize implementation. Early IRIX
90 6.4 OpenGL's advertise the extension and have the
91 video resize API, but an XSGIvc X protocol errors
92 result trying to use the API. Set up an error
93 handler to intercept what would otherwise be a fatal
94 error. If an error was recieved, do not report that
95 video resize is possible. */
96 handler
= XSetErrorHandler(catchXSGIvcErrors
);
100 glXQueryChannelDeltasSGIX(__glutDisplay
, __glutScreen
,
101 videoResizeChannel
, &dx
, &dy
, &dw
, &dh
);
103 /* glXQueryChannelDeltasSGIX is an inherent X server
104 round-trip so we know we will have gotten either the
105 correct reply or and error by this time. */
106 XSetErrorHandler(handler
);
108 /* Still yet another work around. In IRIX 6.4 betas,
109 glXQueryChannelDeltasSGIX will return as if it
110 succeeded, but the values are filled with junk.
111 Watch to make sure the delta variables really make
114 dx
< 0 || dy
< 0 || dw
< 0 || dh
< 0 ||
115 dx
> 2048 || dy
> 2048 || dw
> 2048 || dh
> 2048) {
121 #endif /* GLX_SGIX_video_resize */
124 case GLUT_VIDEO_RESIZE_POSSIBLE
:
125 return canVideoResize
;
126 case GLUT_VIDEO_RESIZE_IN_USE
:
127 return videoResizeInUse
;
128 case GLUT_VIDEO_RESIZE_X_DELTA
:
130 case GLUT_VIDEO_RESIZE_Y_DELTA
:
132 case GLUT_VIDEO_RESIZE_WIDTH_DELTA
:
134 case GLUT_VIDEO_RESIZE_HEIGHT_DELTA
:
136 case GLUT_VIDEO_RESIZE_X
:
137 case GLUT_VIDEO_RESIZE_Y
:
138 case GLUT_VIDEO_RESIZE_WIDTH
:
139 case GLUT_VIDEO_RESIZE_HEIGHT
:
140 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
141 if (videoResizeInUse
) {
142 int x
, y
, width
, height
;
144 glXQueryChannelRectSGIX(__glutDisplay
, __glutScreen
,
145 videoResizeChannel
, &x
, &y
, &width
, &height
);
147 case GLUT_VIDEO_RESIZE_X
:
149 case GLUT_VIDEO_RESIZE_Y
:
151 case GLUT_VIDEO_RESIZE_WIDTH
:
153 case GLUT_VIDEO_RESIZE_HEIGHT
:
160 __glutWarning("invalid glutVideoResizeGet parameter: %d", param
);
166 glutSetupVideoResizing(void)
168 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
169 if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE
)) {
170 glXBindChannelToWindowSGIX(__glutDisplay
, __glutScreen
,
171 videoResizeChannel
, __glutCurrentWindow
->win
);
172 videoResizeInUse
= 1;
175 __glutFatalError("glutEstablishVideoResizing: video resizing not possible.\n");
179 glutStopVideoResizing(void)
181 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
182 if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE
)) {
183 if (videoResizeInUse
) {
184 glXBindChannelToWindowSGIX(__glutDisplay
, __glutScreen
,
185 videoResizeChannel
, None
);
186 videoResizeInUse
= 0;
194 glutVideoResize(int x
, int y
, int width
, int height
)
196 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
197 if (videoResizeInUse
) {
198 #ifdef GLX_SYNC_SWAP_SGIX
199 /* glXChannelRectSyncSGIX introduced in a patch to IRIX
200 6.2; the original unpatched IRIX 6.2 behavior is always
201 GLX_SYNC_SWAP_SGIX. */
202 glXChannelRectSyncSGIX(__glutDisplay
, __glutScreen
,
203 videoResizeChannel
, GLX_SYNC_SWAP_SGIX
);
205 glXChannelRectSGIX(__glutDisplay
, __glutScreen
,
206 videoResizeChannel
, x
, y
, width
, height
);
213 glutVideoPan(int x
, int y
, int width
, int height
)
215 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
216 if (videoResizeInUse
) {
217 #ifdef GLX_SYNC_FRAME_SGIX
218 /* glXChannelRectSyncSGIX introduced in a patch to IRIX
219 6.2; the original unpatched IRIX 6.2 behavior is always
220 GLX_SYNC_SWAP_SGIX. We just ignore that we cannot
221 accomplish GLX_SYNC_FRAME_SGIX on IRIX unpatched 6.2;
222 this means you'd need a glutSwapBuffers to actually
223 realize the video resize. */
224 glXChannelRectSyncSGIX(__glutDisplay
, __glutScreen
,
225 videoResizeChannel
, GLX_SYNC_FRAME_SGIX
);
227 glXChannelRectSGIX(__glutDisplay
, __glutScreen
,
228 videoResizeChannel
, x
, y
, width
, height
);