xref: /OK3568_Linux_fs/external/xserver/hw/dmx/glxProxy/glxscreens.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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