#include "pipe/p_compiler.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "util/u_debug.h" #include "util/u_memory.h" #include "target-helpers/inline_sw_helper.h" #include "target-helpers/inline_debug_helper.h" #include "state_tracker/xlibsw_api.h" #include "state_tracker/graw.h" #include "sw/xlib/xlib_sw_winsys.h" #include <X11/Xlib.h> #include <X11/Xlibint.h> #include <X11/Xutil.h> #include <stdio.h> static struct { Display *display; void (*draw)(void); } graw; static struct pipe_screen * graw_create_screen( void ) { struct pipe_screen *screen = NULL; struct sw_winsys *winsys = NULL; /* Create the underlying winsys, which performs presents to Xlib * drawables: */ winsys = xlib_create_sw_winsys( graw.display ); if (winsys == NULL) return NULL; screen = sw_screen_create( winsys ); /* Inject any wrapping layers we want to here: */ return debug_screen_wrap( screen ); } struct pipe_screen * graw_create_window_and_screen( int x, int y, unsigned width, unsigned height, enum pipe_format format, void **handle) { struct pipe_screen *screen = NULL; struct xlib_drawable *xlib_handle = NULL; XSetWindowAttributes attr; Window root; Window win = 0; XVisualInfo templat, *visinfo = NULL; unsigned mask; int n; int scrnum; graw.display = XOpenDisplay(NULL); if (graw.display == NULL) return NULL; scrnum = DefaultScreen( graw.display ); root = RootWindow( graw.display, scrnum ); if (graw.display == NULL) goto fail; xlib_handle = CALLOC_STRUCT(xlib_drawable); if (xlib_handle == NULL) goto fail; mask = VisualScreenMask | VisualDepthMask | VisualClassMask; templat.screen = DefaultScreen(graw.display); templat.depth = 32; templat.class = TrueColor; visinfo = XGetVisualInfo(graw.display, mask, &templat, &n); if (!visinfo) { printf("Error: couldn't get an RGB, Double-buffered visual\n"); exit(1); } /* See if the requirested pixel format matches the visual */ if (visinfo->red_mask == 0xff0000 && visinfo->green_mask == 0xff00 && visinfo->blue_mask == 0xff) { if (format != PIPE_FORMAT_BGRA8888_UNORM) goto fail; } else if (visinfo->red_mask == 0xff && visinfo->green_mask == 0xff00 && visinfo->blue_mask == 0xff0000) { if (format != PIPE_FORMAT_RGBA8888_UNORM) goto fail; } else { goto fail; } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; /* XXX this is a bad way to get a borderless window! */ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow( graw.display, root, x, y, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); /* set hints and properties */ { char *name = NULL; XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(graw.display, win, &sizehints); XSetStandardProperties(graw.display, win, name, name, None, (char **)NULL, 0, &sizehints); } XMapWindow(graw.display, win); while (1) { XEvent e; XNextEvent( graw.display, &e ); if (e.type == MapNotify && e.xmap.window == win) { break; } } xlib_handle->visual = visinfo->visual; xlib_handle->drawable = (Drawable)win; xlib_handle->depth = visinfo->depth; *handle = (void *)xlib_handle; screen = graw_create_screen(); if (screen == NULL) goto fail; free(visinfo); return screen; fail: if (screen) screen->destroy(screen); FREE(xlib_handle); free(visinfo); if (win) XDestroyWindow(graw.display, win); return NULL; } void graw_set_display_func( void (*draw)( void ) ) { graw.draw = draw; } void graw_main_loop( void ) { int i; for (i = 0; i < 10; i++) { graw.draw(); sleep(1); } }