14642e01fSmrg/*
24642e01fSmrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
34642e01fSmrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
44642e01fSmrg *
54642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
64642e01fSmrg * copy of this software and associated documentation files (the "Software"),
74642e01fSmrg * to deal in the Software without restriction, including without limitation
84642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
94642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the
104642e01fSmrg * Software is furnished to do so, subject to the following conditions:
114642e01fSmrg *
124642e01fSmrg * The above copyright notice including the dates of first publication and
134642e01fSmrg * either this permission notice or a reference to
144642e01fSmrg * http://oss.sgi.com/projects/FreeB/
154642e01fSmrg * shall be included in all copies or substantial portions of the Software.
164642e01fSmrg *
174642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
184642e01fSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
194642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
204642e01fSmrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
214642e01fSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
224642e01fSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
234642e01fSmrg * SOFTWARE.
244642e01fSmrg *
254642e01fSmrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
264642e01fSmrg * shall not be used in advertising or otherwise to promote the sale, use or
274642e01fSmrg * other dealings in this Software without prior written authorization from
284642e01fSmrg * Silicon Graphics, Inc.
294642e01fSmrg */
304642e01fSmrg
314642e01fSmrg#ifdef HAVE_DIX_CONFIG_H
324642e01fSmrg#include <dix-config.h>
334642e01fSmrg#endif
344642e01fSmrg
354642e01fSmrg#include "glxserver.h"
364642e01fSmrg#include "glxutil.h"
374642e01fSmrg#include "glxext.h"
384642e01fSmrg#include "indirect_dispatch.h"
394642e01fSmrg#include "unpack.h"
404642e01fSmrg
41f7df2e56Smrgint
42f7df2e56Smrg__glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
434642e01fSmrg{
440b0d8713Smrg    ClientPtr client = cl->client;
454642e01fSmrg    GLsizei size;
464642e01fSmrg    GLenum type;
47f7df2e56Smrg
484642e01fSmrg    __GLX_DECLARE_SWAP_VARIABLES;
494642e01fSmrg    __GLXcontext *cx;
504642e01fSmrg    int error;
514642e01fSmrg
520b0d8713Smrg    REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
530b0d8713Smrg
54f7df2e56Smrg    __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
554642e01fSmrg    cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
564642e01fSmrg    if (!cx) {
57f7df2e56Smrg        return error;
584642e01fSmrg    }
594642e01fSmrg
604642e01fSmrg    pc += __GLX_SINGLE_HDR_SIZE;
61f7df2e56Smrg    __GLX_SWAP_INT(pc + 0);
62f7df2e56Smrg    __GLX_SWAP_INT(pc + 4);
63f7df2e56Smrg    size = *(GLsizei *) (pc + 0);
64f7df2e56Smrg    type = *(GLenum *) (pc + 4);
654642e01fSmrg    if (cx->feedbackBufSize < size) {
66f7df2e56Smrg        cx->feedbackBuf = reallocarray(cx->feedbackBuf,
67f7df2e56Smrg                                       (size_t) size, __GLX_SIZE_FLOAT32);
68f7df2e56Smrg        if (!cx->feedbackBuf) {
69f7df2e56Smrg            cl->client->errorValue = size;
70f7df2e56Smrg            return BadAlloc;
71f7df2e56Smrg        }
72f7df2e56Smrg        cx->feedbackBufSize = size;
734642e01fSmrg    }
74f7df2e56Smrg    glFeedbackBuffer(size, type, cx->feedbackBuf);
754642e01fSmrg    return Success;
764642e01fSmrg}
774642e01fSmrg
78f7df2e56Smrgint
79f7df2e56Smrg__glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
804642e01fSmrg{
810b0d8713Smrg    ClientPtr client = cl->client;
824642e01fSmrg    __GLXcontext *cx;
834642e01fSmrg    GLsizei size;
84f7df2e56Smrg
854642e01fSmrg    __GLX_DECLARE_SWAP_VARIABLES;
864642e01fSmrg    int error;
874642e01fSmrg
880b0d8713Smrg    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
890b0d8713Smrg
90f7df2e56Smrg    __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
914642e01fSmrg    cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
924642e01fSmrg    if (!cx) {
93f7df2e56Smrg        return error;
944642e01fSmrg    }
954642e01fSmrg
964642e01fSmrg    pc += __GLX_SINGLE_HDR_SIZE;
97f7df2e56Smrg    __GLX_SWAP_INT(pc + 0);
98f7df2e56Smrg    size = *(GLsizei *) (pc + 0);
994642e01fSmrg    if (cx->selectBufSize < size) {
100f7df2e56Smrg        cx->selectBuf = reallocarray(cx->selectBuf,
101f7df2e56Smrg                                     (size_t) size, __GLX_SIZE_CARD32);
102f7df2e56Smrg        if (!cx->selectBuf) {
103f7df2e56Smrg            cl->client->errorValue = size;
104f7df2e56Smrg            return BadAlloc;
105f7df2e56Smrg        }
106f7df2e56Smrg        cx->selectBufSize = size;
1074642e01fSmrg    }
108f7df2e56Smrg    glSelectBuffer(size, cx->selectBuf);
1094642e01fSmrg    return Success;
1104642e01fSmrg}
1114642e01fSmrg
112f7df2e56Smrgint
113f7df2e56Smrg__glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
1144642e01fSmrg{
1150b0d8713Smrg    ClientPtr client = cl->client;
1164642e01fSmrg    __GLXcontext *cx;
1174642e01fSmrg    xGLXRenderModeReply reply;
118f7df2e56Smrg    GLint nitems = 0, retBytes = 0, retval, newModeCheck;
1194642e01fSmrg    GLubyte *retBuffer = NULL;
1204642e01fSmrg    GLenum newMode;
121f7df2e56Smrg
1224642e01fSmrg    __GLX_DECLARE_SWAP_VARIABLES;
1234642e01fSmrg    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
1244642e01fSmrg    int error;
1254642e01fSmrg
1260b0d8713Smrg    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
1270b0d8713Smrg
128f7df2e56Smrg    __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
1294642e01fSmrg    cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
1304642e01fSmrg    if (!cx) {
131f7df2e56Smrg        return error;
1324642e01fSmrg    }
1334642e01fSmrg
1344642e01fSmrg    pc += __GLX_SINGLE_HDR_SIZE;
1354642e01fSmrg    __GLX_SWAP_INT(pc);
136f7df2e56Smrg    newMode = *(GLenum *) pc;
137f7df2e56Smrg    retval = glRenderMode(newMode);
1384642e01fSmrg
1394642e01fSmrg    /* Check that render mode worked */
140f7df2e56Smrg    glGetIntegerv(GL_RENDER_MODE, &newModeCheck);
1414642e01fSmrg    if (newModeCheck != newMode) {
142f7df2e56Smrg        /* Render mode change failed.  Bail */
143f7df2e56Smrg        newMode = newModeCheck;
144f7df2e56Smrg        goto noChangeAllowed;
1454642e01fSmrg    }
1464642e01fSmrg
1474642e01fSmrg    /*
148f7df2e56Smrg     ** Render mode might have still failed if we get here.  But in this
149f7df2e56Smrg     ** case we can't really tell, nor does it matter.  If it did fail, it
150f7df2e56Smrg     ** will return 0, and thus we won't send any data across the wire.
151f7df2e56Smrg     */
1524642e01fSmrg
1534642e01fSmrg    switch (cx->renderMode) {
154f7df2e56Smrg    case GL_RENDER:
155f7df2e56Smrg        cx->renderMode = newMode;
156f7df2e56Smrg        break;
157f7df2e56Smrg    case GL_FEEDBACK:
158f7df2e56Smrg        if (retval < 0) {
159f7df2e56Smrg            /* Overflow happened. Copy the entire buffer */
160f7df2e56Smrg            nitems = cx->feedbackBufSize;
161f7df2e56Smrg        }
162f7df2e56Smrg        else {
163f7df2e56Smrg            nitems = retval;
164f7df2e56Smrg        }
165f7df2e56Smrg        retBytes = nitems * __GLX_SIZE_FLOAT32;
166f7df2e56Smrg        retBuffer = (GLubyte *) cx->feedbackBuf;
167f7df2e56Smrg        __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems);
168f7df2e56Smrg        cx->renderMode = newMode;
169f7df2e56Smrg        break;
170f7df2e56Smrg    case GL_SELECT:
171f7df2e56Smrg        if (retval < 0) {
172f7df2e56Smrg            /* Overflow happened.  Copy the entire buffer */
173f7df2e56Smrg            nitems = cx->selectBufSize;
174f7df2e56Smrg        }
175f7df2e56Smrg        else {
176f7df2e56Smrg            GLuint *bp = cx->selectBuf;
177f7df2e56Smrg            GLint i;
178f7df2e56Smrg
179f7df2e56Smrg            /*
180f7df2e56Smrg             ** Figure out how many bytes of data need to be sent.  Parse
181f7df2e56Smrg             ** the selection buffer to determine this fact as the
182f7df2e56Smrg             ** return value is the number of hits, not the number of
183f7df2e56Smrg             ** items in the buffer.
184f7df2e56Smrg             */
185f7df2e56Smrg            nitems = 0;
186f7df2e56Smrg            i = retval;
187f7df2e56Smrg            while (--i >= 0) {
188f7df2e56Smrg                GLuint n;
189f7df2e56Smrg
190f7df2e56Smrg                /* Parse select data for this hit */
191f7df2e56Smrg                n = *bp;
192f7df2e56Smrg                bp += 3 + n;
193f7df2e56Smrg            }
194f7df2e56Smrg            nitems = bp - cx->selectBuf;
195f7df2e56Smrg        }
196f7df2e56Smrg        retBytes = nitems * __GLX_SIZE_CARD32;
197f7df2e56Smrg        retBuffer = (GLubyte *) cx->selectBuf;
198f7df2e56Smrg        __GLX_SWAP_INT_ARRAY((GLbyte *) retBuffer, nitems);
199f7df2e56Smrg        cx->renderMode = newMode;
200f7df2e56Smrg        break;
2014642e01fSmrg    }
2024642e01fSmrg
2034642e01fSmrg    /*
204f7df2e56Smrg     ** First reply is the number of elements returned in the feedback or
205f7df2e56Smrg     ** selection array, as per the API for glRenderMode itself.
206f7df2e56Smrg     */
207f7df2e56Smrg noChangeAllowed:;
208f7df2e56Smrg    reply = (xGLXRenderModeReply) {
209f7df2e56Smrg        .type = X_Reply,
210f7df2e56Smrg        .sequenceNumber = client->sequence,
211f7df2e56Smrg        .length = nitems,
212f7df2e56Smrg        .retval = retval,
213f7df2e56Smrg        .size = nitems,
214f7df2e56Smrg        .newMode = newMode
215f7df2e56Smrg    };
2164642e01fSmrg    __GLX_SWAP_SHORT(&reply.sequenceNumber);
2174642e01fSmrg    __GLX_SWAP_INT(&reply.length);
2184642e01fSmrg    __GLX_SWAP_INT(&reply.retval);
2194642e01fSmrg    __GLX_SWAP_INT(&reply.size);
2204642e01fSmrg    __GLX_SWAP_INT(&reply.newMode);
221f7df2e56Smrg    WriteToClient(client, sz_xGLXRenderModeReply, &reply);
2224642e01fSmrg    if (retBytes) {
223f7df2e56Smrg        WriteToClient(client, retBytes, retBuffer);
2244642e01fSmrg    }
2254642e01fSmrg    return Success;
2264642e01fSmrg}
2274642e01fSmrg
228f7df2e56Smrgint
229f7df2e56Smrg__glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
2304642e01fSmrg{
231f7df2e56Smrg    ClientPtr client = cl->client;
232f7df2e56Smrg    __GLXcontext *cx;
233f7df2e56Smrg    int error;
234f7df2e56Smrg
235f7df2e56Smrg    __GLX_DECLARE_SWAP_VARIABLES;
236f7df2e56Smrg
237f7df2e56Smrg    REQUEST_SIZE_MATCH(xGLXSingleReq);
238f7df2e56Smrg
239f7df2e56Smrg    __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
240f7df2e56Smrg    cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
241f7df2e56Smrg    if (!cx) {
242f7df2e56Smrg        return error;
243f7df2e56Smrg    }
244f7df2e56Smrg
245f7df2e56Smrg    glFlush();
246f7df2e56Smrg    return Success;
2474642e01fSmrg}
2484642e01fSmrg
249f7df2e56Smrgint
250f7df2e56Smrg__glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
2514642e01fSmrg{
2520b0d8713Smrg    ClientPtr client = cl->client;
2534642e01fSmrg    __GLXcontext *cx;
2544642e01fSmrg    int error;
2557e31ba66Smrg    xGLXSingleReply reply = { 0, };
256f7df2e56Smrg
2574642e01fSmrg    __GLX_DECLARE_SWAP_VARIABLES;
2584642e01fSmrg
2590b0d8713Smrg    REQUEST_SIZE_MATCH(xGLXSingleReq);
2600b0d8713Smrg
261f7df2e56Smrg    __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
2624642e01fSmrg    cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
2634642e01fSmrg    if (!cx) {
264f7df2e56Smrg        return error;
2654642e01fSmrg    }
2664642e01fSmrg
2674642e01fSmrg    /* Do a local glFinish */
268f7df2e56Smrg    glFinish();
2694642e01fSmrg
2704642e01fSmrg    /* Send empty reply packet to indicate finish is finished */
2714642e01fSmrg    __GLX_BEGIN_REPLY(0);
2724642e01fSmrg    __GLX_PUT_RETVAL(0);
2734642e01fSmrg    __GLX_SWAP_REPLY_HEADER();
2744642e01fSmrg    __GLX_SEND_HEADER();
2754642e01fSmrg
2764642e01fSmrg    return Success;
2774642e01fSmrg}
2784642e01fSmrg
279f7df2e56Smrgint
280f7df2e56Smrg__glXDispSwap_GetString(__GLXclientState * cl, GLbyte * pc)
2814642e01fSmrg{
2824642e01fSmrg    return DoGetString(cl, pc, GL_TRUE);
2834642e01fSmrg}
284