xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

vndext.c (8944B)


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