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