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