1bf215546Sopenharmony_ci#include "pipe/p_compiler.h" 2bf215546Sopenharmony_ci#include "pipe/p_context.h" 3bf215546Sopenharmony_ci#include "pipe/p_screen.h" 4bf215546Sopenharmony_ci#include "util/u_debug.h" 5bf215546Sopenharmony_ci#include "util/u_memory.h" 6bf215546Sopenharmony_ci#include "target-helpers/inline_sw_helper.h" 7bf215546Sopenharmony_ci#include "target-helpers/inline_debug_helper.h" 8bf215546Sopenharmony_ci#include "frontend/xlibsw_api.h" 9bf215546Sopenharmony_ci#include "frontend/graw.h" 10bf215546Sopenharmony_ci#include "sw/xlib/xlib_sw_winsys.h" 11bf215546Sopenharmony_ci 12bf215546Sopenharmony_ci#include <X11/Xlib.h> 13bf215546Sopenharmony_ci#include <X11/Xlibint.h> 14bf215546Sopenharmony_ci#include <X11/Xutil.h> 15bf215546Sopenharmony_ci#include <stdio.h> 16bf215546Sopenharmony_ci 17bf215546Sopenharmony_cistatic struct { 18bf215546Sopenharmony_ci Display *display; 19bf215546Sopenharmony_ci void (*draw)(void); 20bf215546Sopenharmony_ci} graw; 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_cistatic struct pipe_screen * 24bf215546Sopenharmony_cigraw_create_screen( void ) 25bf215546Sopenharmony_ci{ 26bf215546Sopenharmony_ci struct pipe_screen *screen = NULL; 27bf215546Sopenharmony_ci struct sw_winsys *winsys = NULL; 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci /* Create the underlying winsys, which performs presents to Xlib 30bf215546Sopenharmony_ci * drawables: 31bf215546Sopenharmony_ci */ 32bf215546Sopenharmony_ci winsys = xlib_create_sw_winsys( graw.display ); 33bf215546Sopenharmony_ci if (winsys == NULL) 34bf215546Sopenharmony_ci return NULL; 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci screen = sw_screen_create( winsys ); 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci /* Inject any wrapping layers we want to here: 39bf215546Sopenharmony_ci */ 40bf215546Sopenharmony_ci return debug_screen_wrap( screen ); 41bf215546Sopenharmony_ci} 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistruct pipe_screen * 45bf215546Sopenharmony_cigraw_create_window_and_screen( int x, 46bf215546Sopenharmony_ci int y, 47bf215546Sopenharmony_ci unsigned width, 48bf215546Sopenharmony_ci unsigned height, 49bf215546Sopenharmony_ci enum pipe_format format, 50bf215546Sopenharmony_ci void **handle) 51bf215546Sopenharmony_ci{ 52bf215546Sopenharmony_ci struct pipe_screen *screen = NULL; 53bf215546Sopenharmony_ci struct xlib_drawable *xlib_handle = NULL; 54bf215546Sopenharmony_ci XSetWindowAttributes attr; 55bf215546Sopenharmony_ci Window root; 56bf215546Sopenharmony_ci Window win = 0; 57bf215546Sopenharmony_ci XVisualInfo templat, *visinfo = NULL; 58bf215546Sopenharmony_ci unsigned mask; 59bf215546Sopenharmony_ci int n; 60bf215546Sopenharmony_ci int scrnum; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci graw.display = XOpenDisplay(NULL); 63bf215546Sopenharmony_ci if (graw.display == NULL) 64bf215546Sopenharmony_ci return NULL; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci scrnum = DefaultScreen( graw.display ); 67bf215546Sopenharmony_ci root = RootWindow( graw.display, scrnum ); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci if (graw.display == NULL) 71bf215546Sopenharmony_ci goto fail; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci xlib_handle = CALLOC_STRUCT(xlib_drawable); 74bf215546Sopenharmony_ci if (xlib_handle == NULL) 75bf215546Sopenharmony_ci goto fail; 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci mask = VisualScreenMask | VisualDepthMask | VisualClassMask; 79bf215546Sopenharmony_ci templat.screen = DefaultScreen(graw.display); 80bf215546Sopenharmony_ci templat.depth = 32; 81bf215546Sopenharmony_ci templat.class = TrueColor; 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci visinfo = XGetVisualInfo(graw.display, mask, &templat, &n); 84bf215546Sopenharmony_ci if (!visinfo) { 85bf215546Sopenharmony_ci printf("Error: couldn't get an RGB, Double-buffered visual\n"); 86bf215546Sopenharmony_ci exit(1); 87bf215546Sopenharmony_ci } 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci /* See if the requirested pixel format matches the visual */ 90bf215546Sopenharmony_ci if (visinfo->red_mask == 0xff0000 && 91bf215546Sopenharmony_ci visinfo->green_mask == 0xff00 && 92bf215546Sopenharmony_ci visinfo->blue_mask == 0xff) { 93bf215546Sopenharmony_ci if (format != PIPE_FORMAT_BGRA8888_UNORM) 94bf215546Sopenharmony_ci goto fail; 95bf215546Sopenharmony_ci } 96bf215546Sopenharmony_ci else if (visinfo->red_mask == 0xff && 97bf215546Sopenharmony_ci visinfo->green_mask == 0xff00 && 98bf215546Sopenharmony_ci visinfo->blue_mask == 0xff0000) { 99bf215546Sopenharmony_ci if (format != PIPE_FORMAT_RGBA8888_UNORM) 100bf215546Sopenharmony_ci goto fail; 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci else { 103bf215546Sopenharmony_ci goto fail; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci /* window attributes */ 107bf215546Sopenharmony_ci attr.background_pixel = 0; 108bf215546Sopenharmony_ci attr.border_pixel = 0; 109bf215546Sopenharmony_ci attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone); 110bf215546Sopenharmony_ci attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; 111bf215546Sopenharmony_ci /* XXX this is a bad way to get a borderless window! */ 112bf215546Sopenharmony_ci mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci win = XCreateWindow( graw.display, root, x, y, width, height, 115bf215546Sopenharmony_ci 0, visinfo->depth, InputOutput, 116bf215546Sopenharmony_ci visinfo->visual, mask, &attr ); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci /* set hints and properties */ 120bf215546Sopenharmony_ci { 121bf215546Sopenharmony_ci char *name = NULL; 122bf215546Sopenharmony_ci XSizeHints sizehints; 123bf215546Sopenharmony_ci sizehints.x = x; 124bf215546Sopenharmony_ci sizehints.y = y; 125bf215546Sopenharmony_ci sizehints.width = width; 126bf215546Sopenharmony_ci sizehints.height = height; 127bf215546Sopenharmony_ci sizehints.flags = USSize | USPosition; 128bf215546Sopenharmony_ci XSetNormalHints(graw.display, win, &sizehints); 129bf215546Sopenharmony_ci XSetStandardProperties(graw.display, win, name, name, 130bf215546Sopenharmony_ci None, (char **)NULL, 0, &sizehints); 131bf215546Sopenharmony_ci } 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci XMapWindow(graw.display, win); 134bf215546Sopenharmony_ci while (1) { 135bf215546Sopenharmony_ci XEvent e; 136bf215546Sopenharmony_ci XNextEvent( graw.display, &e ); 137bf215546Sopenharmony_ci if (e.type == MapNotify && e.xmap.window == win) { 138bf215546Sopenharmony_ci break; 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci xlib_handle->visual = visinfo->visual; 143bf215546Sopenharmony_ci xlib_handle->drawable = (Drawable)win; 144bf215546Sopenharmony_ci xlib_handle->depth = visinfo->depth; 145bf215546Sopenharmony_ci *handle = (void *)xlib_handle; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci screen = graw_create_screen(); 148bf215546Sopenharmony_ci if (screen == NULL) 149bf215546Sopenharmony_ci goto fail; 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci free(visinfo); 152bf215546Sopenharmony_ci return screen; 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_cifail: 155bf215546Sopenharmony_ci if (screen) 156bf215546Sopenharmony_ci screen->destroy(screen); 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci FREE(xlib_handle); 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci free(visinfo); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci if (win) 163bf215546Sopenharmony_ci XDestroyWindow(graw.display, win); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci return NULL; 166bf215546Sopenharmony_ci} 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_civoid 170bf215546Sopenharmony_cigraw_set_display_func( void (*draw)( void ) ) 171bf215546Sopenharmony_ci{ 172bf215546Sopenharmony_ci graw.draw = draw; 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_civoid 176bf215546Sopenharmony_cigraw_main_loop( void ) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci int i; 179bf215546Sopenharmony_ci for (i = 0; i < 10; i++) { 180bf215546Sopenharmony_ci graw.draw(); 181bf215546Sopenharmony_ci sleep(1); 182bf215546Sopenharmony_ci } 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci 185