Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / kdrive / ephyr / ephyrglxext.c
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
53 int ephyrGLXQueryVersion(__GLXclientState * cl, GLbyte * pc);
54 int ephyrGLXQueryVersionSwap(__GLXclientState * cl, GLbyte * pc);
55 int ephyrGLXGetVisualConfigs(__GLXclientState * cl, GLbyte * pc);
56 int ephyrGLXGetVisualConfigsSwap(__GLXclientState * cl, GLbyte * pc);
57 int ephyrGLXClientInfo(__GLXclientState * cl, GLbyte * pc);
58 int ephyrGLXClientInfoSwap(__GLXclientState * cl, GLbyte * pc);
59 int ephyrGLXQueryServerString(__GLXclientState * a_cl, GLbyte * a_pc);
60 int ephyrGLXQueryServerStringSwap(__GLXclientState * a_cl, GLbyte * a_pc);
61 int ephyrGLXGetFBConfigsSGIX(__GLXclientState * a_cl, GLbyte * a_pc);
62 int ephyrGLXGetFBConfigsSGIXSwap(__GLXclientState * a_cl, GLbyte * a_pc);
63 int ephyrGLXCreateContext(__GLXclientState * a_cl, GLbyte * a_pc);
64 int ephyrGLXCreateContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
65 int ephyrGLXCreateNewContext(__GLXclientState * a_cl, GLbyte * a_pc);
66 int ephyrGLXCreateNewContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
67 int ephyrGLXDestroyContext(__GLXclientState * a_cl, GLbyte * a_pc);
68 int ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
69 int ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
70 int ephyrGLXMakeCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc);
71 int ephyrGLXMakeCurrentReadSGI(__GLXclientState * a_cl, GLbyte * a_pc);
72 int ephyrGLXMakeCurrentReadSGISwap(__GLXclientState * a_cl, GLbyte * a_pc);
73 int ephyrGLXMakeContextCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
74 int ephyrGLXMakeContextCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc);
75 int ephyrGLXGetString(__GLXclientState * a_cl, GLbyte * a_pc);
76 int ephyrGLXGetStringSwap(__GLXclientState * a_cl, GLbyte * a_pc);
77 int ephyrGLXGetIntegerv(__GLXclientState * a_cl, GLbyte * a_pc);
78 int ephyrGLXGetIntegervSwap(__GLXclientState * a_cl, GLbyte * a_pc);
79 int ephyrGLXIsDirect(__GLXclientState * a_cl, GLbyte * a_pc);
80 int ephyrGLXIsDirectSwap(__GLXclientState * a_cl, GLbyte * a_pc);
81
82 Bool
83 ephyrHijackGLXExtension(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
163 int
164 ephyrGLXQueryVersion(__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
203 int
204 ephyrGLXQueryVersionSwap(__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
216 static int
217 ephyrGLXGetVisualConfigsReal(__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
272 static int
273 ephyrGLXGetFBConfigsSGIXReal(__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
328 int
329 ephyrGLXGetVisualConfigs(__GLXclientState * a_cl, GLbyte * a_pc)
330 {
331 return ephyrGLXGetVisualConfigsReal(a_cl, a_pc, FALSE);
332 }
333
334 int
335 ephyrGLXGetVisualConfigsSwap(__GLXclientState * a_cl, GLbyte * a_pc)
336 {
337 return ephyrGLXGetVisualConfigsReal(a_cl, a_pc, TRUE);
338 }
339
340 int
341 ephyrGLXClientInfo(__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
358 int
359 ephyrGLXClientInfoSwap(__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
373 int
374 ephyrGLXQueryServerString(__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
412 int
413 ephyrGLXQueryServerStringSwap(__GLXclientState * a_cl, GLbyte * a_pc)
414 {
415 EPHYR_LOG_ERROR("not yet implemented\n");
416 return BadImplementation;
417 }
418
419 int
420 ephyrGLXGetFBConfigsSGIX(__GLXclientState * a_cl, GLbyte * a_pc)
421 {
422 return ephyrGLXGetFBConfigsSGIXReal(a_cl, a_pc, FALSE);
423 }
424
425 int
426 ephyrGLXGetFBConfigsSGIXSwap(__GLXclientState * a_cl, GLbyte * a_pc)
427 {
428 return ephyrGLXGetFBConfigsSGIXReal(a_cl, a_pc, TRUE);
429 }
430
431 static int
432 ephyrGLXCreateContextReal(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
478 static int
479 ephyrGLXCreateNewContextReal(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
517 int
518 ephyrGLXCreateContext(__GLXclientState * cl, GLbyte * pc)
519 {
520 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
521
522 return ephyrGLXCreateContextReal(req, FALSE);
523 }
524
525 int
526 ephyrGLXCreateContextSwap(__GLXclientState * cl, GLbyte * pc)
527 {
528 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
529
530 return ephyrGLXCreateContextReal(req, TRUE);
531 }
532
533 int
534 ephyrGLXCreateNewContext(__GLXclientState * cl, GLbyte * pc)
535 {
536 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
537
538 return ephyrGLXCreateNewContextReal(req, FALSE);
539 }
540
541 int
542 ephyrGLXCreateNewContextSwap(__GLXclientState * cl, GLbyte * pc)
543 {
544 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
545
546 return ephyrGLXCreateNewContextReal(req, TRUE);
547 }
548
549 static int
550 ephyrGLXDestroyContextReal(__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
570 int
571 ephyrGLXDestroyContext(__GLXclientState * a_cl, GLbyte * a_pc)
572 {
573 return ephyrGLXDestroyContextReal(a_cl, a_pc, FALSE);
574 }
575
576 int
577 ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc)
578 {
579 return ephyrGLXDestroyContextReal(a_cl, a_pc, TRUE);
580 }
581
582 static int
583 ephyrGLXMakeCurrentReal(__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
634 int
635 ephyrGLXMakeCurrent(__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
642 int
643 ephyrGLXMakeCurrentSwap(__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
656 int
657 ephyrGLXMakeCurrentReadSGI(__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
665 int
666 ephyrGLXMakeCurrentReadSGISwap(__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
680 int
681 ephyrGLXMakeContextCurrent(__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
689 int
690 ephyrGLXMakeContextCurrentSwap(__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
704 static int
705 ephyrGLXGetStringReal(__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
753 int
754 ephyrGLXGetString(__GLXclientState * a_cl, GLbyte * a_pc)
755 {
756 return ephyrGLXGetStringReal(a_cl, a_pc, FALSE);
757 }
758
759 int
760 ephyrGLXGetStringSwap(__GLXclientState * a_cl, GLbyte * a_pc)
761 {
762 return ephyrGLXGetStringReal(a_cl, a_pc, TRUE);
763 }
764
765 static int
766 ephyrGLXGetIntegervReal(__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
800 int
801 ephyrGLXGetIntegerv(__GLXclientState * a_cl, GLbyte * a_pc)
802 {
803 return ephyrGLXGetIntegervReal(a_cl, a_pc, FALSE);
804 }
805
806 int
807 ephyrGLXGetIntegervSwap(__GLXclientState * a_cl, GLbyte * a_pc)
808 {
809 return ephyrGLXGetIntegervReal(a_cl, a_pc, TRUE);
810 }
811
812 static int
813 ephyrGLXIsDirectReal(__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
844 int
845 ephyrGLXIsDirect(__GLXclientState * a_cl, GLbyte * a_pc)
846 {
847 return ephyrGLXIsDirectReal(a_cl, a_pc, FALSE);
848 }
849
850 int
851 ephyrGLXIsDirectSwap(__GLXclientState * a_cl, GLbyte * a_pc)
852 {
853 return ephyrGLXIsDirectReal(a_cl, a_pc, TRUE);
854 }