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 "frontend/xlibsw_api.h"
9 #include "frontend/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 *
graw_create_screen(void)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 *
graw_create_window_and_screen(int x,int y,unsigned width,unsigned height,enum pipe_format format,void ** handle)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
graw_set_display_func(void (* draw)(void))170 graw_set_display_func( void (*draw)( void ) )
171 {
172    graw.draw = draw;
173 }
174 
175 void
graw_main_loop(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