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