Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / kdrive / ephyr / ephyrglxext.c
CommitLineData
a09e091a
JB
1/*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@openedhand.com>
4 *
5 * Copyright © 2007 OpenedHand Ltd
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of OpenedHand Ltd not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. OpenedHand Ltd makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Dodji Seketeli <dodji@openedhand.com>
27 */
28#ifdef HAVE_CONFIG_H
29#include <kdrive-config.h>
30#endif
31
32#include <xcb/glx.h>
33#include "extnsionst.h"
34#include "ephyrglxext.h"
35#include "ephyrhostglx.h"
36#define _HAVE_XALLOC_DECLS
37#include "ephyrlog.h"
38#include <GL/glxproto.h>
39#include "glx/glxserver.h"
40#include "glx/indirect_table.h"
41#include "glx/indirect_util.h"
42#include "glx/unpack.h"
43#include "hostx.h"
44
45#ifndef TRUE
46#define TRUE 1
47#endif
48
49#ifndef FALSE
50#define FALSE 0
51#endif
52
53int ephyrGLXQueryVersion(__GLXclientState * cl, GLbyte * pc);
54int ephyrGLXQueryVersionSwap(__GLXclientState * cl, GLbyte * pc);
55int ephyrGLXGetVisualConfigs(__GLXclientState * cl, GLbyte * pc);
56int ephyrGLXGetVisualConfigsSwap(__GLXclientState * cl, GLbyte * pc);
57int ephyrGLXClientInfo(__GLXclientState * cl, GLbyte * pc);
58int ephyrGLXClientInfoSwap(__GLXclientState * cl, GLbyte * pc);
59int ephyrGLXQueryServerString(__GLXclientState * a_cl, GLbyte * a_pc);
60int ephyrGLXQueryServerStringSwap(__GLXclientState * a_cl, GLbyte * a_pc);
61int ephyrGLXGetFBConfigsSGIX(__GLXclientState * a_cl, GLbyte * a_pc);
62int ephyrGLXGetFBConfigsSGIXSwap(__GLXclientState * a_cl, GLbyte * a_pc);
63int ephyrGLXCreateContext(__GLXclientState * a_cl, GLbyte * a_pc);
64int ephyrGLXCreateContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
65int ephyrGLXCreateNewContext(__GLXclientState * a_cl, GLbyte * a_pc);
66int ephyrGLXCreateNewContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
67int ephyrGLXDestroyContext(__GLXclientState * a_cl, GLbyte * a_pc);
68int ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
69int ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
70int ephyrGLXMakeCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc);
71int ephyrGLXMakeCurrentReadSGI(__GLXclientState * a_cl, GLbyte * a_pc);
72int ephyrGLXMakeCurrentReadSGISwap(__GLXclientState * a_cl, GLbyte * a_pc);
73int ephyrGLXMakeContextCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
74int ephyrGLXMakeContextCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc);
75int ephyrGLXGetString(__GLXclientState * a_cl, GLbyte * a_pc);
76int ephyrGLXGetStringSwap(__GLXclientState * a_cl, GLbyte * a_pc);
77int ephyrGLXGetIntegerv(__GLXclientState * a_cl, GLbyte * a_pc);
78int ephyrGLXGetIntegervSwap(__GLXclientState * a_cl, GLbyte * a_pc);
79int ephyrGLXIsDirect(__GLXclientState * a_cl, GLbyte * a_pc);
80int ephyrGLXIsDirectSwap(__GLXclientState * a_cl, GLbyte * a_pc);
81
82Bool
83ephyrHijackGLXExtension(void)
84{
85 const void *(*dispatch_functions)[2];
86
87 if (!host_has_extension(&xcb_glx_id)) {
88 EPHYR_LOG("host X does not have GLX\n");
89 return FALSE;
90 }
91 EPHYR_LOG("host X does have GLX\n");
92
93 if (!Single_dispatch_info.dispatch_functions) {
94 EPHYR_LOG_ERROR("could not get dispatch functions table\n");
95 return FALSE;
96 }
97 /*
98 * hijack some single entry point dispatch functions
99 */
100 dispatch_functions = Single_dispatch_info.dispatch_functions;
101 EPHYR_RETURN_VAL_IF_FAIL(dispatch_functions, FALSE);
102
103 dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion;
104 dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap;
105
106 dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs;
107 dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap;
108 dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo;
109 dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap;
110
111 dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString;
112 dispatch_functions[X_GLXQueryServerString][1] =
113 ephyrGLXQueryServerStringSwap;
114
115 dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext;
116 dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap;
117
118 dispatch_functions[X_GLXCreateNewContext][0] = ephyrGLXCreateNewContext;
119 dispatch_functions[X_GLXCreateNewContext][1] = ephyrGLXCreateNewContextSwap;
120
121 dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext;
122 dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap;
123
124 dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent;
125 dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap;
126
127 dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect;
128 dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap;
129
130 dispatch_functions[73][0] = ephyrGLXGetString;
131 dispatch_functions[73][1] = ephyrGLXGetStringSwap;
132
133 dispatch_functions[61][0] = ephyrGLXGetIntegerv;
134 dispatch_functions[61][1] = ephyrGLXGetIntegervSwap;
135
136 dispatch_functions[X_GLXMakeContextCurrent][0] =
137 ephyrGLXMakeContextCurrent;
138 dispatch_functions[X_GLXMakeContextCurrent][1] =
139 ephyrGLXMakeContextCurrentSwap;
140
141 /*
142 * hijack some vendor priv entry point dispatch functions
143 */
144 dispatch_functions = VendorPriv_dispatch_info.dispatch_functions;
145 dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
146 dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
147
148 dispatch_functions[89][0] = ephyrGLXMakeCurrentReadSGI;
149 dispatch_functions[89][1] = ephyrGLXMakeCurrentReadSGISwap;
150
151 EPHYR_LOG("hijacked glx entry points to forward requests to host X\n");
152
153
154 return TRUE;
155}
156
157/*********************
158 * implementation of
159 * hijacked GLX entry
160 * points
161 ********************/
162
163int
164ephyrGLXQueryVersion(__GLXclientState * a_cl, GLbyte * a_pc)
165{
166 ClientPtr client = a_cl->client;
167 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
168 xGLXQueryVersionReply reply;
169 int major, minor;
170 int res = BadImplementation;
171
172 EPHYR_LOG("enter\n");
173
174 major = req->majorVersion;
175 minor = req->minorVersion;
176
177 if (!ephyrHostGLXQueryVersion(&major, &minor)) {
178 EPHYR_LOG_ERROR("ephyrHostGLXQueryVersion() failed\n");
179 goto out;
180 }
181 EPHYR_LOG("major:%d, minor:%d\n", major, minor);
182 reply = (xGLXQueryVersionReply) {
183 .type = X_Reply,
184 .sequenceNumber = client->sequence,
185 .length = 0,
186 .majorVersion = major,
187 .minorVersion = minor
188 };
189
190 if (client->swapped) {
191 __glXSwapQueryVersionReply(client, &reply);
192 }
193 else {
194 WriteToClient(client, sz_xGLXQueryVersionReply, &reply);
195 }
196
197 res = Success;
198 out:
199 EPHYR_LOG("leave\n");
200 return res;
201}
202
203int
204ephyrGLXQueryVersionSwap(__GLXclientState * a_cl, GLbyte * a_pc)
205{
206 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
207
208 __GLX_DECLARE_SWAP_VARIABLES;
209
210 __GLX_SWAP_SHORT(&req->length);
211 __GLX_SWAP_INT(&req->majorVersion);
212 __GLX_SWAP_INT(&req->minorVersion);
213 return ephyrGLXQueryVersion(a_cl, a_pc);
214}
215
216static int
217ephyrGLXGetVisualConfigsReal(__GLXclientState * a_cl,
218 GLbyte * a_pc, Bool a_do_swap)
219{
220 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
221 ClientPtr client = a_cl->client;
222 xGLXGetVisualConfigsReply reply;
223 int32_t *props_buf = NULL, num_visuals = 0,
224 num_props = 0, res = BadImplementation, i = 0,
225 props_per_visual_size = 0, props_buf_size = 0;
226 __GLX_DECLARE_SWAP_VARIABLES;
227 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
228
229 EPHYR_LOG("enter\n");
230
231 if (!ephyrHostGLXGetVisualConfigs(req->screen,
232 &num_visuals,
233 &num_props,
234 &props_buf_size, &props_buf)) {
235 EPHYR_LOG_ERROR("ephyrHostGLXGetVisualConfigs() failed\n");
236 goto out;
237 }
238 EPHYR_LOG("num_visuals:%d, num_props:%d\n", num_visuals, num_props);
239
240 reply = (xGLXGetVisualConfigsReply) {
241 .type = X_Reply,
242 .sequenceNumber = client->sequence,
243 .length = (num_visuals * __GLX_SIZE_CARD32 * num_props) >> 2,
244 .numVisuals = num_visuals,
245 .numProps = num_props
246 };
247
248 if (a_do_swap) {
249 __GLX_SWAP_SHORT(&reply.sequenceNumber);
250 __GLX_SWAP_INT(&reply.length);
251 __GLX_SWAP_INT(&reply.numVisuals);
252 __GLX_SWAP_INT(&reply.numProps);
253 __GLX_SWAP_INT_ARRAY(props_buf, num_props);
254 }
255 WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
256 props_per_visual_size = props_buf_size / num_visuals;
257 for (i = 0; i < num_visuals; i++) {
258 WriteToClient(client,
259 props_per_visual_size,
260 (char *) props_buf + i * props_per_visual_size);
261 }
262 res = Success;
263
264 out:
265 EPHYR_LOG("leave\n");
266 free(props_buf);
267 props_buf = NULL;
268
269 return res;
270}
271
272static int
273ephyrGLXGetFBConfigsSGIXReal(__GLXclientState * a_cl,
274 GLbyte * a_pc, Bool a_do_swap)
275{
276 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) a_pc;
277 ClientPtr client = a_cl->client;
278 xGLXGetVisualConfigsReply reply;
279 int32_t *props_buf = NULL, num_visuals = 0,
280 num_props = 0, res = BadImplementation, i = 0,
281 props_per_visual_size = 0, props_buf_size = 0;
282 __GLX_DECLARE_SWAP_VARIABLES;
283 __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
284
285 EPHYR_LOG("enter\n");
286
287 if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX(req->screen,
288 &num_visuals,
289 &num_props,
290 &props_buf_size, &props_buf)) {
291 EPHYR_LOG_ERROR("ephyrHostGLXGetVisualConfigs() failed\n");
292 goto out;
293 }
294 EPHYR_LOG("num_visuals:%d, num_props:%d\n", num_visuals, num_props);
295
296 reply = (xGLXGetVisualConfigsReply) {
297 .type = X_Reply,
298 .sequenceNumber = client->sequence,
299 .length = props_buf_size >> 2,
300 .numVisuals = num_visuals,
301 .numProps = num_props
302 };
303
304 if (a_do_swap) {
305 __GLX_SWAP_SHORT(&reply.sequenceNumber);
306 __GLX_SWAP_INT(&reply.length);
307 __GLX_SWAP_INT(&reply.numVisuals);
308 __GLX_SWAP_INT(&reply.numProps);
309 __GLX_SWAP_INT_ARRAY(props_buf, num_props);
310 }
311 WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
312 props_per_visual_size = props_buf_size / num_visuals;
313 for (i = 0; i < num_visuals; i++) {
314 WriteToClient(client,
315 props_per_visual_size,
316 &((char *) props_buf)[i * props_per_visual_size]);
317 }
318 res = Success;
319
320 out:
321 EPHYR_LOG("leave\n");
322 free(props_buf);
323 props_buf = NULL;
324
325 return res;
326}
327
328int
329ephyrGLXGetVisualConfigs(__GLXclientState * a_cl, GLbyte * a_pc)
330{
331 return ephyrGLXGetVisualConfigsReal(a_cl, a_pc, FALSE);
332}
333
334int
335ephyrGLXGetVisualConfigsSwap(__GLXclientState * a_cl, GLbyte * a_pc)
336{
337 return ephyrGLXGetVisualConfigsReal(a_cl, a_pc, TRUE);
338}
339
340int
341ephyrGLXClientInfo(__GLXclientState * a_cl, GLbyte * a_pc)
342{
343 int res = BadImplementation;
344 xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
345
346 EPHYR_LOG("enter\n");
347 if (!ephyrHostGLXSendClientInfo(req->major, req->minor, (char *) req + 1)) {
348 EPHYR_LOG_ERROR("failed to send client info to host\n");
349 goto out;
350 }
351 res = Success;
352
353 out:
354 EPHYR_LOG("leave\n");
355 return res;
356}
357
358int
359ephyrGLXClientInfoSwap(__GLXclientState * a_cl, GLbyte * a_pc)
360{
361 xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
362
363 __GLX_DECLARE_SWAP_VARIABLES;
364
365 __GLX_SWAP_SHORT(&req->length);
366 __GLX_SWAP_INT(&req->major);
367 __GLX_SWAP_INT(&req->minor);
368 __GLX_SWAP_INT(&req->numbytes);
369
370 return ephyrGLXClientInfo(a_cl, a_pc);
371}
372
373int
374ephyrGLXQueryServerString(__GLXclientState * a_cl, GLbyte * a_pc)
375{
376 int res = BadImplementation;
377 ClientPtr client = a_cl->client;
378 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
379 xGLXQueryServerStringReply reply;
380 char *server_string = NULL;
381 int length = 0;
382
383 EPHYR_LOG("enter\n");
384 if (!ephyrHostGLXQueryServerString(req->screen,
385 req->name,
386 &server_string)) {
387 EPHYR_LOG_ERROR("failed to query string from host\n");
388 goto out;
389 }
390 EPHYR_LOG("string: %s\n", server_string);
391 length = strlen(server_string) + 1;
392 reply = (xGLXQueryServerStringReply) {
393 .type = X_Reply,
394 .sequenceNumber = client->sequence,
395 .length = __GLX_PAD(length) >> 2,
396 .n = length
397 };
398
399 WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
400 WriteToClient(client, (int) (reply.length << 2), server_string);
401
402 res = Success;
403
404 out:
405 EPHYR_LOG("leave\n");
406 free(server_string);
407 server_string = NULL;
408
409 return res;
410}
411
412int
413ephyrGLXQueryServerStringSwap(__GLXclientState * a_cl, GLbyte * a_pc)
414{
415 EPHYR_LOG_ERROR("not yet implemented\n");
416 return BadImplementation;
417}
418
419int
420ephyrGLXGetFBConfigsSGIX(__GLXclientState * a_cl, GLbyte * a_pc)
421{
422 return ephyrGLXGetFBConfigsSGIXReal(a_cl, a_pc, FALSE);
423}
424
425int
426ephyrGLXGetFBConfigsSGIXSwap(__GLXclientState * a_cl, GLbyte * a_pc)
427{
428 return ephyrGLXGetFBConfigsSGIXReal(a_cl, a_pc, TRUE);
429}
430
431static int
432ephyrGLXCreateContextReal(xGLXCreateContextReq * a_req, Bool a_do_swap)
433{
434 int res = BadImplementation;
435 EphyrHostWindowAttributes host_w_attrs;
436
437 __GLX_DECLARE_SWAP_VARIABLES;
438
439 EPHYR_RETURN_VAL_IF_FAIL(a_req, BadValue);
440 EPHYR_LOG("enter\n");
441
442 if (a_do_swap) {
443 __GLX_SWAP_SHORT(&a_req->length);
444 __GLX_SWAP_INT(&a_req->context);
445 __GLX_SWAP_INT(&a_req->visual);
446 __GLX_SWAP_INT(&a_req->screen);
447 __GLX_SWAP_INT(&a_req->shareList);
448 }
449
450 EPHYR_LOG("context creation requested. localid:%d, "
451 "screen:%d, visual:%d, direct:%d\n",
452 (int) a_req->context, (int) a_req->screen,
453 (int) a_req->visual, (int) a_req->isDirect);
454
455 memset(&host_w_attrs, 0, sizeof(host_w_attrs));
456 if (!hostx_get_window_attributes(hostx_get_window(a_req->screen),
457 &host_w_attrs)) {
458 EPHYR_LOG_ERROR("failed to get host window attrs\n");
459 goto out;
460 }
461
462 EPHYR_LOG("host window visual id: %d\n", host_w_attrs.visualid);
463
464 if (!ephyrHostGLXCreateContext(a_req->screen,
465 host_w_attrs.visualid,
466 a_req->context,
467 a_req->shareList, 0,
468 a_req->isDirect, X_GLXCreateContext)) {
469 EPHYR_LOG_ERROR("ephyrHostGLXCreateContext() failed\n");
470 goto out;
471 }
472 res = Success;
473 out:
474 EPHYR_LOG("leave\n");
475 return res;
476}
477
478static int
479ephyrGLXCreateNewContextReal(xGLXCreateNewContextReq * a_req, Bool a_do_swap)
480{
481 int res = BadImplementation;
482
483 __GLX_DECLARE_SWAP_VARIABLES;
484
485 EPHYR_RETURN_VAL_IF_FAIL(a_req, BadValue);
486 EPHYR_LOG("enter\n");
487
488 if (a_do_swap) {
489 __GLX_SWAP_SHORT(&a_req->length);
490 __GLX_SWAP_INT(&a_req->context);
491 __GLX_SWAP_INT(&a_req->fbconfig);
492 __GLX_SWAP_INT(&a_req->screen);
493 __GLX_SWAP_INT(&a_req->renderType);
494 __GLX_SWAP_INT(&a_req->shareList);
495 }
496
497 EPHYR_LOG("context creation requested. localid:%d, "
498 "screen:%d, fbconfig:%d, renderType:%d, direct:%d\n",
499 (int) a_req->context, (int) a_req->screen,
500 (int) a_req->fbconfig, (int) a_req->renderType,
501 (int) a_req->isDirect);
502
503 if (!ephyrHostGLXCreateContext(a_req->screen,
504 a_req->fbconfig,
505 a_req->context,
506 a_req->shareList, a_req->renderType,
507 a_req->isDirect, X_GLXCreateNewContext)) {
508 EPHYR_LOG_ERROR("ephyrHostGLXCreateNewContext() failed\n");
509 goto out;
510 }
511 res = Success;
512 out:
513 EPHYR_LOG("leave\n");
514 return res;
515}
516
517int
518ephyrGLXCreateContext(__GLXclientState * cl, GLbyte * pc)
519{
520 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
521
522 return ephyrGLXCreateContextReal(req, FALSE);
523}
524
525int
526ephyrGLXCreateContextSwap(__GLXclientState * cl, GLbyte * pc)
527{
528 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
529
530 return ephyrGLXCreateContextReal(req, TRUE);
531}
532
533int
534ephyrGLXCreateNewContext(__GLXclientState * cl, GLbyte * pc)
535{
536 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
537
538 return ephyrGLXCreateNewContextReal(req, FALSE);
539}
540
541int
542ephyrGLXCreateNewContextSwap(__GLXclientState * cl, GLbyte * pc)
543{
544 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
545
546 return ephyrGLXCreateNewContextReal(req, TRUE);
547}
548
549static int
550ephyrGLXDestroyContextReal(__GLXclientState * a_cl,
551 GLbyte * a_pc, Bool a_do_swap)
552{
553 int res = BadImplementation;
554 ClientPtr client = a_cl->client;
555 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
556
557 EPHYR_LOG("enter. id:%d\n", (int) req->context);
558 if (!ephyrHostDestroyContext(req->context)) {
559 EPHYR_LOG_ERROR("ephyrHostDestroyContext() failed\n");
560 client->errorValue = req->context;
561 goto out;
562 }
563 res = Success;
564
565 out:
566 EPHYR_LOG("leave\n");
567 return res;
568}
569
570int
571ephyrGLXDestroyContext(__GLXclientState * a_cl, GLbyte * a_pc)
572{
573 return ephyrGLXDestroyContextReal(a_cl, a_pc, FALSE);
574}
575
576int
577ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc)
578{
579 return ephyrGLXDestroyContextReal(a_cl, a_pc, TRUE);
580}
581
582static int
583ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLXDrawable write,
584 GLXDrawable read, GLXContextTag ctx,
585 GLXContextTag old_ctx, Bool a_do_swap)
586{
587 int res = BadImplementation;
588 xGLXMakeCurrentReply reply;
589 DrawablePtr drawableR = NULL, drawableW = NULL;
590 GLXContextTag new_ctx = 0;
591
592 EPHYR_LOG("enter\n");
593 res = dixLookupDrawable(&drawableW, write, a_cl->client, 0, DixReadAccess);
594 EPHYR_RETURN_VAL_IF_FAIL(drawableW, BadValue);
595 EPHYR_RETURN_VAL_IF_FAIL(drawableW->pScreen, BadValue);
596 EPHYR_LOG("screen nummber requested:%d\n", drawableW->pScreen->myNum);
597
598 if (read != write) {
599 res = dixLookupDrawable(&drawableR, read, a_cl->client, 0,
600 DixReadAccess);
601 EPHYR_RETURN_VAL_IF_FAIL(drawableR, BadValue);
602 EPHYR_RETURN_VAL_IF_FAIL(drawableR->pScreen, BadValue);
603 }
604 else {
605 drawableR = drawableW;
606 }
607
608 if (!ephyrHostGLXMakeCurrent(hostx_get_window(drawableW->pScreen->myNum),
609 hostx_get_window(drawableR->pScreen->myNum),
610 ctx, old_ctx, (int *) &new_ctx)) {
611 EPHYR_LOG_ERROR("ephyrHostGLXMakeCurrent() failed\n");
612 goto out;
613 }
614 reply = (xGLXMakeCurrentReply) {
615 .type = X_Reply,
616 .sequenceNumber = a_cl->client->sequence,
617 .length = 0,
618 .contextTag = new_ctx
619 };
620 if (a_do_swap) {
621 __GLX_DECLARE_SWAP_VARIABLES;
622 __GLX_SWAP_SHORT(&reply.sequenceNumber);
623 __GLX_SWAP_INT(&reply.length);
624 __GLX_SWAP_INT(&reply.contextTag);
625 }
626 WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, &reply);
627
628 res = Success;
629 out:
630 EPHYR_LOG("leave\n");
631 return res;
632}
633
634int
635ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc)
636{
637 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
638 return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable,
639 req->context, req->oldContextTag, FALSE);
640}
641
642int
643ephyrGLXMakeCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc)
644{
645 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
646 __GLX_DECLARE_SWAP_VARIABLES;
647
648 __GLX_SWAP_INT(&req->drawable);
649 __GLX_SWAP_INT(&req->context);
650 __GLX_SWAP_INT(&req->oldContextTag);
651
652 return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable,
653 req->context, req->oldContextTag, TRUE);
654}
655
656int
657ephyrGLXMakeCurrentReadSGI(__GLXclientState * a_cl, GLbyte * a_pc)
658{
659 xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) a_pc;
660
661 return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readable,
662 req->context, req->oldContextTag, FALSE);
663}
664
665int
666ephyrGLXMakeCurrentReadSGISwap(__GLXclientState * a_cl, GLbyte * a_pc)
667{
668 xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) a_pc;
669 __GLX_DECLARE_SWAP_VARIABLES;
670
671 __GLX_SWAP_INT(&req->drawable);
672 __GLX_SWAP_INT(&req->readable);
673 __GLX_SWAP_INT(&req->context);
674 __GLX_SWAP_INT(&req->oldContextTag);
675
676 return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readable,
677 req->context, req->oldContextTag, TRUE);
678}
679
680int
681ephyrGLXMakeContextCurrent(__GLXclientState * a_cl, GLbyte * a_pc)
682{
683 xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) a_pc;
684
685 return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readdrawable,
686 req->context, req->oldContextTag, FALSE);
687}
688
689int
690ephyrGLXMakeContextCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc)
691{
692 xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) a_pc;
693 __GLX_DECLARE_SWAP_VARIABLES;
694
695 __GLX_SWAP_INT(&req->drawable);
696 __GLX_SWAP_INT(&req->readdrawable);
697 __GLX_SWAP_INT(&req->context);
698 __GLX_SWAP_INT(&req->oldContextTag);
699
700 return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readdrawable,
701 req->context, req->oldContextTag, TRUE);
702}
703
704static int
705ephyrGLXGetStringReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
706{
707 ClientPtr client = NULL;
708 int context_tag = 0, name = 0, res = BadImplementation, length = 0;
709 char *string = NULL;
710
711 __GLX_DECLARE_SWAP_VARIABLES;
712
713 EPHYR_RETURN_VAL_IF_FAIL(a_cl && a_pc, BadValue);
714
715 EPHYR_LOG("enter\n");
716
717 client = a_cl->client;
718
719 if (a_do_swap) {
720 __GLX_SWAP_INT(a_pc + 4);
721 __GLX_SWAP_INT(a_pc + __GLX_SINGLE_HDR_SIZE);
722 }
723 context_tag = __GLX_GET_SINGLE_CONTEXT_TAG(a_pc);
724 a_pc += __GLX_SINGLE_HDR_SIZE;
725 name = *(GLenum *) (a_pc + 0);
726 EPHYR_LOG("context_tag:%d, name:%d\n", context_tag, name);
727 if (!ephyrHostGLXGetString(context_tag, name, &string)) {
728 EPHYR_LOG_ERROR("failed to get string from server\n");
729 goto out;
730 }
731 if (string) {
732 length = strlen(string) + 1;
733 EPHYR_LOG("got string:'%s', size:%d\n", string, length);
734 }
735 else {
736 EPHYR_LOG("got string: string (null)\n");
737 }
738 __GLX_BEGIN_REPLY(length);
739 __GLX_PUT_SIZE(length);
740 __GLX_SEND_HEADER();
741 if (a_do_swap) {
742 __GLX_SWAP_REPLY_SIZE();
743 __GLX_SWAP_REPLY_HEADER();
744 }
745 WriteToClient(client, length, string);
746
747 res = Success;
748 out:
749 EPHYR_LOG("leave\n");
750 return res;
751}
752
753int
754ephyrGLXGetString(__GLXclientState * a_cl, GLbyte * a_pc)
755{
756 return ephyrGLXGetStringReal(a_cl, a_pc, FALSE);
757}
758
759int
760ephyrGLXGetStringSwap(__GLXclientState * a_cl, GLbyte * a_pc)
761{
762 return ephyrGLXGetStringReal(a_cl, a_pc, TRUE);
763}
764
765static int
766ephyrGLXGetIntegervReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
767{
768 int res = BadImplementation;
769 xGLXSingleReq *const req = (xGLXSingleReq *) a_pc;
770 GLenum int_name;
771 int value = 0;
772 GLint answer_buf_room[200];
773 GLint *buf = NULL;
774
775 EPHYR_LOG("enter\n");
776
777 a_pc += __GLX_SINGLE_HDR_SIZE;
778
779 int_name = *(GLenum *) (a_pc + 0);
780 if (!ephyrHostGetIntegerValue(req->contextTag, int_name, &value)) {
781 EPHYR_LOG_ERROR("ephyrHostGetIntegerValue() failed\n");
782 goto out;
783 }
784 buf = __glXGetAnswerBuffer(a_cl, sizeof(value),
785 answer_buf_room, sizeof(answer_buf_room), 4);
786
787 if (!buf) {
788 EPHYR_LOG_ERROR("failed to allocate reply buffer\n");
789 res = BadAlloc;
790 goto out;
791 }
792 __glXSendReply(a_cl->client, buf, 1, sizeof(value), GL_FALSE, 0);
793 res = Success;
794
795 out:
796 EPHYR_LOG("leave\n");
797 return res;
798}
799
800int
801ephyrGLXGetIntegerv(__GLXclientState * a_cl, GLbyte * a_pc)
802{
803 return ephyrGLXGetIntegervReal(a_cl, a_pc, FALSE);
804}
805
806int
807ephyrGLXGetIntegervSwap(__GLXclientState * a_cl, GLbyte * a_pc)
808{
809 return ephyrGLXGetIntegervReal(a_cl, a_pc, TRUE);
810}
811
812static int
813ephyrGLXIsDirectReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
814{
815 int res = BadImplementation;
816 ClientPtr client = a_cl->client;
817 xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
818 xGLXIsDirectReply reply;
819 int is_direct = 0;
820
821 EPHYR_RETURN_VAL_IF_FAIL(a_cl && a_pc, FALSE);
822
823 EPHYR_LOG("enter\n");
824
825 if (!ephyrHostIsContextDirect(req->context, (int *) &is_direct)) {
826 EPHYR_LOG_ERROR("ephyrHostIsContextDirect() failed\n");
827 goto out;
828 }
829 reply = (xGLXIsDirectReply) {
830 .type = X_Reply,
831 .sequenceNumber = client->sequence,
832 .length = 0,
833 .isDirect = is_direct
834 };
835
836 WriteToClient(client, sz_xGLXIsDirectReply, &reply);
837 res = Success;
838
839 out:
840 EPHYR_LOG("leave\n");
841 return res;
842}
843
844int
845ephyrGLXIsDirect(__GLXclientState * a_cl, GLbyte * a_pc)
846{
847 return ephyrGLXIsDirectReal(a_cl, a_pc, FALSE);
848}
849
850int
851ephyrGLXIsDirectSwap(__GLXclientState * a_cl, GLbyte * a_pc)
852{
853 return ephyrGLXIsDirectReal(a_cl, a_pc, TRUE);
854}