1848b8605Smrg/*
2848b8605Smrg * Copyright © 2010 Intel Corporation
3848b8605Smrg *
4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5848b8605Smrg * copy of this software and associated documentation files (the "Soft-
6848b8605Smrg * ware"), to deal in the Software without restriction, including without
7848b8605Smrg * limitation the rights to use, copy, modify, merge, publish, distribute,
8848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
9848b8605Smrg * Software is furnished to do so, provided that the above copyright
10848b8605Smrg * notice(s) and this permission notice appear in all copies of the Soft-
11848b8605Smrg * ware and that both the above copyright notice(s) and this permission
12848b8605Smrg * notice appear in supporting documentation.
13848b8605Smrg *
14848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16848b8605Smrg * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17848b8605Smrg * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18848b8605Smrg * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19848b8605Smrg * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20848b8605Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21848b8605Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22848b8605Smrg * MANCE OF THIS SOFTWARE.
23848b8605Smrg *
24848b8605Smrg * Except as contained in this notice, the name of a copyright holder shall
25848b8605Smrg * not be used in advertising or otherwise to promote the sale, use or
26848b8605Smrg * other dealings in this Software without prior written authorization of
27848b8605Smrg * the copyright holder.
28848b8605Smrg *
29848b8605Smrg * Authors:
30848b8605Smrg *   Kristian Høgsberg (krh@bitplanet.net)
31848b8605Smrg */
32848b8605Smrg
33b8e80941Smrg#include <stdbool.h>
34b8e80941Smrg
35848b8605Smrg#include "glapi.h"
36848b8605Smrg#include "glxclient.h"
37848b8605Smrg
38b8e80941Smrg#include "util/debug.h"
39b8e80941Smrg
40848b8605Smrg#ifndef GLX_USE_APPLEGL
41848b8605Smrg
42848b8605Smrgextern struct _glapi_table *__glXNewIndirectAPI(void);
43848b8605Smrg
44848b8605Smrg/*
45848b8605Smrg** All indirect rendering contexts will share the same indirect dispatch table.
46848b8605Smrg*/
47848b8605Smrgstatic struct _glapi_table *IndirectAPI = NULL;
48848b8605Smrg
49848b8605Smrgstatic void
50848b8605Smrgindirect_destroy_context(struct glx_context *gc)
51848b8605Smrg{
52848b8605Smrg   __glXFreeVertexArrayState(gc);
53848b8605Smrg
54848b8605Smrg   free((char *) gc->vendor);
55848b8605Smrg   free((char *) gc->renderer);
56848b8605Smrg   free((char *) gc->version);
57848b8605Smrg   free((char *) gc->extensions);
58848b8605Smrg   __glFreeAttributeState(gc);
59848b8605Smrg   free((char *) gc->buf);
60848b8605Smrg   free((char *) gc->client_state_private);
61848b8605Smrg   free((char *) gc);
62848b8605Smrg}
63848b8605Smrg
64848b8605Smrgstatic Bool
65b8e80941SmrgSendMakeCurrentRequest(Display * dpy, GLXContextID gc_id,
66b8e80941Smrg                       GLXContextTag gc_tag, GLXDrawable draw,
67b8e80941Smrg                       GLXDrawable read, GLXContextTag *out_tag)
68848b8605Smrg{
69848b8605Smrg   xGLXMakeCurrentReply reply;
70848b8605Smrg   Bool ret;
71b8e80941Smrg   int opcode = __glXSetupForCommand(dpy);
72848b8605Smrg
73848b8605Smrg   LockDisplay(dpy);
74848b8605Smrg
75848b8605Smrg   if (draw == read) {
76848b8605Smrg      xGLXMakeCurrentReq *req;
77848b8605Smrg
78848b8605Smrg      GetReq(GLXMakeCurrent, req);
79848b8605Smrg      req->reqType = opcode;
80848b8605Smrg      req->glxCode = X_GLXMakeCurrent;
81848b8605Smrg      req->drawable = draw;
82848b8605Smrg      req->context = gc_id;
83848b8605Smrg      req->oldContextTag = gc_tag;
84848b8605Smrg   }
85848b8605Smrg   else {
86848b8605Smrg      struct glx_display *priv = __glXInitialize(dpy);
87848b8605Smrg
88848b8605Smrg      /* If the server can support the GLX 1.3 version, we should
89848b8605Smrg       * perfer that.  Not only that, some servers support GLX 1.3 but
90848b8605Smrg       * not the SGI extension.
91848b8605Smrg       */
92848b8605Smrg
93848b8605Smrg      if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
94848b8605Smrg         xGLXMakeContextCurrentReq *req;
95848b8605Smrg
96848b8605Smrg         GetReq(GLXMakeContextCurrent, req);
97848b8605Smrg         req->reqType = opcode;
98848b8605Smrg         req->glxCode = X_GLXMakeContextCurrent;
99848b8605Smrg         req->drawable = draw;
100848b8605Smrg         req->readdrawable = read;
101848b8605Smrg         req->context = gc_id;
102848b8605Smrg         req->oldContextTag = gc_tag;
103848b8605Smrg      }
104848b8605Smrg      else {
105848b8605Smrg         xGLXVendorPrivateWithReplyReq *vpreq;
106848b8605Smrg         xGLXMakeCurrentReadSGIReq *req;
107848b8605Smrg
108848b8605Smrg         GetReqExtra(GLXVendorPrivateWithReply,
109848b8605Smrg                     sz_xGLXMakeCurrentReadSGIReq -
110848b8605Smrg                     sz_xGLXVendorPrivateWithReplyReq, vpreq);
111848b8605Smrg         req = (xGLXMakeCurrentReadSGIReq *) vpreq;
112848b8605Smrg         req->reqType = opcode;
113848b8605Smrg         req->glxCode = X_GLXVendorPrivateWithReply;
114848b8605Smrg         req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
115848b8605Smrg         req->drawable = draw;
116848b8605Smrg         req->readable = read;
117848b8605Smrg         req->context = gc_id;
118848b8605Smrg         req->oldContextTag = gc_tag;
119848b8605Smrg      }
120848b8605Smrg   }
121848b8605Smrg
122848b8605Smrg   ret = _XReply(dpy, (xReply *) &reply, 0, False);
123848b8605Smrg
124848b8605Smrg   if (out_tag)
125848b8605Smrg      *out_tag = reply.contextTag;
126848b8605Smrg
127848b8605Smrg   UnlockDisplay(dpy);
128848b8605Smrg   SyncHandle();
129848b8605Smrg
130848b8605Smrg   return ret;
131848b8605Smrg}
132848b8605Smrg
133848b8605Smrgstatic int
134848b8605Smrgindirect_bind_context(struct glx_context *gc, struct glx_context *old,
135848b8605Smrg		      GLXDrawable draw, GLXDrawable read)
136848b8605Smrg{
137848b8605Smrg   GLXContextTag tag;
138848b8605Smrg   Display *dpy = gc->psc->dpy;
139848b8605Smrg   Bool sent;
140848b8605Smrg
141848b8605Smrg   if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) {
142848b8605Smrg      tag = old->currentContextTag;
143848b8605Smrg      old->currentContextTag = 0;
144848b8605Smrg   } else {
145848b8605Smrg      tag = 0;
146848b8605Smrg   }
147848b8605Smrg
148b8e80941Smrg   sent = SendMakeCurrentRequest(dpy, gc->xid, tag, draw, read,
149848b8605Smrg				 &gc->currentContextTag);
150848b8605Smrg
151848b8605Smrg   if (!IndirectAPI)
152848b8605Smrg      IndirectAPI = __glXNewIndirectAPI();
153848b8605Smrg   _glapi_set_dispatch(IndirectAPI);
154848b8605Smrg
155848b8605Smrg   return !sent;
156848b8605Smrg}
157848b8605Smrg
158848b8605Smrgstatic void
159848b8605Smrgindirect_unbind_context(struct glx_context *gc, struct glx_context *new)
160848b8605Smrg{
161848b8605Smrg   Display *dpy = gc->psc->dpy;
162848b8605Smrg
163848b8605Smrg   if (gc == new)
164848b8605Smrg      return;
165848b8605Smrg
166b8e80941Smrg   /* We are either switching to no context, away from an indirect
167848b8605Smrg    * context to a direct context or from one dpy to another and have
168848b8605Smrg    * to send a request to the dpy to unbind the previous context.
169848b8605Smrg    */
170848b8605Smrg   if (!new || new->isDirect || new->psc->dpy != dpy) {
171b8e80941Smrg      SendMakeCurrentRequest(dpy, None, gc->currentContextTag, None, None,
172b8e80941Smrg                             NULL);
173848b8605Smrg      gc->currentContextTag = 0;
174848b8605Smrg   }
175848b8605Smrg}
176848b8605Smrg
177848b8605Smrgstatic void
178848b8605Smrgindirect_wait_gl(struct glx_context *gc)
179848b8605Smrg{
180848b8605Smrg   xGLXWaitGLReq *req;
181848b8605Smrg   Display *dpy = gc->currentDpy;
182848b8605Smrg
183848b8605Smrg   /* Flush any pending commands out */
184848b8605Smrg   __glXFlushRenderBuffer(gc, gc->pc);
185848b8605Smrg
186848b8605Smrg   /* Send the glXWaitGL request */
187848b8605Smrg   LockDisplay(dpy);
188848b8605Smrg   GetReq(GLXWaitGL, req);
189848b8605Smrg   req->reqType = gc->majorOpcode;
190848b8605Smrg   req->glxCode = X_GLXWaitGL;
191848b8605Smrg   req->contextTag = gc->currentContextTag;
192848b8605Smrg   UnlockDisplay(dpy);
193848b8605Smrg   SyncHandle();
194848b8605Smrg}
195848b8605Smrg
196848b8605Smrgstatic void
197848b8605Smrgindirect_wait_x(struct glx_context *gc)
198848b8605Smrg{
199848b8605Smrg   xGLXWaitXReq *req;
200848b8605Smrg   Display *dpy = gc->currentDpy;
201848b8605Smrg
202848b8605Smrg   /* Flush any pending commands out */
203848b8605Smrg   __glXFlushRenderBuffer(gc, gc->pc);
204848b8605Smrg
205848b8605Smrg   LockDisplay(dpy);
206848b8605Smrg   GetReq(GLXWaitX, req);
207848b8605Smrg   req->reqType = gc->majorOpcode;
208848b8605Smrg   req->glxCode = X_GLXWaitX;
209848b8605Smrg   req->contextTag = gc->currentContextTag;
210848b8605Smrg   UnlockDisplay(dpy);
211848b8605Smrg   SyncHandle();
212848b8605Smrg}
213848b8605Smrg
214848b8605Smrgstatic void
215848b8605Smrgindirect_use_x_font(struct glx_context *gc,
216848b8605Smrg		    Font font, int first, int count, int listBase)
217848b8605Smrg{
218848b8605Smrg   xGLXUseXFontReq *req;
219848b8605Smrg   Display *dpy = gc->currentDpy;
220848b8605Smrg
221848b8605Smrg   /* Flush any pending commands out */
222848b8605Smrg   __glXFlushRenderBuffer(gc, gc->pc);
223848b8605Smrg
224848b8605Smrg   /* Send the glXUseFont request */
225848b8605Smrg   LockDisplay(dpy);
226848b8605Smrg   GetReq(GLXUseXFont, req);
227848b8605Smrg   req->reqType = gc->majorOpcode;
228848b8605Smrg   req->glxCode = X_GLXUseXFont;
229848b8605Smrg   req->contextTag = gc->currentContextTag;
230848b8605Smrg   req->font = font;
231848b8605Smrg   req->first = first;
232848b8605Smrg   req->count = count;
233848b8605Smrg   req->listBase = listBase;
234848b8605Smrg   UnlockDisplay(dpy);
235848b8605Smrg   SyncHandle();
236848b8605Smrg}
237848b8605Smrg
238848b8605Smrgstatic void
239848b8605Smrgindirect_bind_tex_image(Display * dpy,
240848b8605Smrg			GLXDrawable drawable,
241848b8605Smrg			int buffer, const int *attrib_list)
242848b8605Smrg{
243848b8605Smrg   xGLXVendorPrivateReq *req;
244848b8605Smrg   struct glx_context *gc = __glXGetCurrentContext();
245848b8605Smrg   CARD32 *drawable_ptr;
246848b8605Smrg   INT32 *buffer_ptr;
247848b8605Smrg   CARD32 *num_attrib_ptr;
248848b8605Smrg   CARD32 *attrib_ptr;
249848b8605Smrg   CARD8 opcode;
250848b8605Smrg   unsigned int i;
251848b8605Smrg
252848b8605Smrg   i = 0;
253848b8605Smrg   if (attrib_list) {
254848b8605Smrg      while (attrib_list[i * 2] != None)
255848b8605Smrg         i++;
256848b8605Smrg   }
257848b8605Smrg
258848b8605Smrg   opcode = __glXSetupForCommand(dpy);
259848b8605Smrg   if (!opcode)
260848b8605Smrg      return;
261848b8605Smrg
262848b8605Smrg   LockDisplay(dpy);
263848b8605Smrg   GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req);
264848b8605Smrg   req->reqType = opcode;
265848b8605Smrg   req->glxCode = X_GLXVendorPrivate;
266848b8605Smrg   req->vendorCode = X_GLXvop_BindTexImageEXT;
267848b8605Smrg   req->contextTag = gc->currentContextTag;
268848b8605Smrg
269848b8605Smrg   drawable_ptr = (CARD32 *) (req + 1);
270848b8605Smrg   buffer_ptr = (INT32 *) (drawable_ptr + 1);
271848b8605Smrg   num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
272848b8605Smrg   attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
273848b8605Smrg
274848b8605Smrg   *drawable_ptr = drawable;
275848b8605Smrg   *buffer_ptr = buffer;
276848b8605Smrg   *num_attrib_ptr = (CARD32) i;
277848b8605Smrg
278848b8605Smrg   i = 0;
279848b8605Smrg   if (attrib_list) {
280848b8605Smrg      while (attrib_list[i * 2] != None) {
281848b8605Smrg         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
282848b8605Smrg         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
283848b8605Smrg         i++;
284848b8605Smrg      }
285848b8605Smrg   }
286848b8605Smrg
287848b8605Smrg   UnlockDisplay(dpy);
288848b8605Smrg   SyncHandle();
289848b8605Smrg}
290848b8605Smrg
291848b8605Smrgstatic void
292848b8605Smrgindirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
293848b8605Smrg{
294848b8605Smrg   xGLXVendorPrivateReq *req;
295848b8605Smrg   struct glx_context *gc = __glXGetCurrentContext();
296848b8605Smrg   CARD32 *drawable_ptr;
297848b8605Smrg   INT32 *buffer_ptr;
298848b8605Smrg   CARD8 opcode;
299848b8605Smrg
300848b8605Smrg   opcode = __glXSetupForCommand(dpy);
301848b8605Smrg   if (!opcode)
302848b8605Smrg      return;
303848b8605Smrg
304848b8605Smrg   LockDisplay(dpy);
305848b8605Smrg   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req);
306848b8605Smrg   req->reqType = opcode;
307848b8605Smrg   req->glxCode = X_GLXVendorPrivate;
308848b8605Smrg   req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
309848b8605Smrg   req->contextTag = gc->currentContextTag;
310848b8605Smrg
311848b8605Smrg   drawable_ptr = (CARD32 *) (req + 1);
312848b8605Smrg   buffer_ptr = (INT32 *) (drawable_ptr + 1);
313848b8605Smrg
314848b8605Smrg   *drawable_ptr = drawable;
315848b8605Smrg   *buffer_ptr = buffer;
316848b8605Smrg
317848b8605Smrg   UnlockDisplay(dpy);
318848b8605Smrg   SyncHandle();
319848b8605Smrg}
320848b8605Smrg
321848b8605Smrgstatic const struct glx_context_vtable indirect_context_vtable = {
322848b8605Smrg   .destroy             = indirect_destroy_context,
323848b8605Smrg   .bind                = indirect_bind_context,
324848b8605Smrg   .unbind              = indirect_unbind_context,
325848b8605Smrg   .wait_gl             = indirect_wait_gl,
326848b8605Smrg   .wait_x              = indirect_wait_x,
327848b8605Smrg   .use_x_font          = indirect_use_x_font,
328848b8605Smrg   .bind_tex_image      = indirect_bind_tex_image,
329848b8605Smrg   .release_tex_image   = indirect_release_tex_image,
330848b8605Smrg   .get_proc_address    = NULL,
331848b8605Smrg};
332848b8605Smrg
333848b8605Smrg/**
334848b8605Smrg * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
335848b8605Smrg * function called \c __glXAllocateClientState that allocates the memory and
336848b8605Smrg * does all the initialization (including the pixel pack / unpack).
337848b8605Smrg *
338848b8605Smrg * \note
339848b8605Smrg * This function is \b not the place to validate the context creation
340848b8605Smrg * parameters.  It is just the allocator for the \c glx_context.
341848b8605Smrg */
342848b8605Smrg_X_HIDDEN struct glx_context *
343848b8605Smrgindirect_create_context(struct glx_screen *psc,
344848b8605Smrg			struct glx_config *mode,
345848b8605Smrg			struct glx_context *shareList, int renderType)
346848b8605Smrg{
347848b8605Smrg   struct glx_context *gc;
348848b8605Smrg   int bufSize;
349848b8605Smrg   CARD8 opcode;
350848b8605Smrg   __GLXattribute *state;
351848b8605Smrg
352848b8605Smrg   opcode = __glXSetupForCommand(psc->dpy);
353848b8605Smrg   if (!opcode) {
354848b8605Smrg      return NULL;
355848b8605Smrg   }
356848b8605Smrg
357848b8605Smrg   /* Allocate our context record */
358848b8605Smrg   gc = calloc(1, sizeof *gc);
359848b8605Smrg   if (!gc) {
360848b8605Smrg      /* Out of memory */
361848b8605Smrg      return NULL;
362848b8605Smrg   }
363848b8605Smrg
364848b8605Smrg   glx_context_init(gc, psc, mode);
365848b8605Smrg   gc->isDirect = GL_FALSE;
366848b8605Smrg   gc->vtable = &indirect_context_vtable;
367848b8605Smrg   state = calloc(1, sizeof(struct __GLXattributeRec));
368848b8605Smrg   gc->renderType = renderType;
369848b8605Smrg
370848b8605Smrg   if (state == NULL) {
371848b8605Smrg      /* Out of memory */
372848b8605Smrg      free(gc);
373848b8605Smrg      return NULL;
374848b8605Smrg   }
375848b8605Smrg   gc->client_state_private = state;
376b8e80941Smrg   state->NoDrawArraysProtocol = env_var_as_boolean("LIBGL_NO_DRAWARRAYS", false);
377848b8605Smrg
378848b8605Smrg   /*
379848b8605Smrg    ** Create a temporary buffer to hold GLX rendering commands.  The size
380848b8605Smrg    ** of the buffer is selected so that the maximum number of GLX rendering
381848b8605Smrg    ** commands can fit in a single X packet and still have room in the X
382848b8605Smrg    ** packet for the GLXRenderReq header.
383848b8605Smrg    */
384848b8605Smrg
385848b8605Smrg   bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
386848b8605Smrg   gc->buf = malloc(bufSize);
387848b8605Smrg   if (!gc->buf) {
388848b8605Smrg      free(gc->client_state_private);
389848b8605Smrg      free(gc);
390848b8605Smrg      return NULL;
391848b8605Smrg   }
392848b8605Smrg   gc->bufSize = bufSize;
393848b8605Smrg
394848b8605Smrg   /* Fill in the new context */
395848b8605Smrg   gc->renderMode = GL_RENDER;
396848b8605Smrg
397848b8605Smrg   state->storePack.alignment = 4;
398848b8605Smrg   state->storeUnpack.alignment = 4;
399848b8605Smrg
400848b8605Smrg   gc->attributes.stackPointer = &gc->attributes.stack[0];
401848b8605Smrg
402848b8605Smrg   /*
403848b8605Smrg    ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
404848b8605Smrg    */
405848b8605Smrg   gc->fillImage = __glFillImage;
406848b8605Smrg   gc->pc = gc->buf;
407848b8605Smrg   gc->bufEnd = gc->buf + bufSize;
408848b8605Smrg   gc->isDirect = GL_FALSE;
409848b8605Smrg   if (__glXDebug) {
410848b8605Smrg      /*
411848b8605Smrg       ** Set limit register so that there will be one command per packet
412848b8605Smrg       */
413848b8605Smrg      gc->limit = gc->buf;
414848b8605Smrg   }
415848b8605Smrg   else {
416848b8605Smrg      gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
417848b8605Smrg   }
418848b8605Smrg   gc->majorOpcode = opcode;
419848b8605Smrg
420848b8605Smrg   /*
421848b8605Smrg    ** Constrain the maximum drawing command size allowed to be
422848b8605Smrg    ** transfered using the X_GLXRender protocol request.  First
423848b8605Smrg    ** constrain by a software limit, then constrain by the protocl
424848b8605Smrg    ** limit.
425848b8605Smrg    */
426848b8605Smrg   if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
427848b8605Smrg      bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
428848b8605Smrg   }
429848b8605Smrg   if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
430848b8605Smrg      bufSize = __GLX_MAX_RENDER_CMD_SIZE;
431848b8605Smrg   }
432848b8605Smrg   gc->maxSmallRenderCommandSize = bufSize;
433848b8605Smrg
434848b8605Smrg
435848b8605Smrg   return gc;
436848b8605Smrg}
437848b8605Smrg
438848b8605Smrg_X_HIDDEN struct glx_context *
439848b8605Smrgindirect_create_context_attribs(struct glx_screen *base,
440848b8605Smrg				struct glx_config *config_base,
441848b8605Smrg				struct glx_context *shareList,
442848b8605Smrg				unsigned num_attribs,
443848b8605Smrg				const uint32_t *attribs,
444848b8605Smrg				unsigned *error)
445848b8605Smrg{
446848b8605Smrg   int renderType = GLX_RGBA_TYPE;
447848b8605Smrg   unsigned i;
448848b8605Smrg
449848b8605Smrg   /* The error parameter is only used on the server so that correct GLX
450848b8605Smrg    * protocol errors can be generated.  On the client, it can be ignored.
451848b8605Smrg    */
452848b8605Smrg   (void) error;
453848b8605Smrg
454848b8605Smrg   /* All of the attribute validation for indirect contexts is handled on the
455848b8605Smrg    * server, so there's not much to do here. Still, we need to parse the
456848b8605Smrg    * attributes to correctly set renderType.
457848b8605Smrg    */
458848b8605Smrg   for (i = 0; i < num_attribs; i++) {
459848b8605Smrg      if (attribs[i * 2] == GLX_RENDER_TYPE)
460848b8605Smrg         renderType = attribs[i * 2 + 1];
461848b8605Smrg   }
462848b8605Smrg
463848b8605Smrg   return indirect_create_context(base, config_base, shareList, renderType);
464848b8605Smrg}
465848b8605Smrg
466848b8605Smrgstatic const struct glx_screen_vtable indirect_screen_vtable = {
467848b8605Smrg   .create_context         = indirect_create_context,
468848b8605Smrg   .create_context_attribs = indirect_create_context_attribs,
469848b8605Smrg   .query_renderer_integer = NULL,
470848b8605Smrg   .query_renderer_string  = NULL,
471848b8605Smrg};
472848b8605Smrg
473848b8605Smrg_X_HIDDEN struct glx_screen *
474848b8605Smrgindirect_create_screen(int screen, struct glx_display * priv)
475848b8605Smrg{
476848b8605Smrg   struct glx_screen *psc;
477848b8605Smrg
478848b8605Smrg   psc = calloc(1, sizeof *psc);
479848b8605Smrg   if (psc == NULL)
480848b8605Smrg      return NULL;
481848b8605Smrg
482848b8605Smrg   glx_screen_init(psc, screen, priv);
483848b8605Smrg   psc->vtable = &indirect_screen_vtable;
484848b8605Smrg
485848b8605Smrg   return psc;
486848b8605Smrg}
487848b8605Smrg
488848b8605Smrg#endif
489