Merge branch 'gallium-no-rhw-position'
[mesa.git] / src / gallium / state_trackers / egl / x11 / native_ximage.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.8
4 *
5 * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <assert.h>
26 #include <sys/ipc.h>
27 #include <sys/types.h>
28 #include <sys/shm.h>
29 #include <X11/Xlib.h>
30 #include <X11/Xutil.h>
31 #include <X11/extensions/XShm.h>
32 #include "util/u_memory.h"
33 #include "util/u_math.h"
34 #include "util/u_format.h"
35 #include "pipe/p_compiler.h"
36 #include "util/u_simple_screen.h"
37 #include "util/u_inlines.h"
38 #include "softpipe/sp_winsys.h"
39 #include "egllog.h"
40
41 #include "sw_winsys.h"
42 #include "native_x11.h"
43 #include "x11_screen.h"
44
45 enum ximage_surface_type {
46 XIMAGE_SURFACE_TYPE_WINDOW,
47 XIMAGE_SURFACE_TYPE_PIXMAP,
48 XIMAGE_SURFACE_TYPE_PBUFFER
49 };
50
51 struct ximage_display {
52 struct native_display base;
53 Display *dpy;
54 boolean own_dpy;
55
56 struct x11_screen *xscr;
57 int xscr_number;
58
59 boolean use_xshm;
60
61 struct pipe_winsys *winsys;
62 struct ximage_config *configs;
63 int num_configs;
64 };
65
66 struct ximage_buffer {
67 XImage *ximage;
68
69 struct pipe_texture *texture;
70 XShmSegmentInfo *shm_info;
71 boolean xshm_attached;
72 };
73
74 struct ximage_surface {
75 struct native_surface base;
76 Drawable drawable;
77 enum ximage_surface_type type;
78 enum pipe_format color_format;
79 XVisualInfo visual;
80 struct ximage_display *xdpy;
81
82 GC gc;
83
84 unsigned int server_stamp;
85 unsigned int client_stamp;
86 int width, height;
87 struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
88 uint valid_mask;
89 };
90
91 struct ximage_config {
92 struct native_config base;
93 const XVisualInfo *visual;
94 };
95
96 static INLINE struct ximage_display *
97 ximage_display(const struct native_display *ndpy)
98 {
99 return (struct ximage_display *) ndpy;
100 }
101
102 static INLINE struct ximage_surface *
103 ximage_surface(const struct native_surface *nsurf)
104 {
105 return (struct ximage_surface *) nsurf;
106 }
107
108 static INLINE struct ximage_config *
109 ximage_config(const struct native_config *nconf)
110 {
111 return (struct ximage_config *) nconf;
112 }
113
114 static void
115 ximage_surface_free_buffer(struct native_surface *nsurf,
116 enum native_attachment which)
117 {
118 struct ximage_surface *xsurf = ximage_surface(nsurf);
119 struct ximage_buffer *xbuf = &xsurf->buffers[which];
120
121 pipe_texture_reference(&xbuf->texture, NULL);
122
123 if (xbuf->shm_info) {
124 if (xbuf->xshm_attached)
125 XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
126 if (xbuf->shm_info->shmaddr != (void *) -1)
127 shmdt(xbuf->shm_info->shmaddr);
128 if (xbuf->shm_info->shmid != -1)
129 shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
130
131 xbuf->shm_info->shmaddr = (void *) -1;
132 xbuf->shm_info->shmid = -1;
133 }
134 }
135
136 static boolean
137 ximage_surface_alloc_buffer(struct native_surface *nsurf,
138 enum native_attachment which)
139 {
140 struct ximage_surface *xsurf = ximage_surface(nsurf);
141 struct ximage_buffer *xbuf = &xsurf->buffers[which];
142 struct pipe_screen *screen = xsurf->xdpy->base.screen;
143 struct pipe_texture templ;
144
145 /* free old data */
146 if (xbuf->texture)
147 ximage_surface_free_buffer(&xsurf->base, which);
148
149 memset(&templ, 0, sizeof(templ));
150 templ.target = PIPE_TEXTURE_2D;
151 templ.format = xsurf->color_format;
152 templ.width0 = xsurf->width;
153 templ.height0 = xsurf->height;
154 templ.depth0 = 1;
155 templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
156
157 if (xbuf->shm_info) {
158 struct pipe_buffer *pbuf;
159 unsigned stride, size;
160 void *addr = NULL;
161
162 stride = util_format_get_stride(xsurf->color_format, xsurf->width);
163 /* alignment should depend on visual? */
164 stride = align(stride, 4);
165 size = stride * xsurf->height;
166
167 /* create and attach shm object */
168 xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
169 if (xbuf->shm_info->shmid != -1) {
170 xbuf->shm_info->shmaddr =
171 shmat(xbuf->shm_info->shmid, NULL, 0);
172 if (xbuf->shm_info->shmaddr != (void *) -1) {
173 if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
174 addr = xbuf->shm_info->shmaddr;
175 xbuf->xshm_attached = TRUE;
176 }
177 }
178 }
179
180 if (addr) {
181 pbuf = screen->user_buffer_create(screen, addr, size);
182 if (pbuf) {
183 xbuf->texture =
184 screen->texture_blanket(screen, &templ, &stride, pbuf);
185 pipe_buffer_reference(&pbuf, NULL);
186 }
187 }
188 }
189 else {
190 xbuf->texture = screen->texture_create(screen, &templ);
191 }
192
193 /* clean up the buffer if allocation failed */
194 if (!xbuf->texture)
195 ximage_surface_free_buffer(&xsurf->base, which);
196
197 return (xbuf->texture != NULL);
198 }
199
200 /**
201 * Update the geometry of the surface. Return TRUE if the geometry has changed
202 * since last call.
203 */
204 static boolean
205 ximage_surface_update_geometry(struct native_surface *nsurf)
206 {
207 struct ximage_surface *xsurf = ximage_surface(nsurf);
208 Status ok;
209 Window root;
210 int x, y;
211 unsigned int w, h, border, depth;
212 boolean updated = FALSE;
213
214 /* pbuffer has fixed geometry */
215 if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
216 return FALSE;
217
218 ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
219 &root, &x, &y, &w, &h, &border, &depth);
220 if (ok && (xsurf->width != w || xsurf->height != h)) {
221 xsurf->width = w;
222 xsurf->height = h;
223
224 xsurf->server_stamp++;
225 updated = TRUE;
226 }
227
228 return updated;
229 }
230
231 /**
232 * Update the buffers of the surface. It is a slow function due to the
233 * round-trip to the server.
234 */
235 static boolean
236 ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
237 {
238 struct ximage_surface *xsurf = ximage_surface(nsurf);
239 boolean updated;
240 uint new_valid;
241 int att;
242
243 updated = ximage_surface_update_geometry(&xsurf->base);
244 if (updated) {
245 /* all buffers become invalid */
246 xsurf->valid_mask = 0x0;
247 }
248 else {
249 buffer_mask &= ~xsurf->valid_mask;
250 /* all requested buffers are valid */
251 if (!buffer_mask) {
252 xsurf->client_stamp = xsurf->server_stamp;
253 return TRUE;
254 }
255 }
256
257 new_valid = 0x0;
258 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
259 if (native_attachment_mask_test(buffer_mask, att)) {
260 struct ximage_buffer *xbuf = &xsurf->buffers[att];
261
262 /* reallocate the texture */
263 if (!ximage_surface_alloc_buffer(&xsurf->base, att))
264 break;
265
266 /* update ximage */
267 if (xbuf->ximage) {
268 xbuf->ximage->width = xsurf->width;
269 xbuf->ximage->height = xsurf->height;
270 }
271
272 new_valid |= (1 << att);
273 if (buffer_mask == new_valid)
274 break;
275 }
276 }
277
278 xsurf->valid_mask |= new_valid;
279 xsurf->client_stamp = xsurf->server_stamp;
280
281 return (new_valid == buffer_mask);
282 }
283
284 static boolean
285 ximage_surface_draw_buffer(struct native_surface *nsurf,
286 enum native_attachment which)
287 {
288 struct ximage_surface *xsurf = ximage_surface(nsurf);
289 struct ximage_buffer *xbuf = &xsurf->buffers[which];
290 struct pipe_screen *screen = xsurf->xdpy->base.screen;
291 struct pipe_transfer *transfer;
292
293 if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
294 return TRUE;
295
296 assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
297
298 transfer = screen->get_tex_transfer(screen, xbuf->texture,
299 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
300 if (!transfer)
301 return FALSE;
302
303 xbuf->ximage->bytes_per_line = transfer->stride;
304 xbuf->ximage->data = screen->transfer_map(screen, transfer);
305 if (!xbuf->ximage->data) {
306 screen->tex_transfer_destroy(transfer);
307 return FALSE;
308 }
309
310
311 if (xbuf->shm_info)
312 XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
313 xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
314 else
315 XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
316 xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
317
318 xbuf->ximage->data = NULL;
319 screen->transfer_unmap(screen, transfer);
320
321 /*
322 * softpipe allows the pipe transfer to be re-used, but we don't want to
323 * rely on that behavior.
324 */
325 screen->tex_transfer_destroy(transfer);
326
327 XSync(xsurf->xdpy->dpy, FALSE);
328
329 return TRUE;
330 }
331
332 static boolean
333 ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
334 {
335 struct ximage_surface *xsurf = ximage_surface(nsurf);
336 boolean ret;
337
338 ret = ximage_surface_draw_buffer(&xsurf->base,
339 NATIVE_ATTACHMENT_FRONT_LEFT);
340 /* force buffers to be updated in next validation call */
341 xsurf->server_stamp++;
342
343 return ret;
344 }
345
346 static boolean
347 ximage_surface_swap_buffers(struct native_surface *nsurf)
348 {
349 struct ximage_surface *xsurf = ximage_surface(nsurf);
350 struct ximage_buffer *xfront, *xback, xtmp;
351 boolean ret;
352
353 /* display the back buffer first */
354 ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
355 /* force buffers to be updated in next validation call */
356 xsurf->server_stamp++;
357
358 xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
359 xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
360
361 /* skip swapping so that the front buffer is allocated only when needed */
362 if (!xfront->texture)
363 return ret;
364
365 xtmp = *xfront;
366 *xfront = *xback;
367 *xback = xtmp;
368
369 return ret;
370 }
371
372 static boolean
373 ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
374 unsigned int *seq_num, struct pipe_texture **textures,
375 int *width, int *height)
376 {
377 struct ximage_surface *xsurf = ximage_surface(nsurf);
378
379 if (xsurf->client_stamp != xsurf->server_stamp ||
380 (xsurf->valid_mask & attachment_mask) != attachment_mask) {
381 if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
382 return FALSE;
383 }
384
385 if (seq_num)
386 *seq_num = xsurf->client_stamp;
387
388 if (textures) {
389 int att;
390 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
391 if (native_attachment_mask_test(attachment_mask, att)) {
392 struct ximage_buffer *xbuf = &xsurf->buffers[att];
393
394 textures[att] = NULL;
395 pipe_texture_reference(&textures[att], xbuf->texture);
396 }
397 }
398 }
399
400 if (width)
401 *width = xsurf->width;
402 if (height)
403 *height = xsurf->height;
404
405 return TRUE;
406 }
407
408 static void
409 ximage_surface_wait(struct native_surface *nsurf)
410 {
411 struct ximage_surface *xsurf = ximage_surface(nsurf);
412 XSync(xsurf->xdpy->dpy, FALSE);
413 /* TODO XGetImage and update the front texture */
414 }
415
416 static void
417 ximage_surface_destroy(struct native_surface *nsurf)
418 {
419 struct ximage_surface *xsurf = ximage_surface(nsurf);
420 int i;
421
422 for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
423 struct ximage_buffer *xbuf = &xsurf->buffers[i];
424 ximage_surface_free_buffer(&xsurf->base, i);
425 /* xbuf->shm_info is owned by xbuf->ximage? */
426 if (xbuf->ximage) {
427 XDestroyImage(xbuf->ximage);
428 xbuf->ximage = NULL;
429 }
430 }
431
432 if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
433 XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
434 free(xsurf);
435 }
436
437 static struct ximage_surface *
438 ximage_display_create_surface(struct native_display *ndpy,
439 enum ximage_surface_type type,
440 Drawable drawable,
441 const struct native_config *nconf)
442 {
443 struct ximage_display *xdpy = ximage_display(ndpy);
444 struct ximage_config *xconf = ximage_config(nconf);
445 struct ximage_surface *xsurf;
446 int i;
447
448 xsurf = CALLOC_STRUCT(ximage_surface);
449 if (!xsurf)
450 return NULL;
451
452 xsurf->xdpy = xdpy;
453 xsurf->type = type;
454 xsurf->color_format = xconf->base.color_format;
455 xsurf->drawable = drawable;
456
457 if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
458 xsurf->drawable = drawable;
459 xsurf->visual = *xconf->visual;
460
461 xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
462 if (!xsurf->gc) {
463 free(xsurf);
464 return NULL;
465 }
466
467 /* initialize the geometry */
468 ximage_surface_update_buffers(&xsurf->base, 0x0);
469
470 for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
471 struct ximage_buffer *xbuf = &xsurf->buffers[i];
472
473 if (xdpy->use_xshm) {
474 xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
475 if (xbuf->shm_info) {
476 /* initialize shm info */
477 xbuf->shm_info->shmid = -1;
478 xbuf->shm_info->shmaddr = (void *) -1;
479 xbuf->shm_info->readOnly = TRUE;
480
481 xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
482 xsurf->visual.visual,
483 xsurf->visual.depth,
484 ZPixmap, NULL,
485 xbuf->shm_info,
486 0, 0);
487 }
488 }
489 else {
490 xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
491 xsurf->visual.visual,
492 xsurf->visual.depth,
493 ZPixmap, 0, /* format, offset */
494 NULL, /* data */
495 0, 0, /* size */
496 8, /* bitmap_pad */
497 0); /* bytes_per_line */
498 }
499
500 if (!xbuf->ximage) {
501 XFreeGC(xdpy->dpy, xsurf->gc);
502 free(xsurf);
503 return NULL;
504 }
505 }
506 }
507
508 xsurf->base.destroy = ximage_surface_destroy;
509 xsurf->base.swap_buffers = ximage_surface_swap_buffers;
510 xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer;
511 xsurf->base.validate = ximage_surface_validate;
512 xsurf->base.wait = ximage_surface_wait;
513
514 return xsurf;
515 }
516
517 static struct native_surface *
518 ximage_display_create_window_surface(struct native_display *ndpy,
519 EGLNativeWindowType win,
520 const struct native_config *nconf)
521 {
522 struct ximage_surface *xsurf;
523
524 xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW,
525 (Drawable) win, nconf);
526 return (xsurf) ? &xsurf->base : NULL;
527 }
528
529 static struct native_surface *
530 ximage_display_create_pixmap_surface(struct native_display *ndpy,
531 EGLNativePixmapType pix,
532 const struct native_config *nconf)
533 {
534 struct ximage_surface *xsurf;
535
536 xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP,
537 (Drawable) pix, nconf);
538 return (xsurf) ? &xsurf->base : NULL;
539 }
540
541 static struct native_surface *
542 ximage_display_create_pbuffer_surface(struct native_display *ndpy,
543 const struct native_config *nconf,
544 uint width, uint height)
545 {
546 struct ximage_surface *xsurf;
547
548 xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER,
549 (Drawable) None, nconf);
550 if (xsurf) {
551 xsurf->width = width;
552 xsurf->height = height;
553 }
554 return (xsurf) ? &xsurf->base : NULL;
555 }
556
557 static enum pipe_format
558 choose_format(const XVisualInfo *vinfo)
559 {
560 enum pipe_format fmt;
561 /* TODO elaborate the formats */
562 switch (vinfo->depth) {
563 case 32:
564 fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
565 break;
566 case 24:
567 fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
568 break;
569 case 16:
570 fmt = PIPE_FORMAT_R5G6B5_UNORM;
571 break;
572 default:
573 fmt = PIPE_FORMAT_NONE;
574 break;
575 }
576
577 return fmt;
578 }
579
580 static const struct native_config **
581 ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
582 {
583 struct ximage_display *xdpy = ximage_display(ndpy);
584 const struct native_config **configs;
585 int i;
586
587 /* first time */
588 if (!xdpy->configs) {
589 const XVisualInfo *visuals;
590 int num_visuals, count, j;
591
592 visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals);
593 if (!visuals)
594 return NULL;
595
596 /*
597 * Create two configs for each visual.
598 * One with depth/stencil buffer; one without
599 */
600 xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs));
601 if (!xdpy->configs)
602 return NULL;
603
604 count = 0;
605 for (i = 0; i < num_visuals; i++) {
606 for (j = 0; j < 2; j++) {
607 struct ximage_config *xconf = &xdpy->configs[count];
608 __GLcontextModes *mode = &xconf->base.mode;
609
610 xconf->visual = &visuals[i];
611 xconf->base.color_format = choose_format(xconf->visual);
612 if (xconf->base.color_format == PIPE_FORMAT_NONE)
613 continue;
614
615 x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode);
616 /* support double buffer mode */
617 mode->doubleBufferMode = TRUE;
618
619 xconf->base.depth_format = PIPE_FORMAT_NONE;
620 xconf->base.stencil_format = PIPE_FORMAT_NONE;
621 /* create the second config with depth/stencil buffer */
622 if (j == 1) {
623 xconf->base.depth_format = PIPE_FORMAT_S8Z24_UNORM;
624 xconf->base.stencil_format = PIPE_FORMAT_S8Z24_UNORM;
625 mode->depthBits = 24;
626 mode->stencilBits = 8;
627 mode->haveDepthBuffer = TRUE;
628 mode->haveStencilBuffer = TRUE;
629 }
630
631 mode->maxPbufferWidth = 4096;
632 mode->maxPbufferHeight = 4096;
633 mode->maxPbufferPixels = 4096 * 4096;
634 mode->drawableType =
635 GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
636 mode->swapMethod = GLX_SWAP_EXCHANGE_OML;
637
638 if (mode->alphaBits)
639 mode->bindToTextureRgba = TRUE;
640 else
641 mode->bindToTextureRgb = TRUE;
642
643 count++;
644 }
645 }
646
647 xdpy->num_configs = count;
648 }
649
650 configs = malloc(xdpy->num_configs * sizeof(*configs));
651 if (configs) {
652 for (i = 0; i < xdpy->num_configs; i++)
653 configs[i] = (const struct native_config *) &xdpy->configs[i];
654 if (num_configs)
655 *num_configs = xdpy->num_configs;
656 }
657 return configs;
658 }
659
660 static boolean
661 ximage_display_is_pixmap_supported(struct native_display *ndpy,
662 EGLNativePixmapType pix,
663 const struct native_config *nconf)
664 {
665 struct ximage_display *xdpy = ximage_display(ndpy);
666 enum pipe_format fmt;
667 uint depth;
668
669 depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
670 switch (depth) {
671 case 32:
672 fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
673 break;
674 case 24:
675 fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
676 break;
677 case 16:
678 fmt = PIPE_FORMAT_R5G6B5_UNORM;
679 break;
680 default:
681 fmt = PIPE_FORMAT_NONE;
682 break;
683 }
684
685 return (fmt == nconf->color_format);
686 }
687
688 static void
689 ximage_display_destroy(struct native_display *ndpy)
690 {
691 struct ximage_display *xdpy = ximage_display(ndpy);
692
693 if (xdpy->configs)
694 free(xdpy->configs);
695
696 xdpy->base.screen->destroy(xdpy->base.screen);
697 free(xdpy->winsys);
698
699 x11_screen_destroy(xdpy->xscr);
700 if (xdpy->own_dpy)
701 XCloseDisplay(xdpy->dpy);
702 free(xdpy);
703 }
704
705 struct native_display *
706 x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
707 {
708 struct ximage_display *xdpy;
709
710 xdpy = CALLOC_STRUCT(ximage_display);
711 if (!xdpy)
712 return NULL;
713
714 xdpy->dpy = dpy;
715 if (!xdpy->dpy) {
716 xdpy->dpy = XOpenDisplay(NULL);
717 if (!xdpy->dpy) {
718 free(xdpy);
719 return NULL;
720 }
721 xdpy->own_dpy = TRUE;
722 }
723
724 xdpy->xscr_number = DefaultScreen(xdpy->dpy);
725 xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
726 if (!xdpy->xscr) {
727 free(xdpy);
728 return NULL;
729 }
730
731 xdpy->use_xshm =
732 (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
733
734 xdpy->winsys = create_sw_winsys();
735 xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
736
737 xdpy->base.destroy = ximage_display_destroy;
738
739 xdpy->base.get_configs = ximage_display_get_configs;
740 xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
741 xdpy->base.create_window_surface = ximage_display_create_window_surface;
742 xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
743 xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface;
744
745 return &xdpy->base;
746 }