2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
37 #ifdef HAVE_DIX_CONFIG_H
38 #include <dix-config.h>
45 #include "glxserver.h"
48 #include "indirect_dispatch.h"
50 #include "glapitable.h"
55 int __glXDisp_FeedbackBuffer(__GLXclientState
*cl
, GLbyte
*pc
)
62 cx
= __glXForceCurrent(cl
, __GLX_GET_SINGLE_CONTEXT_TAG(pc
), &error
);
67 pc
+= __GLX_SINGLE_HDR_SIZE
;
68 size
= *(GLsizei
*)(pc
+0);
69 type
= *(GLenum
*)(pc
+4);
70 if (cx
->feedbackBufSize
< size
) {
71 cx
->feedbackBuf
= (GLfloat
*) xrealloc(cx
->feedbackBuf
,
73 * __GLX_SIZE_FLOAT32
);
74 if (!cx
->feedbackBuf
) {
75 cl
->client
->errorValue
= size
;
78 cx
->feedbackBufSize
= size
;
80 CALL_FeedbackBuffer( GET_DISPATCH(), (size
, type
, cx
->feedbackBuf
) );
81 __GLX_NOTE_UNFLUSHED_CMDS(cx
);
85 int __glXDisp_SelectBuffer(__GLXclientState
*cl
, GLbyte
*pc
)
91 cx
= __glXForceCurrent(cl
, __GLX_GET_SINGLE_CONTEXT_TAG(pc
), &error
);
96 pc
+= __GLX_SINGLE_HDR_SIZE
;
97 size
= *(GLsizei
*)(pc
+0);
98 if (cx
->selectBufSize
< size
) {
99 cx
->selectBuf
= (GLuint
*) xrealloc(cx
->selectBuf
,
101 * __GLX_SIZE_CARD32
);
102 if (!cx
->selectBuf
) {
103 cl
->client
->errorValue
= size
;
106 cx
->selectBufSize
= size
;
108 CALL_SelectBuffer( GET_DISPATCH(), (size
, cx
->selectBuf
) );
109 __GLX_NOTE_UNFLUSHED_CMDS(cx
);
113 int __glXDisp_RenderMode(__GLXclientState
*cl
, GLbyte
*pc
)
116 xGLXRenderModeReply reply
;
118 GLint nitems
=0, retBytes
=0, retval
, newModeCheck
;
119 GLubyte
*retBuffer
= NULL
;
123 cx
= __glXForceCurrent(cl
, __GLX_GET_SINGLE_CONTEXT_TAG(pc
), &error
);
128 pc
+= __GLX_SINGLE_HDR_SIZE
;
129 newMode
= *(GLenum
*) pc
;
130 retval
= CALL_RenderMode( GET_DISPATCH(), (newMode
) );
132 /* Check that render mode worked */
133 CALL_GetIntegerv( GET_DISPATCH(), (GL_RENDER_MODE
, &newModeCheck
) );
134 if (newModeCheck
!= newMode
) {
135 /* Render mode change failed. Bail */
136 newMode
= newModeCheck
;
137 goto noChangeAllowed
;
141 ** Render mode might have still failed if we get here. But in this
142 ** case we can't really tell, nor does it matter. If it did fail, it
143 ** will return 0, and thus we won't send any data across the wire.
146 switch (cx
->renderMode
) {
148 cx
->renderMode
= newMode
;
152 /* Overflow happened. Copy the entire buffer */
153 nitems
= cx
->feedbackBufSize
;
157 retBytes
= nitems
* __GLX_SIZE_FLOAT32
;
158 retBuffer
= (GLubyte
*) cx
->feedbackBuf
;
159 cx
->renderMode
= newMode
;
163 /* Overflow happened. Copy the entire buffer */
164 nitems
= cx
->selectBufSize
;
166 GLuint
*bp
= cx
->selectBuf
;
170 ** Figure out how many bytes of data need to be sent. Parse
171 ** the selection buffer to determine this fact as the
172 ** return value is the number of hits, not the number of
173 ** items in the buffer.
180 /* Parse select data for this hit */
184 nitems
= bp
- cx
->selectBuf
;
186 retBytes
= nitems
* __GLX_SIZE_CARD32
;
187 retBuffer
= (GLubyte
*) cx
->selectBuf
;
188 cx
->renderMode
= newMode
;
193 ** First reply is the number of elements returned in the feedback or
194 ** selection array, as per the API for glRenderMode itself.
198 reply
.length
= nitems
;
199 reply
.type
= X_Reply
;
200 reply
.sequenceNumber
= client
->sequence
;
201 reply
.retval
= retval
;
203 reply
.newMode
= newMode
;
204 WriteToClient(client
, sz_xGLXRenderModeReply
, (char *)&reply
);
206 WriteToClient(client
, retBytes
, (char *)retBuffer
);
211 int __glXDisp_Flush(__GLXclientState
*cl
, GLbyte
*pc
)
216 cx
= __glXForceCurrent(cl
, __GLX_GET_SINGLE_CONTEXT_TAG(pc
), &error
);
221 CALL_Flush( GET_DISPATCH(), () );
222 __GLX_NOTE_FLUSHED_CMDS(cx
);
226 int __glXDisp_Finish(__GLXclientState
*cl
, GLbyte
*pc
)
232 cx
= __glXForceCurrent(cl
, __GLX_GET_SINGLE_CONTEXT_TAG(pc
), &error
);
237 /* Do a local glFinish */
238 CALL_Finish( GET_DISPATCH(), () );
239 __GLX_NOTE_FLUSHED_CMDS(cx
);
241 /* Send empty reply packet to indicate finish is finished */
243 __GLX_BEGIN_REPLY(0);
248 #define SEPARATOR " "
250 char *__glXcombine_strings(const char *cext_string
, const char *sext_string
)
253 char *combo_string
, *token
, *s1
;
254 const char *s2
, *end
;
256 /* safeguard to prevent potentially fatal errors in the string functions */
263 ** String can't be longer than min(cstring, sstring)
264 ** pull tokens out of shortest string
265 ** include space in combo_string for final separator and null terminator
267 clen
= strlen(cext_string
);
268 slen
= strlen(sext_string
);
270 combo_string
= (char *) xalloc(slen
+ 2);
271 s1
= (char *) xalloc(slen
+ 2);
272 if (s1
) strcpy(s1
, sext_string
);
275 combo_string
= (char *) xalloc(clen
+ 2);
276 s1
= (char *) xalloc(clen
+ 2);
277 if (s1
) strcpy(s1
, cext_string
);
280 if (!combo_string
|| !s1
) {
287 combo_string
[0] = '\0';
289 /* Get first extension token */
290 token
= strtok( s1
, SEPARATOR
);
291 while ( token
!= NULL
) {
294 ** if token in second string then save it
295 ** beware of extension names which are prefixes of other extension names
300 size_t n
= strcspn(p
, SEPARATOR
);
301 if ((strlen(token
) == n
) && (strncmp(token
, p
, n
) == 0)) {
302 combo_string
= strcat(combo_string
, token
);
303 combo_string
= strcat(combo_string
, SEPARATOR
);
308 /* Get next extension token */
309 token
= strtok( NULL
, SEPARATOR
);
315 int DoGetString(__GLXclientState
*cl
, GLbyte
*pc
, GLboolean need_swap
)
321 __GLX_DECLARE_SWAP_VARIABLES
;
323 char *buf
= NULL
, *buf1
= NULL
;
326 /* If the client has the opposite byte order, swap the contextTag and
330 __GLX_SWAP_INT(pc
+ 4);
331 __GLX_SWAP_INT(pc
+ __GLX_SINGLE_HDR_SIZE
);
334 cx
= __glXForceCurrent(cl
, __GLX_GET_SINGLE_CONTEXT_TAG(pc
), &error
);
339 pc
+= __GLX_SINGLE_HDR_SIZE
;
340 name
= *(GLenum
*)(pc
+ 0);
341 string
= (const char *) CALL_GetString( GET_DISPATCH(), (name
) );
345 ** Restrict extensions to those that are supported by both the
346 ** implementation and the connection. That is, return the
347 ** intersection of client, server, and core extension strings.
349 if (name
== GL_EXTENSIONS
) {
350 buf1
= __glXcombine_strings(string
,
351 cl
->GLClientextensions
);
352 buf
= __glXcombine_strings(buf1
,
353 cx
->pGlxScreen
->GLextensions
);
359 else if ( name
== GL_VERSION
) {
360 if ( atof( string
) > atof( GLServerVersion
) ) {
361 buf
= xalloc( strlen( string
) + strlen( GLServerVersion
) + 4 );
363 string
= GLServerVersion
;
366 sprintf( buf
, "%s (%s)", GLServerVersion
, string
);
372 length
= strlen((const char *) string
) + 1;
375 __GLX_BEGIN_REPLY(length
);
376 __GLX_PUT_SIZE(length
);
379 __GLX_SWAP_REPLY_SIZE();
380 __GLX_SWAP_REPLY_HEADER();
384 WriteToClient(client
, length
, (char *) string
);
391 int __glXDisp_GetString(__GLXclientState
*cl
, GLbyte
*pc
)
393 return DoGetString(cl
, pc
, GL_FALSE
);