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