mesa: include mtypes.h
[mesa.git] / src / glut / os2 / glut_vidresize.cpp
1
2 /* Copyright (c) Mark J. Kilgard, 1996. */
3
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. */
7
8 #include <stdlib.h>
9
10 #ifdef __sgi
11 #include <dlfcn.h>
12 #endif
13
14 #include "glutint.h"
15
16 /* Grumble. The IRIX 6.3 and early IRIX 6.4 OpenGL headers
17 support the video resize extension, but failed to define
18 GLX_SGIX_video_resize. */
19 #if 0
20 #ifdef GLX_SYNC_FRAME_SGIX
21 #define GLX_SGIX_video_resize 1
22 #endif
23 #endif
24
25 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
26 static int canVideoResize = -1;
27 static int videoResizeChannel;
28 #else
29 static int canVideoResize = 0;
30 #endif
31 static int videoResizeInUse = 0;
32 static int dx = -1, dy = -1, dw = -1, dh = -1;
33
34 /* XXX Note that IRIX 6.2, 6.3, and some 6.4 versions have a
35 bug where programs seg-fault when they attempt video
36 resizing from an indirect OpenGL context (either local or
37 over a network). */
38
39 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
40
41 static volatile int errorCaught;
42
43 /* ARGSUSED */
44 static int
45 catchXSGIvcErrors(Display * dpy, XErrorEvent * event)
46 {
47 errorCaught = 1;
48 return 0;
49 }
50 #endif
51
52 /* CENTRY */
53
54 int GLUTAPIENTRY
55 glutVideoResizeGet(GLenum param)
56 {
57 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
58 if (canVideoResize < 0) {
59 canVideoResize = __glutIsSupportedByGLX("GLX_SGIX_video_resize");
60 if (canVideoResize) {
61 #if defined(__sgi) && __sgi
62 /* This is a hack because IRIX 6.2, 6.3, and some 6.4
63 versions were released with GLX_SGIX_video_resize
64 being advertised by the X server though the video
65 resize extension is not actually supported. We try to
66 determine if the libGL.so we are using actually has a
67 video resize entrypoint before we try to use the
68 feature. */
69 void (*func) (void);
70 void *glxDso = dlopen("libGL.so", RTLD_LAZY);
71
72 func = (void (*)(void)) dlsym(glxDso, "glXQueryChannelDeltasSGIX");
73 if (!func) {
74 canVideoResize = 0;
75 } else
76 #endif
77 {
78 char *channelString;
79 int (*handler) (Display *, XErrorEvent *);
80
81 channelString = getenv("GLUT_VIDEO_RESIZE_CHANNEL");
82 videoResizeChannel = channelString ? atoi(channelString) : 0;
83
84 /* Work around another annoying problem with SGI's
85 GLX_SGIX_video_resize implementation. Early IRIX
86 6.4 OpenGL's advertise the extension and have the
87 video resize API, but an XSGIvc X protocol errors
88 result trying to use the API. Set up an error
89 handler to intercept what would otherwise be a fatal
90 error. If an error was recieved, do not report that
91 video resize is possible. */
92 handler = XSetErrorHandler(catchXSGIvcErrors);
93
94 errorCaught = 0;
95
96 #if defined(GLX_GLXEXT_PROTOTYPES)
97 #endif
98
99 __glut_glXQueryChannelDeltasSGIX(__glutDisplay, __glutScreen,
100 videoResizeChannel, &dx, &dy, &dw, &dh);
101
102 /* glXQueryChannelDeltasSGIX is an inherent X server
103 round-trip so we know we will have gotten either the
104 correct reply or and error by this time. */
105 XSetErrorHandler(handler);
106
107 /* Still yet another work around. In IRIX 6.4 betas,
108 glXQueryChannelDeltasSGIX will return as if it
109 succeeded, but the values are filled with junk.
110 Watch to make sure the delta variables really make
111 sense. */
112 if (errorCaught ||
113 dx < 0 || dy < 0 || dw < 0 || dh < 0 ||
114 dx > 2048 || dy > 2048 || dw > 2048 || dh > 2048) {
115 canVideoResize = 0;
116 }
117 }
118 }
119 }
120 #endif /* GLX_SGIX_video_resize */
121
122 switch (param) {
123 case GLUT_VIDEO_RESIZE_POSSIBLE:
124 return canVideoResize;
125 case GLUT_VIDEO_RESIZE_IN_USE:
126 return videoResizeInUse;
127 case GLUT_VIDEO_RESIZE_X_DELTA:
128 return dx;
129 case GLUT_VIDEO_RESIZE_Y_DELTA:
130 return dy;
131 case GLUT_VIDEO_RESIZE_WIDTH_DELTA:
132 return dw;
133 case GLUT_VIDEO_RESIZE_HEIGHT_DELTA:
134 return dh;
135 case GLUT_VIDEO_RESIZE_X:
136 case GLUT_VIDEO_RESIZE_Y:
137 case GLUT_VIDEO_RESIZE_WIDTH:
138 case GLUT_VIDEO_RESIZE_HEIGHT:
139 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
140 if (videoResizeInUse) {
141 int x, y, width, height;
142
143 __glut_glXQueryChannelRectSGIX(__glutDisplay, __glutScreen,
144 videoResizeChannel, &x, &y, &width, &height);
145 switch (param) {
146 case GLUT_VIDEO_RESIZE_X:
147 return x;
148 case GLUT_VIDEO_RESIZE_Y:
149 return y;
150 case GLUT_VIDEO_RESIZE_WIDTH:
151 return width;
152 case GLUT_VIDEO_RESIZE_HEIGHT:
153 return height;
154 }
155 }
156 #endif
157 return -1;
158 default:
159 __glutWarning("invalid glutVideoResizeGet parameter: %d", param);
160 return -1;
161 }
162 }
163
164 void GLUTAPIENTRY
165 glutSetupVideoResizing(void)
166 {
167 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
168 if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
169 __glut_glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
170 videoResizeChannel, __glutCurrentWindow->win);
171 videoResizeInUse = 1;
172 } else
173 #endif
174 __glutFatalError("glutEstablishVideoResizing: video resizing not possible.\n");
175 }
176
177 void GLUTAPIENTRY
178 glutStopVideoResizing(void)
179 {
180 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
181 if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
182 if (videoResizeInUse) {
183 __glut_glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
184 videoResizeChannel, None);
185 videoResizeInUse = 0;
186 }
187 }
188 #endif
189 }
190
191 /* ARGSUSED */
192 void GLUTAPIENTRY
193 glutVideoResize(int x, int y, int width, int height)
194 {
195 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
196 if (videoResizeInUse) {
197 #ifdef GLX_SYNC_SWAP_SGIX
198 /* glXChannelRectSyncSGIX introduced in a patch to IRIX
199 6.2; the original unpatched IRIX 6.2 behavior is always
200 GLX_SYNC_SWAP_SGIX. */
201 __glut_glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
202 videoResizeChannel, GLX_SYNC_SWAP_SGIX);
203 #endif
204 __glut_glXChannelRectSGIX(__glutDisplay, __glutScreen,
205 videoResizeChannel, x, y, width, height);
206 }
207 #endif
208 }
209
210 /* ARGSUSED */
211 void GLUTAPIENTRY
212 glutVideoPan(int x, int y, int width, int height)
213 {
214 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
215 if (videoResizeInUse) {
216 #ifdef GLX_SYNC_FRAME_SGIX
217 /* glXChannelRectSyncSGIX introduced in a patch to IRIX
218 6.2; the original unpatched IRIX 6.2 behavior is always
219 GLX_SYNC_SWAP_SGIX. We just ignore that we cannot
220 accomplish GLX_SYNC_FRAME_SGIX on IRIX unpatched 6.2;
221 this means you'd need a glutSwapBuffers to actually
222 realize the video resize. */
223 __glut_glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
224 videoResizeChannel, GLX_SYNC_FRAME_SGIX);
225 #endif
226 __glut_glXChannelRectSGIX(__glutDisplay, __glutScreen,
227 videoResizeChannel, x, y, width, height);
228 }
229 #endif
230 }
231
232 /* ENDCENTRY */