Merge commit 'origin/gallium-0.1'
[mesa.git] / src / glx / x11 / glx_query.c
1 /*
2 * (C) Copyright IBM Corporation 2004
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file glx_query.c
27 * Generic utility functions to query internal data from the server.
28 *
29 * \author Ian Romanick <idr@us.ibm.com>
30 */
31
32 #include "glxclient.h"
33
34 #if defined(USE_XCB)
35 # include <X11/Xlib-xcb.h>
36 # include <xcb/xcb.h>
37 # include <xcb/glx.h>
38 #endif
39
40 #ifdef USE_XCB
41
42 /**
43 * Exchange a protocol request for glXQueryServerString.
44 */
45 char *
46 __glXQueryServerString(Display* dpy,
47 int opcode,
48 CARD32 screen,
49 CARD32 name)
50 {
51 xcb_connection_t *c = XGetXCBConnection(dpy);
52 xcb_glx_query_server_string_reply_t* reply =
53 xcb_glx_query_server_string_reply(c,
54 xcb_glx_query_server_string(c,
55 screen,
56 name),
57 NULL);
58
59 /* The spec doesn't mention this, but the Xorg server replies with
60 * a string already terminated with '\0'. */
61 uint32_t len = xcb_glx_query_server_string_string_length(reply);
62 char* buf = Xmalloc(len);
63 memcpy(buf, xcb_glx_query_server_string_string(reply), len);
64 free(reply);
65
66 return buf;
67 }
68
69 /**
70 * Exchange a protocol request for glGetString.
71 */
72 char *
73 __glXGetString(Display* dpy,
74 int opcode,
75 CARD32 contextTag,
76 CARD32 name)
77 {
78 xcb_connection_t *c = XGetXCBConnection(dpy);
79 xcb_glx_get_string_reply_t* reply =
80 xcb_glx_get_string_reply(c,
81 xcb_glx_get_string(c,
82 contextTag,
83 name),
84 NULL);
85
86 /* The spec doesn't mention this, but the Xorg server replies with
87 * a string already terminated with '\0'. */
88 uint32_t len = xcb_glx_get_string_string_length(reply);
89 char* buf = Xmalloc(len);
90 memcpy(buf, xcb_glx_get_string_string(reply), len);
91 free(reply);
92
93 return buf;
94 }
95
96 #else
97
98 /**
99 * GLX protocol structure for the ficticious "GXLGenericGetString" request.
100 *
101 * This is a non-existant protocol packet. It just so happens that all of
102 * the real protocol packets used to request a string from the server have
103 * an identical binary layout. The only difference between them is the
104 * meaning of the \c for_whom field and the value of the \c glxCode.
105 */
106 typedef struct GLXGenericGetString
107 {
108 CARD8 reqType;
109 CARD8 glxCode;
110 CARD16 length B16;
111 CARD32 for_whom B32;
112 CARD32 name B32;
113 } xGLXGenericGetStringReq;
114
115 /* These defines are only needed to make the GetReq macro happy.
116 */
117 #define sz_xGLXGenericGetStringReq 12
118 #define X_GLXGenericGetString 0
119
120 /**
121 * Query the Server GLX string.
122 * This routine will allocate the necessay space for the string.
123 */
124 static char *
125 __glXGetStringFromServer(Display * dpy, int opcode, CARD32 glxCode,
126 CARD32 for_whom, CARD32 name)
127 {
128 xGLXGenericGetStringReq *req;
129 xGLXSingleReply reply;
130 int length;
131 int numbytes;
132 char *buf;
133
134
135 LockDisplay(dpy);
136
137
138 /* All of the GLX protocol requests for getting a string from the server
139 * look the same. The exact meaning of the for_whom field is usually
140 * either the screen number (for glXQueryServerString) or the context tag
141 * (for GLXSingle).
142 */
143
144 GetReq(GLXGenericGetString, req);
145 req->reqType = opcode;
146 req->glxCode = glxCode;
147 req->for_whom = for_whom;
148 req->name = name;
149
150 _XReply(dpy, (xReply *) & reply, 0, False);
151
152 length = reply.length * 4;
153 numbytes = reply.size;
154
155 buf = (char *) Xmalloc(numbytes);
156 if (buf != NULL) {
157 _XRead(dpy, buf, numbytes);
158 length -= numbytes;
159 }
160
161 _XEatData(dpy, length);
162
163 UnlockDisplay(dpy);
164 SyncHandle();
165
166 return buf;
167 }
168
169 char *
170 __glXQueryServerString(Display* dpy,
171 int opcode,
172 CARD32 screen,
173 CARD32 name)
174 {
175 return __glXGetStringFromServer(dpy, opcode,
176 X_GLXQueryServerString,
177 screen, name);
178 }
179
180 char *
181 __glXGetString(Display* dpy,
182 int opcode,
183 CARD32 contextTag,
184 CARD32 name)
185 {
186 return __glXGetStringFromServer(dpy, opcode, X_GLsop_GetString,
187 contextTag, name);
188 }
189
190 #endif /* USE_XCB */
191