changed coding style
[mesa.git] / src / glut / beos / 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 #if !defined(_WIN32) && !defined(__BEOS__)
11 #include <GL/glx.h>
12 #endif
13
14 #ifdef __sgi
15 #include <dlfcn.h>
16 #endif
17
18 #include "glutint.h"
19
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
25 #endif
26
27 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
28 static int canVideoResize = -1;
29 static int videoResizeChannel;
30 #else
31 static int canVideoResize = 0;
32 #endif
33 static int videoResizeInUse = 0;
34 static int dx = -1, dy = -1, dw = -1, dh = -1;
35
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
39 over a network). */
40
41 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
42
43 static volatile int errorCaught;
44
45 /* ARGSUSED */
46 static
47 catchXSGIvcErrors(Display * dpy, XErrorEvent * event)
48 {
49 errorCaught = 1;
50 return 0;
51 }
52 #endif
53
54 /* CENTRY */
55 int APIENTRY
56 glutVideoResizeGet(GLenum param)
57 {
58 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
59 if (canVideoResize < 0) {
60 canVideoResize = __glutIsSupportedByGLX("GLX_SGIX_video_resize");
61 if (canVideoResize) {
62 #if __sgi
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
69 feature. */
70 void (*func) (void);
71 void *glxDso = dlopen("libGL.so", RTLD_LAZY);
72
73 func = (void (*)(void)) dlsym(glxDso, "glXQueryChannelDeltasSGIX");
74 if (!func) {
75 canVideoResize = 0;
76 } else
77 #endif
78 {
79 char *channelString;
80 int (*handler) (Display *, XErrorEvent *);
81
82 channelString = getenv("GLUT_VIDEO_RESIZE_CHANNEL");
83 videoResizeChannel = channelString ? atoi(channelString) : 0;
84
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);
94
95 errorCaught = 0;
96
97 glXQueryChannelDeltasSGIX(__glutDisplay, __glutScreen,
98 videoResizeChannel, &dx, &dy, &dw, &dh);
99
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);
104
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
109 sense. */
110 if (errorCaught ||
111 dx < 0 || dy < 0 || dw < 0 || dh < 0 ||
112 dx > 2048 || dy > 2048 || dw > 2048 || dh > 2048) {
113 canVideoResize = 0;
114 }
115 }
116 }
117 }
118 #endif /* GLX_SGIX_video_resize */
119
120 switch (param) {
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:
126 return dx;
127 case GLUT_VIDEO_RESIZE_Y_DELTA:
128 return dy;
129 case GLUT_VIDEO_RESIZE_WIDTH_DELTA:
130 return dw;
131 case GLUT_VIDEO_RESIZE_HEIGHT_DELTA:
132 return dh;
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;
140
141 glXQueryChannelRectSGIX(__glutDisplay, __glutScreen,
142 videoResizeChannel, &x, &y, &width, &height);
143 switch (param) {
144 case GLUT_VIDEO_RESIZE_X:
145 return x;
146 case GLUT_VIDEO_RESIZE_Y:
147 return y;
148 case GLUT_VIDEO_RESIZE_WIDTH:
149 return width;
150 case GLUT_VIDEO_RESIZE_HEIGHT:
151 return height;
152 }
153 }
154 #endif
155 return -1;
156 default:
157 __glutWarning("invalid glutVideoResizeGet parameter: %d", param);
158 return -1;
159 }
160 }
161
162 void APIENTRY
163 glutSetupVideoResizing(void)
164 {
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;
170 } else
171 #endif
172 __glutFatalError("glutEstablishVideoResizing: video resizing not possible.\n");
173 }
174
175 void APIENTRY
176 glutStopVideoResizing(void)
177 {
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;
184 }
185 }
186 #endif
187 }
188
189 /* ARGSUSED */
190 void APIENTRY
191 glutVideoResize(int x, int y, int width, int height)
192 {
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);
201 #endif
202 glXChannelRectSGIX(__glutDisplay, __glutScreen,
203 videoResizeChannel, x, y, width, height);
204 }
205 #endif
206 }
207
208 /* ARGSUSED */
209 void APIENTRY
210 glutVideoPan(int x, int y, int width, int height)
211 {
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);
223 #endif
224 glXChannelRectSGIX(__glutDisplay, __glutScreen,
225 videoResizeChannel, x, y, width, height);
226 }
227 #endif
228 }
229
230 /* ENDCENTRY */