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
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 debug_screen_wrap( 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 (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
153fail:
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
170void
171graw_set_display_func( void (*draw)( void ) )
172{
173   graw.draw = draw;
174}
175
176void
177graw_main_loop( void )
178{
179   int i;
180   for (i = 0; i < 10; i++) {
181      graw.draw();
182      sleep(1);
183   }
184}
185
186