Imported Upstream version 1.15.1
[deb_xorg-server.git] / glx / single2swap.c
CommitLineData
a09e091a
JB
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
41int
42__glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
43{
44 GLsizei size;
45 GLenum type;
46
47 __GLX_DECLARE_SWAP_VARIABLES;
48 __GLXcontext *cx;
49 int error;
50
51 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
52 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
53 if (!cx) {
54 return error;
55 }
56
57 pc += __GLX_SINGLE_HDR_SIZE;
58 __GLX_SWAP_INT(pc + 0);
59 __GLX_SWAP_INT(pc + 4);
60 size = *(GLsizei *) (pc + 0);
61 type = *(GLenum *) (pc + 4);
62 if (cx->feedbackBufSize < size) {
63 cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf,
64 (size_t) size
65 * __GLX_SIZE_FLOAT32);
66 if (!cx->feedbackBuf) {
67 cl->client->errorValue = size;
68 return BadAlloc;
69 }
70 cx->feedbackBufSize = size;
71 }
72 glFeedbackBuffer(size, type, cx->feedbackBuf);
73 cx->hasUnflushedCommands = GL_TRUE;
74 return Success;
75}
76
77int
78__glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
79{
80 __GLXcontext *cx;
81 GLsizei size;
82
83 __GLX_DECLARE_SWAP_VARIABLES;
84 int error;
85
86 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
87 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
88 if (!cx) {
89 return error;
90 }
91
92 pc += __GLX_SINGLE_HDR_SIZE;
93 __GLX_SWAP_INT(pc + 0);
94 size = *(GLsizei *) (pc + 0);
95 if (cx->selectBufSize < size) {
96 cx->selectBuf = (GLuint *) realloc(cx->selectBuf,
97 (size_t) size * __GLX_SIZE_CARD32);
98 if (!cx->selectBuf) {
99 cl->client->errorValue = size;
100 return BadAlloc;
101 }
102 cx->selectBufSize = size;
103 }
104 glSelectBuffer(size, cx->selectBuf);
105 cx->hasUnflushedCommands = GL_TRUE;
106 return Success;
107}
108
109int
110__glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
111{
112 ClientPtr client;
113 __GLXcontext *cx;
114 xGLXRenderModeReply reply;
115 GLint nitems = 0, retBytes = 0, retval, newModeCheck;
116 GLubyte *retBuffer = NULL;
117 GLenum newMode;
118
119 __GLX_DECLARE_SWAP_VARIABLES;
120 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
121 int error;
122
123 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
124 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
125 if (!cx) {
126 return error;
127 }
128
129 pc += __GLX_SINGLE_HDR_SIZE;
130 __GLX_SWAP_INT(pc);
131 newMode = *(GLenum *) pc;
132 retval = glRenderMode(newMode);
133
134 /* Check that render mode worked */
135 glGetIntegerv(GL_RENDER_MODE, &newModeCheck);
136 if (newModeCheck != newMode) {
137 /* Render mode change failed. Bail */
138 newMode = newModeCheck;
139 goto noChangeAllowed;
140 }
141
142 /*
143 ** Render mode might have still failed if we get here. But in this
144 ** case we can't really tell, nor does it matter. If it did fail, it
145 ** will return 0, and thus we won't send any data across the wire.
146 */
147
148 switch (cx->renderMode) {
149 case GL_RENDER:
150 cx->renderMode = newMode;
151 break;
152 case GL_FEEDBACK:
153 if (retval < 0) {
154 /* Overflow happened. Copy the entire buffer */
155 nitems = cx->feedbackBufSize;
156 }
157 else {
158 nitems = retval;
159 }
160 retBytes = nitems * __GLX_SIZE_FLOAT32;
161 retBuffer = (GLubyte *) cx->feedbackBuf;
162 __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems);
163 cx->renderMode = newMode;
164 break;
165 case GL_SELECT:
166 if (retval < 0) {
167 /* Overflow happened. Copy the entire buffer */
168 nitems = cx->selectBufSize;
169 }
170 else {
171 GLuint *bp = cx->selectBuf;
172 GLint i;
173
174 /*
175 ** Figure out how many bytes of data need to be sent. Parse
176 ** the selection buffer to determine this fact as the
177 ** return value is the number of hits, not the number of
178 ** items in the buffer.
179 */
180 nitems = 0;
181 i = retval;
182 while (--i >= 0) {
183 GLuint n;
184
185 /* Parse select data for this hit */
186 n = *bp;
187 bp += 3 + n;
188 }
189 nitems = bp - cx->selectBuf;
190 }
191 retBytes = nitems * __GLX_SIZE_CARD32;
192 retBuffer = (GLubyte *) cx->selectBuf;
193 __GLX_SWAP_INT_ARRAY((GLbyte *) retBuffer, nitems);
194 cx->renderMode = newMode;
195 break;
196 }
197
198 /*
199 ** First reply is the number of elements returned in the feedback or
200 ** selection array, as per the API for glRenderMode itself.
201 */
202 noChangeAllowed:;
203 client = cl->client;
204 reply = (xGLXRenderModeReply) {
205 .type = X_Reply,
206 .sequenceNumber = client->sequence,
207 .length = nitems,
208 .retval = retval,
209 .size = nitems,
210 .newMode = newMode
211 };
212 __GLX_SWAP_SHORT(&reply.sequenceNumber);
213 __GLX_SWAP_INT(&reply.length);
214 __GLX_SWAP_INT(&reply.retval);
215 __GLX_SWAP_INT(&reply.size);
216 __GLX_SWAP_INT(&reply.newMode);
217 WriteToClient(client, sz_xGLXRenderModeReply, &reply);
218 if (retBytes) {
219 WriteToClient(client, retBytes, retBuffer);
220 }
221 return Success;
222}
223
224int
225__glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
226{
227 __GLXcontext *cx;
228 int error;
229
230 __GLX_DECLARE_SWAP_VARIABLES;
231
232 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
233 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
234 if (!cx) {
235 return error;
236 }
237
238 glFlush();
239 cx->hasUnflushedCommands = GL_FALSE;
240 return Success;
241}
242
243int
244__glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
245{
246 __GLXcontext *cx;
247 ClientPtr client;
248 int error;
249
250 __GLX_DECLARE_SWAP_VARIABLES;
251
252 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
253 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
254 if (!cx) {
255 return error;
256 }
257
258 /* Do a local glFinish */
259 glFinish();
260 cx->hasUnflushedCommands = GL_FALSE;
261
262 /* Send empty reply packet to indicate finish is finished */
263 client = cl->client;
264 __GLX_BEGIN_REPLY(0);
265 __GLX_PUT_RETVAL(0);
266 __GLX_SWAP_REPLY_HEADER();
267 __GLX_SEND_HEADER();
268
269 return Success;
270}
271
272int
273__glXDispSwap_GetString(__GLXclientState * cl, GLbyte * pc)
274{
275 return DoGetString(cl, pc, GL_TRUE);
276}