vndservermapping.c revision 1b5d61b8
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 <pixmapstr.h>
33
34#include "vndservervendor.h"
35
36static GlxServerVendor *LookupXIDMapResource(XID id)
37{
38    void *ptr = NULL;
39    int rv;
40
41    rv = dixLookupResourceByType(&ptr, id, idResource, NULL, DixReadAccess);
42    if (rv == Success) {
43        return (GlxServerVendor *) ptr;
44    } else {
45        return NULL;
46    }
47}
48
49GlxServerVendor *GlxGetXIDMap(XID id)
50{
51    GlxServerVendor *vendor = LookupXIDMapResource(id);
52
53    if (vendor == NULL) {
54        // If we haven't seen this XID before, then it may be a drawable that
55        // wasn't created through GLX, like a regular X window or pixmap. Try
56        // to look up a matching drawable to find a screen number for it.
57        void *ptr = NULL;
58        int rv = dixLookupResourceByClass(&ptr, id, RC_DRAWABLE, NULL,
59                                         DixGetAttrAccess);
60        if (rv == Success && ptr != NULL) {
61            DrawablePtr draw = (DrawablePtr) ptr;
62            GlxScreenPriv *screenPriv = GlxGetScreen(draw->pScreen);
63            if (screenPriv != NULL) {
64                vendor = screenPriv->vendor;
65            }
66        }
67    }
68    return vendor;
69}
70
71Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor)
72{
73    if (id == 0 || vendor == NULL) {
74        return FALSE;
75    }
76    if (LookupXIDMapResource(id) != NULL) {
77        return FALSE;
78    }
79    return AddResource(id, idResource, vendor);
80}
81
82void GlxRemoveXIDMap(XID id)
83{
84    FreeResourceByType(id, idResource, FALSE);
85}
86
87GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor)
88{
89    GlxClientPriv *cl;
90    unsigned int index;
91
92    if (vendor == NULL) {
93        return NULL;
94    }
95
96    cl = GlxGetClientData(client);
97    if (cl == NULL) {
98        return NULL;
99    }
100
101    // Look for a free tag index.
102    for (index=0; index<cl->contextTagCount; index++) {
103        if (cl->contextTags[index].vendor == NULL) {
104            break;
105        }
106    }
107    if (index >= cl->contextTagCount) {
108        // We didn't find a free entry, so grow the array.
109        GlxContextTagInfo *newTags;
110        unsigned int newSize = cl->contextTagCount * 2;
111        if (newSize == 0) {
112            // TODO: What's a good starting size for this?
113            newSize = 16;
114        }
115
116        newTags = (GlxContextTagInfo *)
117            realloc(cl->contextTags, newSize * sizeof(GlxContextTagInfo));
118        if (newTags == NULL) {
119            return NULL;
120        }
121
122        memset(&newTags[cl->contextTagCount], 0,
123                (newSize - cl->contextTagCount) * sizeof(GlxContextTagInfo));
124
125        index = cl->contextTagCount;
126        cl->contextTags = newTags;
127        cl->contextTagCount = newSize;
128    }
129
130    assert(index >= 0);
131    assert(index < cl->contextTagCount);
132    memset(&cl->contextTags[index], 0, sizeof(GlxContextTagInfo));
133    cl->contextTags[index].tag = (GLXContextTag) (index + 1);
134    cl->contextTags[index].client = client;
135    cl->contextTags[index].vendor = vendor;
136    return &cl->contextTags[index];
137}
138
139GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag)
140{
141    GlxClientPriv *cl = GlxGetClientData(client);
142    if (cl == NULL) {
143        return NULL;
144    }
145
146    if (tag > 0 && (tag - 1) < cl->contextTagCount) {
147        if (cl->contextTags[tag - 1].vendor != NULL) {
148            assert(cl->contextTags[tag - 1].client == client);
149            return &cl->contextTags[tag - 1];
150        }
151    }
152    return NULL;
153}
154
155void GlxFreeContextTag(GlxContextTagInfo *tagInfo)
156{
157    if (tagInfo != NULL) {
158        tagInfo->vendor = NULL;
159        tagInfo->vendor = NULL;
160        tagInfo->data = NULL;
161        tagInfo->context = None;
162        tagInfo->drawable = None;
163        tagInfo->readdrawable = None;
164    }
165}
166
167Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor)
168{
169    GlxScreenPriv *priv;
170
171    if (vendor == NULL) {
172        return FALSE;
173    }
174
175    priv = GlxGetScreen(screen);
176    if (priv == NULL) {
177        return FALSE;
178    }
179
180    if (priv->vendor != NULL) {
181        return FALSE;
182    }
183
184    priv->vendor = vendor;
185    return TRUE;
186}
187
188GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen)
189{
190    GlxScreenPriv *priv = GlxGetScreen(screen);
191    if (priv != NULL) {
192        return priv->vendor;
193    } else {
194        return NULL;
195    }
196}
197