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
17static struct {
18   Display *display;
19   void (*draw)(void);
20} graw;
21
22
23static struct pipe_screen *
24graw_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
44struct pipe_screen *
45graw_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
154fail:
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
169void
170graw_set_display_func( void (*draw)( void ) )
171{
172   graw.draw = draw;
173}
174
175void
176graw_main_loop( void )
177{
178   int i;
179   for (i = 0; i < 10; i++) {
180      graw.draw();
181      sleep(1);
182   }
183}
184
185