2 /* Copyright (c) Mark J. Kilgard, 1996. */
4 /* This program is freely distributable without licensing fees
5 and is provided without guarantee or warrantee expressed or
6 implied. This program is -not- in the public domain. */
10 #if !defined(_WIN32) && !defined(__BEOS__)
20 /* Grumble. The IRIX 6.3 and early IRIX 6.4 OpenGL headers
21 support the video resize extension, but failed to define
22 GLX_SGIX_video_resize. */
23 #ifdef GLX_SYNC_FRAME_SGIX
24 #define GLX_SGIX_video_resize 1
27 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
28 static int canVideoResize
= -1;
29 static int videoResizeChannel
;
31 static int canVideoResize
= 0;
33 static int videoResizeInUse
= 0;
34 static int dx
= -1, dy
= -1, dw
= -1, dh
= -1;
36 /* XXX Note that IRIX 6.2, 6.3, and some 6.4 versions have a
37 bug where programs seg-fault when they attempt video
38 resizing from an indirect OpenGL context (either local or
41 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
43 static volatile int errorCaught
;
47 catchXSGIvcErrors(Display
* dpy
, XErrorEvent
* event
)
56 glutVideoResizeGet(GLenum param
)
58 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
59 if (canVideoResize
< 0) {
60 canVideoResize
= __glutIsSupportedByGLX("GLX_SGIX_video_resize");
63 /* This is a hack because IRIX 6.2, 6.3, and some 6.4
64 versions were released with GLX_SGIX_video_resize
65 being advertised by the X server though the video
66 resize extension is not actually supported. We try to
67 determine if the libGL.so we are using actually has a
68 video resize entrypoint before we try to use the
71 void *glxDso
= dlopen("libGL.so", RTLD_LAZY
);
73 func
= (void (*)(void)) dlsym(glxDso
, "glXQueryChannelDeltasSGIX");
80 int (*handler
) (Display
*, XErrorEvent
*);
82 channelString
= getenv("GLUT_VIDEO_RESIZE_CHANNEL");
83 videoResizeChannel
= channelString
? atoi(channelString
) : 0;
85 /* Work around another annoying problem with SGI's
86 GLX_SGIX_video_resize implementation. Early IRIX
87 6.4 OpenGL's advertise the extension and have the
88 video resize API, but an XSGIvc X protocol errors
89 result trying to use the API. Set up an error
90 handler to intercept what would otherwise be a fatal
91 error. If an error was recieved, do not report that
92 video resize is possible. */
93 handler
= XSetErrorHandler(catchXSGIvcErrors
);
97 glXQueryChannelDeltasSGIX(__glutDisplay
, __glutScreen
,
98 videoResizeChannel
, &dx
, &dy
, &dw
, &dh
);
100 /* glXQueryChannelDeltasSGIX is an inherent X server
101 round-trip so we know we will have gotten either the
102 correct reply or and error by this time. */
103 XSetErrorHandler(handler
);
105 /* Still yet another work around. In IRIX 6.4 betas,
106 glXQueryChannelDeltasSGIX will return as if it
107 succeeded, but the values are filled with junk.
108 Watch to make sure the delta variables really make
111 dx
< 0 || dy
< 0 || dw
< 0 || dh
< 0 ||
112 dx
> 2048 || dy
> 2048 || dw
> 2048 || dh
> 2048) {
118 #endif /* GLX_SGIX_video_resize */
121 case GLUT_VIDEO_RESIZE_POSSIBLE
:
122 return canVideoResize
;
123 case GLUT_VIDEO_RESIZE_IN_USE
:
124 return videoResizeInUse
;
125 case GLUT_VIDEO_RESIZE_X_DELTA
:
127 case GLUT_VIDEO_RESIZE_Y_DELTA
:
129 case GLUT_VIDEO_RESIZE_WIDTH_DELTA
:
131 case GLUT_VIDEO_RESIZE_HEIGHT_DELTA
:
133 case GLUT_VIDEO_RESIZE_X
:
134 case GLUT_VIDEO_RESIZE_Y
:
135 case GLUT_VIDEO_RESIZE_WIDTH
:
136 case GLUT_VIDEO_RESIZE_HEIGHT
:
137 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
138 if (videoResizeInUse
) {
139 int x
, y
, width
, height
;
141 glXQueryChannelRectSGIX(__glutDisplay
, __glutScreen
,
142 videoResizeChannel
, &x
, &y
, &width
, &height
);
144 case GLUT_VIDEO_RESIZE_X
:
146 case GLUT_VIDEO_RESIZE_Y
:
148 case GLUT_VIDEO_RESIZE_WIDTH
:
150 case GLUT_VIDEO_RESIZE_HEIGHT
:
157 __glutWarning("invalid glutVideoResizeGet parameter: %d", param
);
163 glutSetupVideoResizing(void)
165 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
166 if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE
)) {
167 glXBindChannelToWindowSGIX(__glutDisplay
, __glutScreen
,
168 videoResizeChannel
, __glutCurrentWindow
->win
);
169 videoResizeInUse
= 1;
172 __glutFatalError("glutEstablishVideoResizing: video resizing not possible.\n");
176 glutStopVideoResizing(void)
178 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
179 if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE
)) {
180 if (videoResizeInUse
) {
181 glXBindChannelToWindowSGIX(__glutDisplay
, __glutScreen
,
182 videoResizeChannel
, None
);
183 videoResizeInUse
= 0;
191 glutVideoResize(int x
, int y
, int width
, int height
)
193 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
194 if (videoResizeInUse
) {
195 #ifdef GLX_SYNC_SWAP_SGIX
196 /* glXChannelRectSyncSGIX introduced in a patch to IRIX
197 6.2; the original unpatched IRIX 6.2 behavior is always
198 GLX_SYNC_SWAP_SGIX. */
199 glXChannelRectSyncSGIX(__glutDisplay
, __glutScreen
,
200 videoResizeChannel
, GLX_SYNC_SWAP_SGIX
);
202 glXChannelRectSGIX(__glutDisplay
, __glutScreen
,
203 videoResizeChannel
, x
, y
, width
, height
);
210 glutVideoPan(int x
, int y
, int width
, int height
)
212 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
213 if (videoResizeInUse
) {
214 #ifdef GLX_SYNC_FRAME_SGIX
215 /* glXChannelRectSyncSGIX introduced in a patch to IRIX
216 6.2; the original unpatched IRIX 6.2 behavior is always
217 GLX_SYNC_SWAP_SGIX. We just ignore that we cannot
218 accomplish GLX_SYNC_FRAME_SGIX on IRIX unpatched 6.2;
219 this means you'd need a glutSwapBuffers to actually
220 realize the video resize. */
221 glXChannelRectSyncSGIX(__glutDisplay
, __glutScreen
,
222 videoResizeChannel
, GLX_SYNC_FRAME_SGIX
);
224 glXChannelRectSGIX(__glutDisplay
, __glutScreen
,
225 videoResizeChannel
, x
, y
, width
, height
);