native_ximage.c revision ae3926011e6bd08ac921209cb4b189df4c255007
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 45enum ximage_surface_type { 46 XIMAGE_SURFACE_TYPE_WINDOW, 47 XIMAGE_SURFACE_TYPE_PIXMAP, 48 XIMAGE_SURFACE_TYPE_PBUFFER 49}; 50 51struct 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 66struct ximage_buffer { 67 XImage *ximage; 68 69 struct pipe_texture *texture; 70 XShmSegmentInfo *shm_info; 71 boolean xshm_attached; 72}; 73 74struct 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 91struct ximage_config { 92 struct native_config base; 93 const XVisualInfo *visual; 94}; 95 96static INLINE struct ximage_display * 97ximage_display(const struct native_display *ndpy) 98{ 99 return (struct ximage_display *) ndpy; 100} 101 102static INLINE struct ximage_surface * 103ximage_surface(const struct native_surface *nsurf) 104{ 105 return (struct ximage_surface *) nsurf; 106} 107 108static INLINE struct ximage_config * 109ximage_config(const struct native_config *nconf) 110{ 111 return (struct ximage_config *) nconf; 112} 113 114static void 115ximage_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 136static boolean 137ximage_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 */ 204static boolean 205ximage_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 */ 235static boolean 236ximage_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 284static boolean 285ximage_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 332static boolean 333ximage_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 346static boolean 347ximage_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 372static boolean 373ximage_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 408static void 409ximage_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 416static void 417ximage_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 437static struct ximage_surface * 438ximage_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 517static struct native_surface * 518ximage_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 529static struct native_surface * 530ximage_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 541static struct native_surface * 542ximage_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 557static enum pipe_format 558choose_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_B8G8R8A8_UNORM; 565 break; 566 case 24: 567 fmt = PIPE_FORMAT_B8G8R8X8_UNORM; 568 break; 569 case 16: 570 fmt = PIPE_FORMAT_B5G6R5_UNORM; 571 break; 572 default: 573 fmt = PIPE_FORMAT_NONE; 574 break; 575 } 576 577 return fmt; 578} 579 580static const struct native_config ** 581ximage_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_Z24S8_UNORM; 624 xconf->base.stencil_format = PIPE_FORMAT_Z24S8_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 660static boolean 661ximage_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_B8G8R8A8_UNORM; 673 break; 674 case 24: 675 fmt = PIPE_FORMAT_B8G8R8X8_UNORM; 676 break; 677 case 16: 678 fmt = PIPE_FORMAT_B5G6R5_UNORM; 679 break; 680 default: 681 fmt = PIPE_FORMAT_NONE; 682 break; 683 } 684 685 return (fmt == nconf->color_format); 686} 687 688static void 689ximage_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 705struct native_display * 706x11_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} 747