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