graw_xlib.c revision 89deebb1af7191e9fd7432c181b166d13c659f15
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/wrap_screen.h"
7#include "target-helpers/inline_sw_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
16static struct {
17   Display *display;
18   void (*draw)(void);
19} graw;
20
21
22static struct pipe_screen *
23graw_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 gallium_wrap_screen( screen );
40}
41
42
43struct pipe_screen *
44graw_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 (format != PIPE_FORMAT_R8G8B8A8_UNORM)
70      goto fail;
71
72   if (graw.display == NULL)
73      goto fail;
74
75   xlib_handle = CALLOC_STRUCT(xlib_drawable);
76   if (xlib_handle == NULL)
77      goto fail;
78
79
80   mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
81   templat.screen = DefaultScreen(graw.display);
82   templat.depth = 32;
83   templat.class = TrueColor;
84
85   visinfo = XGetVisualInfo(graw.display, mask, &templat, &n);
86   if (!visinfo) {
87      printf("Error: couldn't get an RGB, Double-buffered visual\n");
88      exit(1);
89   }
90
91   /* window attributes */
92   attr.background_pixel = 0;
93   attr.border_pixel = 0;
94   attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone);
95   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
96   /* XXX this is a bad way to get a borderless window! */
97   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
98
99   win = XCreateWindow( graw.display, root, x, y, width, height,
100		        0, visinfo->depth, InputOutput,
101		        visinfo->visual, mask, &attr );
102
103
104   /* set hints and properties */
105   {
106      char *name = NULL;
107      XSizeHints sizehints;
108      sizehints.x = x;
109      sizehints.y = y;
110      sizehints.width  = width;
111      sizehints.height = height;
112      sizehints.flags = USSize | USPosition;
113      XSetNormalHints(graw.display, win, &sizehints);
114      XSetStandardProperties(graw.display, win, name, name,
115                              None, (char **)NULL, 0, &sizehints);
116   }
117
118   XMapWindow(graw.display, win);
119   while (1) {
120      XEvent e;
121      XNextEvent( graw.display, &e );
122      if (e.type == MapNotify && e.xmap.window == win) {
123	 break;
124      }
125   }
126
127   xlib_handle->visual = visinfo->visual;
128   xlib_handle->drawable = (Drawable)win;
129   xlib_handle->depth = visinfo->depth;
130   *handle = (void *)xlib_handle;
131
132   screen = graw_create_screen();
133   if (screen == NULL)
134      goto fail;
135
136   XFree(visinfo);
137   return screen;
138
139fail:
140   if (screen)
141      screen->destroy(screen);
142
143   if (xlib_handle)
144      FREE(xlib_handle);
145
146   if (visinfo)
147      XFree(visinfo);
148
149   if (win)
150      XDestroyWindow(graw.display, win);
151
152   return NULL;
153}
154
155
156void
157graw_set_display_func( void (*draw)( void ) )
158{
159   graw.draw = draw;
160}
161
162void
163graw_main_loop( void )
164{
165   int i;
166   for (i = 0; i < 10; i++) {
167      graw.draw();
168      sleep(1);
169   }
170}
171
172