xref: /OK3568_Linux_fs/external/xserver/glx/vndext.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2016, NVIDIA CORPORATION.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and/or associated documentation files (the
6*4882a593Smuzhiyun  * "Materials"), to deal in the Materials without restriction, including
7*4882a593Smuzhiyun  * without limitation the rights to use, copy, modify, merge, publish,
8*4882a593Smuzhiyun  * distribute, sublicense, and/or sell copies of the Materials, and to
9*4882a593Smuzhiyun  * permit persons to whom the Materials are furnished to do so, subject to
10*4882a593Smuzhiyun  * the following conditions:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included
13*4882a593Smuzhiyun  * unaltered in all copies or substantial portions of the Materials.
14*4882a593Smuzhiyun  * Any additions, deletions, or changes to the original source files
15*4882a593Smuzhiyun  * must be clearly indicated in accompanying documentation.
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * If only executable code is distributed, then the accompanying
18*4882a593Smuzhiyun  * documentation must state that "this software is based in part on the
19*4882a593Smuzhiyun  * work of the Khronos Group."
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22*4882a593Smuzhiyun  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23*4882a593Smuzhiyun  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24*4882a593Smuzhiyun  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25*4882a593Smuzhiyun  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26*4882a593Smuzhiyun  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27*4882a593Smuzhiyun  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
28*4882a593Smuzhiyun  */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include "vndserver.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #include <string.h>
33*4882a593Smuzhiyun #include <scrnintstr.h>
34*4882a593Smuzhiyun #include <windowstr.h>
35*4882a593Smuzhiyun #include <dixstruct.h>
36*4882a593Smuzhiyun #include <extnsionst.h>
37*4882a593Smuzhiyun #include <glx_extinit.h>
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #include <GL/glxproto.h>
40*4882a593Smuzhiyun #include "vndservervendor.h"
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun ExtensionEntry *GlxExtensionEntry;
43*4882a593Smuzhiyun int GlxErrorBase = 0;
44*4882a593Smuzhiyun static CallbackListRec vndInitCallbackList;
45*4882a593Smuzhiyun static CallbackListPtr vndInitCallbackListPtr = &vndInitCallbackList;
46*4882a593Smuzhiyun static DevPrivateKeyRec glvXGLVScreenPrivKey;
47*4882a593Smuzhiyun static DevPrivateKeyRec glvXGLVClientPrivKey;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun // The resource type used to keep track of the vendor library for XID's.
50*4882a593Smuzhiyun RESTYPE idResource;
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun static int
idResourceDeleteCallback(void * value,XID id)53*4882a593Smuzhiyun idResourceDeleteCallback(void *value, XID id)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun     return 0;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun static GlxScreenPriv *
xglvGetScreenPrivate(ScreenPtr pScreen)59*4882a593Smuzhiyun xglvGetScreenPrivate(ScreenPtr pScreen)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun     return dixLookupPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun static void
xglvSetScreenPrivate(ScreenPtr pScreen,void * priv)65*4882a593Smuzhiyun xglvSetScreenPrivate(ScreenPtr pScreen, void *priv)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun     dixSetPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey, priv);
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun GlxScreenPriv *
GlxGetScreen(ScreenPtr pScreen)71*4882a593Smuzhiyun GlxGetScreen(ScreenPtr pScreen)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun     if (pScreen != NULL) {
74*4882a593Smuzhiyun         GlxScreenPriv *priv = xglvGetScreenPrivate(pScreen);
75*4882a593Smuzhiyun         if (priv == NULL) {
76*4882a593Smuzhiyun             priv = calloc(1, sizeof(GlxScreenPriv));
77*4882a593Smuzhiyun             if (priv == NULL) {
78*4882a593Smuzhiyun                 return NULL;
79*4882a593Smuzhiyun             }
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun             xglvSetScreenPrivate(pScreen, priv);
82*4882a593Smuzhiyun         }
83*4882a593Smuzhiyun         return priv;
84*4882a593Smuzhiyun     } else {
85*4882a593Smuzhiyun         return NULL;
86*4882a593Smuzhiyun     }
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun static void
GlxMappingReset(void)90*4882a593Smuzhiyun GlxMappingReset(void)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun     int i;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun     for (i=0; i<screenInfo.numScreens; i++) {
95*4882a593Smuzhiyun         GlxScreenPriv *priv = xglvGetScreenPrivate(screenInfo.screens[i]);
96*4882a593Smuzhiyun         if (priv != NULL) {
97*4882a593Smuzhiyun             xglvSetScreenPrivate(screenInfo.screens[i], NULL);
98*4882a593Smuzhiyun             free(priv);
99*4882a593Smuzhiyun         }
100*4882a593Smuzhiyun     }
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun static Bool
GlxMappingInit(void)104*4882a593Smuzhiyun GlxMappingInit(void)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun     int i;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun     for (i=0; i<screenInfo.numScreens; i++) {
109*4882a593Smuzhiyun         if (GlxGetScreen(screenInfo.screens[i]) == NULL) {
110*4882a593Smuzhiyun             GlxMappingReset();
111*4882a593Smuzhiyun             return FALSE;
112*4882a593Smuzhiyun         }
113*4882a593Smuzhiyun     }
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun     idResource = CreateNewResourceType(idResourceDeleteCallback,
116*4882a593Smuzhiyun                                        "GLXServerIDRes");
117*4882a593Smuzhiyun     if (idResource == RT_NONE)
118*4882a593Smuzhiyun     {
119*4882a593Smuzhiyun         GlxMappingReset();
120*4882a593Smuzhiyun         return FALSE;
121*4882a593Smuzhiyun     }
122*4882a593Smuzhiyun     return TRUE;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun static GlxClientPriv *
xglvGetClientPrivate(ClientPtr pClient)126*4882a593Smuzhiyun xglvGetClientPrivate(ClientPtr pClient)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun     return dixLookupPrivate(&pClient->devPrivates, &glvXGLVClientPrivKey);
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun static void
xglvSetClientPrivate(ClientPtr pClient,void * priv)132*4882a593Smuzhiyun xglvSetClientPrivate(ClientPtr pClient, void *priv)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun     dixSetPrivate(&pClient->devPrivates, &glvXGLVClientPrivKey, priv);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun GlxClientPriv *
GlxGetClientData(ClientPtr client)138*4882a593Smuzhiyun GlxGetClientData(ClientPtr client)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun     GlxClientPriv *cl = xglvGetClientPrivate(client);
141*4882a593Smuzhiyun     if (cl == NULL) {
142*4882a593Smuzhiyun         cl = calloc(1, sizeof(GlxClientPriv)
143*4882a593Smuzhiyun                 + screenInfo.numScreens * sizeof(GlxServerVendor *));
144*4882a593Smuzhiyun         if (cl != NULL) {
145*4882a593Smuzhiyun             int i;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun             cl->vendors = (GlxServerVendor **) (cl + 1);
148*4882a593Smuzhiyun             for (i=0; i<screenInfo.numScreens; i++)
149*4882a593Smuzhiyun             {
150*4882a593Smuzhiyun                 cl->vendors[i] = GlxGetVendorForScreen(NULL, screenInfo.screens[i]);
151*4882a593Smuzhiyun             }
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun             xglvSetClientPrivate(client, cl);
154*4882a593Smuzhiyun         }
155*4882a593Smuzhiyun     }
156*4882a593Smuzhiyun     return cl;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun void
GlxFreeClientData(ClientPtr client)160*4882a593Smuzhiyun GlxFreeClientData(ClientPtr client)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun     GlxClientPriv *cl = xglvGetClientPrivate(client);
163*4882a593Smuzhiyun     if (cl != NULL) {
164*4882a593Smuzhiyun         unsigned int i;
165*4882a593Smuzhiyun         for (i = 0; i < cl->contextTagCount; i++) {
166*4882a593Smuzhiyun             GlxContextTagInfo *tag = &cl->contextTags[i];
167*4882a593Smuzhiyun             if (tag->vendor != NULL) {
168*4882a593Smuzhiyun                 tag->vendor->glxvc.makeCurrent(client, tag->tag,
169*4882a593Smuzhiyun                                                None, None, None, 0);
170*4882a593Smuzhiyun             }
171*4882a593Smuzhiyun         }
172*4882a593Smuzhiyun         xglvSetClientPrivate(client, NULL);
173*4882a593Smuzhiyun         free(cl->contextTags);
174*4882a593Smuzhiyun         free(cl);
175*4882a593Smuzhiyun     }
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun static void
GLXClientCallback(CallbackListPtr * list,void * closure,void * data)179*4882a593Smuzhiyun GLXClientCallback(CallbackListPtr *list, void *closure, void *data)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
182*4882a593Smuzhiyun     ClientPtr client = clientinfo->client;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun     switch (client->clientState)
185*4882a593Smuzhiyun     {
186*4882a593Smuzhiyun         case ClientStateRetained:
187*4882a593Smuzhiyun         case ClientStateGone:
188*4882a593Smuzhiyun             GlxFreeClientData(client);
189*4882a593Smuzhiyun             break;
190*4882a593Smuzhiyun     }
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun static void
GLXReset(ExtensionEntry * extEntry)194*4882a593Smuzhiyun GLXReset(ExtensionEntry *extEntry)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun     // xf86Msg(X_INFO, "GLX: GLXReset\n");
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun     GlxVendorExtensionReset(extEntry);
199*4882a593Smuzhiyun     GlxDispatchReset();
200*4882a593Smuzhiyun     GlxMappingReset();
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun     if ((dispatchException & DE_TERMINATE) == DE_TERMINATE) {
203*4882a593Smuzhiyun         while (vndInitCallbackList.list != NULL) {
204*4882a593Smuzhiyun             CallbackPtr next = vndInitCallbackList.list->next;
205*4882a593Smuzhiyun             free(vndInitCallbackList.list);
206*4882a593Smuzhiyun             vndInitCallbackList.list = next;
207*4882a593Smuzhiyun         }
208*4882a593Smuzhiyun     }
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun void
GlxExtensionInit(void)212*4882a593Smuzhiyun GlxExtensionInit(void)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun     ExtensionEntry *extEntry;
215*4882a593Smuzhiyun     GlxExtensionEntry = NULL;
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun     // Init private keys, per-screen data
218*4882a593Smuzhiyun     if (!dixRegisterPrivateKey(&glvXGLVScreenPrivKey, PRIVATE_SCREEN, 0))
219*4882a593Smuzhiyun         return;
220*4882a593Smuzhiyun     if (!dixRegisterPrivateKey(&glvXGLVClientPrivKey, PRIVATE_CLIENT, 0))
221*4882a593Smuzhiyun         return;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun     if (!GlxMappingInit()) {
224*4882a593Smuzhiyun         return;
225*4882a593Smuzhiyun     }
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun     if (!GlxDispatchInit()) {
228*4882a593Smuzhiyun         return;
229*4882a593Smuzhiyun     }
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun     if (!AddCallback(&ClientStateCallback, GLXClientCallback, NULL)) {
232*4882a593Smuzhiyun         return;
233*4882a593Smuzhiyun     }
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun     extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
236*4882a593Smuzhiyun                             __GLX_NUMBER_ERRORS, GlxDispatchRequest,
237*4882a593Smuzhiyun                             GlxDispatchRequest, GLXReset, StandardMinorOpcode);
238*4882a593Smuzhiyun     if (!extEntry) {
239*4882a593Smuzhiyun         return;
240*4882a593Smuzhiyun     }
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun     GlxExtensionEntry = extEntry;
243*4882a593Smuzhiyun     GlxErrorBase = extEntry->errorBase;
244*4882a593Smuzhiyun     CallCallbacks(&vndInitCallbackListPtr, extEntry);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun     /* We'd better have found at least one vendor */
247*4882a593Smuzhiyun     for (int i = 0; i < screenInfo.numScreens; i++)
248*4882a593Smuzhiyun         if (GlxGetVendorForScreen(serverClient, screenInfo.screens[i]))
249*4882a593Smuzhiyun             return;
250*4882a593Smuzhiyun     extEntry->base = 0;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun static int
GlxForwardRequest(GlxServerVendor * vendor,ClientPtr client)254*4882a593Smuzhiyun GlxForwardRequest(GlxServerVendor *vendor, ClientPtr client)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun     return vendor->glxvc.handleRequest(client);
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun static GlxServerVendor *
GlxGetContextTag(ClientPtr client,GLXContextTag tag)260*4882a593Smuzhiyun GlxGetContextTag(ClientPtr client, GLXContextTag tag)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun     GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag);
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun     if (tagInfo != NULL) {
265*4882a593Smuzhiyun         return tagInfo->vendor;
266*4882a593Smuzhiyun     } else {
267*4882a593Smuzhiyun         return NULL;
268*4882a593Smuzhiyun     }
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun static Bool
GlxSetContextTagPrivate(ClientPtr client,GLXContextTag tag,void * data)272*4882a593Smuzhiyun GlxSetContextTagPrivate(ClientPtr client, GLXContextTag tag, void *data)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun     GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag);
275*4882a593Smuzhiyun     if (tagInfo != NULL) {
276*4882a593Smuzhiyun         tagInfo->data = data;
277*4882a593Smuzhiyun         return TRUE;
278*4882a593Smuzhiyun     } else {
279*4882a593Smuzhiyun         return FALSE;
280*4882a593Smuzhiyun     }
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun static void *
GlxGetContextTagPrivate(ClientPtr client,GLXContextTag tag)284*4882a593Smuzhiyun GlxGetContextTagPrivate(ClientPtr client, GLXContextTag tag)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun     GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag);
287*4882a593Smuzhiyun     if (tagInfo != NULL) {
288*4882a593Smuzhiyun         return tagInfo->data;
289*4882a593Smuzhiyun     } else {
290*4882a593Smuzhiyun         return NULL;
291*4882a593Smuzhiyun     }
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun static GlxServerImports *
GlxAllocateServerImports(void)295*4882a593Smuzhiyun GlxAllocateServerImports(void)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun     return calloc(1, sizeof(GlxServerImports));
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun static void
GlxFreeServerImports(GlxServerImports * imports)301*4882a593Smuzhiyun GlxFreeServerImports(GlxServerImports *imports)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun     free(imports);
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun _X_EXPORT const GlxServerExports glxServer = {
307*4882a593Smuzhiyun     .majorVersion = GLXSERVER_VENDOR_ABI_MAJOR_VERSION,
308*4882a593Smuzhiyun     .minorVersion = GLXSERVER_VENDOR_ABI_MINOR_VERSION,
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun     .extensionInitCallback = &vndInitCallbackListPtr,
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun     .allocateServerImports = GlxAllocateServerImports,
313*4882a593Smuzhiyun     .freeServerImports = GlxFreeServerImports,
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun     .createVendor = GlxCreateVendor,
316*4882a593Smuzhiyun     .destroyVendor = GlxDestroyVendor,
317*4882a593Smuzhiyun     .setScreenVendor = GlxSetScreenVendor,
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun     .addXIDMap = GlxAddXIDMap,
320*4882a593Smuzhiyun     .getXIDMap = GlxGetXIDMap,
321*4882a593Smuzhiyun     .removeXIDMap = GlxRemoveXIDMap,
322*4882a593Smuzhiyun     .getContextTag = GlxGetContextTag,
323*4882a593Smuzhiyun     .setContextTagPrivate = GlxSetContextTagPrivate,
324*4882a593Smuzhiyun     .getContextTagPrivate = GlxGetContextTagPrivate,
325*4882a593Smuzhiyun     .getVendorForScreen = GlxGetVendorForScreen,
326*4882a593Smuzhiyun     .forwardRequest =  GlxForwardRequest,
327*4882a593Smuzhiyun     .setClientScreenVendor = GlxSetClientScreenVendor,
328*4882a593Smuzhiyun };
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun const GlxServerExports *
glvndGetExports(void)331*4882a593Smuzhiyun glvndGetExports(void)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun     return &glxServer;
334*4882a593Smuzhiyun }
335