1 /*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
33 #endif
34
35 #include "glxserver.h"
36 #include "glxutil.h"
37 #include "glxext.h"
38 #include "indirect_dispatch.h"
39 #include "unpack.h"
40
41 int
__glXDispSwap_FeedbackBuffer(__GLXclientState * cl,GLbyte * pc)42 __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
43 {
44 ClientPtr client = cl->client;
45 GLsizei size;
46 GLenum type;
47
48 __GLX_DECLARE_SWAP_VARIABLES;
49 __GLXcontext *cx;
50 int error;
51
52 REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
53
54 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
55 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
56 if (!cx) {
57 return error;
58 }
59
60 pc += __GLX_SINGLE_HDR_SIZE;
61 __GLX_SWAP_INT(pc + 0);
62 __GLX_SWAP_INT(pc + 4);
63 size = *(GLsizei *) (pc + 0);
64 type = *(GLenum *) (pc + 4);
65 if (cx->feedbackBufSize < size) {
66 cx->feedbackBuf = reallocarray(cx->feedbackBuf,
67 (size_t) size, __GLX_SIZE_FLOAT32);
68 if (!cx->feedbackBuf) {
69 cl->client->errorValue = size;
70 return BadAlloc;
71 }
72 cx->feedbackBufSize = size;
73 }
74 glFeedbackBuffer(size, type, cx->feedbackBuf);
75 return Success;
76 }
77
78 int
__glXDispSwap_SelectBuffer(__GLXclientState * cl,GLbyte * pc)79 __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
80 {
81 ClientPtr client = cl->client;
82 __GLXcontext *cx;
83 GLsizei size;
84
85 __GLX_DECLARE_SWAP_VARIABLES;
86 int error;
87
88 REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
89
90 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
91 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
92 if (!cx) {
93 return error;
94 }
95
96 pc += __GLX_SINGLE_HDR_SIZE;
97 __GLX_SWAP_INT(pc + 0);
98 size = *(GLsizei *) (pc + 0);
99 if (cx->selectBufSize < size) {
100 cx->selectBuf = reallocarray(cx->selectBuf,
101 (size_t) size, __GLX_SIZE_CARD32);
102 if (!cx->selectBuf) {
103 cl->client->errorValue = size;
104 return BadAlloc;
105 }
106 cx->selectBufSize = size;
107 }
108 glSelectBuffer(size, cx->selectBuf);
109 return Success;
110 }
111
112 int
__glXDispSwap_RenderMode(__GLXclientState * cl,GLbyte * pc)113 __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
114 {
115 ClientPtr client = cl->client;
116 __GLXcontext *cx;
117 xGLXRenderModeReply reply;
118 GLint nitems = 0, retBytes = 0, retval, newModeCheck;
119 GLubyte *retBuffer = NULL;
120 GLenum newMode;
121
122 __GLX_DECLARE_SWAP_VARIABLES;
123 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
124 int error;
125
126 REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
127
128 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
129 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
130 if (!cx) {
131 return error;
132 }
133
134 pc += __GLX_SINGLE_HDR_SIZE;
135 __GLX_SWAP_INT(pc);
136 newMode = *(GLenum *) pc;
137 retval = glRenderMode(newMode);
138
139 /* Check that render mode worked */
140 glGetIntegerv(GL_RENDER_MODE, &newModeCheck);
141 if (newModeCheck != newMode) {
142 /* Render mode change failed. Bail */
143 newMode = newModeCheck;
144 goto noChangeAllowed;
145 }
146
147 /*
148 ** Render mode might have still failed if we get here. But in this
149 ** case we can't really tell, nor does it matter. If it did fail, it
150 ** will return 0, and thus we won't send any data across the wire.
151 */
152
153 switch (cx->renderMode) {
154 case GL_RENDER:
155 cx->renderMode = newMode;
156 break;
157 case GL_FEEDBACK:
158 if (retval < 0) {
159 /* Overflow happened. Copy the entire buffer */
160 nitems = cx->feedbackBufSize;
161 }
162 else {
163 nitems = retval;
164 }
165 retBytes = nitems * __GLX_SIZE_FLOAT32;
166 retBuffer = (GLubyte *) cx->feedbackBuf;
167 __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems);
168 cx->renderMode = newMode;
169 break;
170 case GL_SELECT:
171 if (retval < 0) {
172 /* Overflow happened. Copy the entire buffer */
173 nitems = cx->selectBufSize;
174 }
175 else {
176 GLuint *bp = cx->selectBuf;
177 GLint i;
178
179 /*
180 ** Figure out how many bytes of data need to be sent. Parse
181 ** the selection buffer to determine this fact as the
182 ** return value is the number of hits, not the number of
183 ** items in the buffer.
184 */
185 nitems = 0;
186 i = retval;
187 while (--i >= 0) {
188 GLuint n;
189
190 /* Parse select data for this hit */
191 n = *bp;
192 bp += 3 + n;
193 }
194 nitems = bp - cx->selectBuf;
195 }
196 retBytes = nitems * __GLX_SIZE_CARD32;
197 retBuffer = (GLubyte *) cx->selectBuf;
198 __GLX_SWAP_INT_ARRAY((GLbyte *) retBuffer, nitems);
199 cx->renderMode = newMode;
200 break;
201 }
202
203 /*
204 ** First reply is the number of elements returned in the feedback or
205 ** selection array, as per the API for glRenderMode itself.
206 */
207 noChangeAllowed:;
208 reply = (xGLXRenderModeReply) {
209 .type = X_Reply,
210 .sequenceNumber = client->sequence,
211 .length = nitems,
212 .retval = retval,
213 .size = nitems,
214 .newMode = newMode
215 };
216 __GLX_SWAP_SHORT(&reply.sequenceNumber);
217 __GLX_SWAP_INT(&reply.length);
218 __GLX_SWAP_INT(&reply.retval);
219 __GLX_SWAP_INT(&reply.size);
220 __GLX_SWAP_INT(&reply.newMode);
221 WriteToClient(client, sz_xGLXRenderModeReply, &reply);
222 if (retBytes) {
223 WriteToClient(client, retBytes, retBuffer);
224 }
225 return Success;
226 }
227
228 int
__glXDispSwap_Flush(__GLXclientState * cl,GLbyte * pc)229 __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
230 {
231 ClientPtr client = cl->client;
232 __GLXcontext *cx;
233 int error;
234
235 __GLX_DECLARE_SWAP_VARIABLES;
236
237 REQUEST_SIZE_MATCH(xGLXSingleReq);
238
239 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
240 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
241 if (!cx) {
242 return error;
243 }
244
245 glFlush();
246 return Success;
247 }
248
249 int
__glXDispSwap_Finish(__GLXclientState * cl,GLbyte * pc)250 __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
251 {
252 ClientPtr client = cl->client;
253 __GLXcontext *cx;
254 int error;
255 xGLXSingleReply reply = { 0, };
256
257 __GLX_DECLARE_SWAP_VARIABLES;
258
259 REQUEST_SIZE_MATCH(xGLXSingleReq);
260
261 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
262 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
263 if (!cx) {
264 return error;
265 }
266
267 /* Do a local glFinish */
268 glFinish();
269
270 /* Send empty reply packet to indicate finish is finished */
271 __GLX_BEGIN_REPLY(0);
272 __GLX_PUT_RETVAL(0);
273 __GLX_SWAP_REPLY_HEADER();
274 __GLX_SEND_HEADER();
275
276 return Success;
277 }
278
279 int
__glXDispSwap_GetString(__GLXclientState * cl,GLbyte * pc)280 __glXDispSwap_GetString(__GLXclientState * cl, GLbyte * pc)
281 {
282 return DoGetString(cl, pc, GL_TRUE);
283 }
284