Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / dmx / glxProxy / glxscreens.c
CommitLineData
a09e091a
JB
1/*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31#ifdef HAVE_DMX_CONFIG_H
32#include <dmx-config.h>
33#endif
34
35#include "dmx.h"
36#include "dmxlog.h"
37
38#include "glxserver.h"
39
40#include <windowstr.h>
41
42#include "glxfbconfig.h"
43
44#ifdef PANORAMIX
45#include "panoramiXsrv.h"
46#endif
47
48__GLXscreenInfo *__glXActiveScreens;
49GLint __glXNumActiveScreens;
50
51__GLXFBConfig **__glXFBConfigs;
52int __glXNumFBConfigs;
53
54static char GLXServerVendorName[] = "SGI DMX/glxProxy";
55static char GLXServerVersion[64];
56static char GLXServerExtensions[] =
57 "GLX_EXT_visual_info "
58 "GLX_EXT_visual_rating "
59 "GLX_EXT_import_context "
60 "GLX_SGIX_fbconfig " "GLX_SGI_make_current_read " "GLX_SGI_swap_control ";
61
62static char ExtensionsString[1024];
63
64static void
65CalcServerVersionAndExtensions(void)
66{
67 int s;
68 xGLXQueryVersionReq *req;
69 xGLXQueryVersionReply reply;
70 char **be_extensions;
71 char *ext;
72 char *denied_extensions;
73
74 /*
75 * set the server glx version to be the minimum version
76 * supported by all back-end servers
77 */
78 __glXVersionMajor = 0;
79 __glXVersionMinor = 0;
80 for (s = 0; s < __glXNumActiveScreens; s++) {
81 DMXScreenInfo *dmxScreen = &dmxScreens[s];
82 Display *dpy = dmxScreen->beDisplay;
83
84 /* Send the glXQueryVersion request */
85 LockDisplay(dpy);
86 GetReq(GLXQueryVersion, req);
87 req->reqType = dmxScreen->glxMajorOpcode;
88 req->glxCode = X_GLXQueryVersion;
89 req->majorVersion = GLX_SERVER_MAJOR_VERSION;
90 req->minorVersion = GLX_SERVER_MINOR_VERSION;
91 _XReply(dpy, (xReply *) &reply, 0, False);
92 UnlockDisplay(dpy);
93 SyncHandle();
94
95 if (s == 0) {
96 __glXVersionMajor = reply.majorVersion;
97 __glXVersionMinor = reply.minorVersion;
98 }
99 else {
100 if (reply.majorVersion < __glXVersionMajor) {
101 __glXVersionMajor = reply.majorVersion;
102 __glXVersionMinor = reply.minorVersion;
103 }
104 else if ((reply.majorVersion == __glXVersionMajor) &&
105 (reply.minorVersion < __glXVersionMinor)) {
106 __glXVersionMinor = reply.minorVersion;
107 }
108 }
109
110 }
111
112 if (GLX_SERVER_MAJOR_VERSION < __glXVersionMajor) {
113 __glXVersionMajor = GLX_SERVER_MAJOR_VERSION;
114 __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
115 }
116 else if ((GLX_SERVER_MAJOR_VERSION == __glXVersionMajor) &&
117 (GLX_SERVER_MINOR_VERSION < __glXVersionMinor)) {
118 __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
119 }
120
121 snprintf(GLXServerVersion, sizeof(GLXServerVersion),
122 "%d.%d DMX %d back-end server(s)",
123 __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens);
124 /*
125 * set the ExtensionsString to the minimum extensions string
126 */
127 ExtensionsString[0] = '\0';
128
129 /*
130 * read extensions strings of all back-end servers
131 */
132 be_extensions = (char **) malloc(__glXNumActiveScreens * sizeof(char *));
133 if (!be_extensions)
134 return;
135
136 for (s = 0; s < __glXNumActiveScreens; s++) {
137 DMXScreenInfo *dmxScreen = &dmxScreens[s];
138 Display *dpy = dmxScreen->beDisplay;
139 xGLXQueryServerStringReq *req;
140 xGLXQueryServerStringReply reply;
141 int length, numbytes;
142
143 /* Send the glXQueryServerString request */
144 LockDisplay(dpy);
145 GetReq(GLXQueryServerString, req);
146 req->reqType = dmxScreen->glxMajorOpcode;
147 req->glxCode = X_GLXQueryServerString;
148 req->screen = DefaultScreen(dpy);
149 req->name = GLX_EXTENSIONS;
150 _XReply(dpy, (xReply *) &reply, 0, False);
151
152 length = (int) reply.length;
153 numbytes = (int) reply.n;
154 be_extensions[s] = (char *) malloc(numbytes);
155 if (!be_extensions[s]) {
156 /* Throw data on the floor */
157 _XEatDataWords(dpy, length);
158 }
159 else {
160 _XReadPad(dpy, (char *) be_extensions[s], numbytes);
161 }
162 UnlockDisplay(dpy);
163 SyncHandle();
164 }
165
166 /*
167 * extensions string will include only extensions that our
168 * server supports as well as all back-end servers supports.
169 * extensions that are in the DMX_DENY_EXTENSIONS string will
170 * not be supported.
171 */
172 denied_extensions = getenv("DMX_DENY_GLX_EXTENSIONS");
173 ext = strtok(GLXServerExtensions, " ");
174 while (ext) {
175 int supported = 1;
176
177 if (denied_extensions && strstr(denied_extensions, ext)) {
178 supported = 0;
179 }
180 else {
181 for (s = 0; s < __glXNumActiveScreens && supported; s++) {
182 if (!strstr(be_extensions[s], ext)) {
183 supported = 0;
184 }
185 }
186 }
187
188 if (supported) {
189 strcat(ExtensionsString, ext);
190 strcat(ExtensionsString, " ");
191 }
192
193 ext = strtok(NULL, " ");
194 }
195
196 /*
197 * release temporary storage
198 */
199 for (s = 0; s < __glXNumActiveScreens; s++) {
200 free(be_extensions[s]);
201 }
202 free(be_extensions);
203
204 if (dmxGLXSwapGroupSupport) {
205 if (!denied_extensions ||
206 !strstr(denied_extensions, "GLX_SGIX_swap_group")) {
207 strcat(ExtensionsString, "GLX_SGIX_swap_group");
208 if (!denied_extensions ||
209 !strstr(denied_extensions, "GLX_SGIX_swap_barrier")) {
210 strcat(ExtensionsString, " GLX_SGIX_swap_barrier");
211 }
212 }
213 }
214
215}
216
217void
218__glXScreenInit(GLint numscreens)
219{
220 int s;
221 int c;
222 DMXScreenInfo *dmxScreen0 = &dmxScreens[0];
223
224 __glXNumActiveScreens = numscreens;
225
226 CalcServerVersionAndExtensions();
227
228 __glXFBConfigs = NULL;
229 __glXNumFBConfigs = 0;
230
231 if ((__glXVersionMajor == 1 && __glXVersionMinor >= 3) ||
232 (__glXVersionMajor > 1) ||
233 (strstr(ExtensionsString, "GLX_SGIX_fbconfig"))) {
234
235 /*
236 // Initialize FBConfig info.
237 // find the set of FBConfigs that are present on all back-end
238 // servers - only those configs will be supported
239 */
240 __glXFBConfigs = (__GLXFBConfig **) malloc(dmxScreen0->numFBConfigs *
241 (numscreens +
242 1) *
243 sizeof(__GLXFBConfig *));
244 __glXNumFBConfigs = 0;
245
246 for (c = 0; c < dmxScreen0->numFBConfigs; c++) {
247 __GLXFBConfig *cfg = NULL;
248
249 if (numscreens > 1) {
250 for (s = 1; s < numscreens; s++) {
251 DMXScreenInfo *dmxScreen = &dmxScreens[s];
252
253 cfg = FindMatchingFBConfig(&dmxScreen0->fbconfigs[c],
254 dmxScreen->fbconfigs,
255 dmxScreen->numFBConfigs);
256 __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + s +
257 1] = cfg;
258 if (!cfg) {
259 dmxLog(dmxInfo,
260 "screen0 FBConfig 0x%x is missing on screen#%d\n",
261 dmxScreen0->fbconfigs[c].id, s);
262 break;
263 }
264 else {
265 dmxLog(dmxInfo,
266 "screen0 FBConfig 0x%x matched to 0x%x on screen#%d\n",
267 dmxScreen0->fbconfigs[c].id, cfg->id, s);
268 }
269 }
270 }
271 else {
272 cfg = &dmxScreen0->fbconfigs[c];
273 }
274
275 if (cfg) {
276
277 /* filter out overlay visuals */
278 if (cfg->level == 0) {
279 __GLXFBConfig *proxy_cfg;
280
281 __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + 1] =
282 &dmxScreen0->fbconfigs[c];
283
284 proxy_cfg = malloc(sizeof(__GLXFBConfig));
285 memcpy(proxy_cfg, cfg, sizeof(__GLXFBConfig));
286 proxy_cfg->id = FakeClientID(0);
287 /* visual will be associated later in __glXGetFBConfigs */
288 proxy_cfg->associatedVisualId = (unsigned int) -1;
289
290 __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + 0] =
291 proxy_cfg;
292
293 __glXNumFBConfigs++;
294 }
295
296 }
297
298 }
299
300 }
301
302}
303
304void
305__glXScreenReset(void)
306{
307 __glXNumActiveScreens = 0;
308}
309
310char *
311__glXGetServerString(unsigned int name)
312{
313 char *ret = NULL;
314
315 switch (name) {
316
317 case GLX_VENDOR:
318 ret = GLXServerVendorName;
319 break;
320
321 case GLX_VERSION:
322 ret = GLXServerVersion;
323 break;
324
325 case GLX_EXTENSIONS:
326 ret = ExtensionsString;
327 break;
328
329 default:
330 break;
331 }
332
333 return ret;
334
335}
336
337int
338glxIsExtensionSupported(char *ext)
339{
340 return (strstr(ExtensionsString, ext) != NULL);
341}