1848b8605Smrg#include "pipe/p_compiler.h"
2848b8605Smrg#include "pipe/p_context.h"
3848b8605Smrg#include "pipe/p_screen.h"
4848b8605Smrg#include "util/u_debug.h"
5848b8605Smrg#include "util/u_memory.h"
6848b8605Smrg#include "target-helpers/inline_sw_helper.h"
7848b8605Smrg#include "target-helpers/inline_debug_helper.h"
8848b8605Smrg#include "state_tracker/xlibsw_api.h"
9848b8605Smrg#include "state_tracker/graw.h"
10848b8605Smrg#include "sw/xlib/xlib_sw_winsys.h"
11848b8605Smrg
12848b8605Smrg#include <X11/Xlib.h>
13848b8605Smrg#include <X11/Xlibint.h>
14848b8605Smrg#include <X11/Xutil.h>
15848b8605Smrg#include <stdio.h>
16848b8605Smrg
17848b8605Smrgstatic struct {
18848b8605Smrg   Display *display;
19848b8605Smrg   void (*draw)(void);
20848b8605Smrg} graw;
21848b8605Smrg
22848b8605Smrg
23848b8605Smrgstatic struct pipe_screen *
24848b8605Smrggraw_create_screen( void )
25848b8605Smrg{
26848b8605Smrg   struct pipe_screen *screen = NULL;
27848b8605Smrg   struct sw_winsys *winsys = NULL;
28848b8605Smrg
29848b8605Smrg   /* Create the underlying winsys, which performs presents to Xlib
30848b8605Smrg    * drawables:
31848b8605Smrg    */
32848b8605Smrg   winsys = xlib_create_sw_winsys( graw.display );
33848b8605Smrg   if (winsys == NULL)
34848b8605Smrg      return NULL;
35848b8605Smrg
36848b8605Smrg   screen = sw_screen_create( winsys );
37848b8605Smrg
38848b8605Smrg   /* Inject any wrapping layers we want to here:
39848b8605Smrg    */
40848b8605Smrg   return debug_screen_wrap( screen );
41848b8605Smrg}
42848b8605Smrg
43848b8605Smrg
44848b8605Smrgstruct pipe_screen *
45848b8605Smrggraw_create_window_and_screen( int x,
46848b8605Smrg                               int y,
47848b8605Smrg                               unsigned width,
48848b8605Smrg                               unsigned height,
49848b8605Smrg                               enum pipe_format format,
50848b8605Smrg                               void **handle)
51848b8605Smrg{
52848b8605Smrg   struct pipe_screen *screen = NULL;
53848b8605Smrg   struct xlib_drawable *xlib_handle = NULL;
54848b8605Smrg   XSetWindowAttributes attr;
55848b8605Smrg   Window root;
56848b8605Smrg   Window win = 0;
57848b8605Smrg   XVisualInfo templat, *visinfo = NULL;
58848b8605Smrg   unsigned mask;
59848b8605Smrg   int n;
60848b8605Smrg   int scrnum;
61848b8605Smrg
62848b8605Smrg   graw.display = XOpenDisplay(NULL);
63848b8605Smrg   if (graw.display == NULL)
64848b8605Smrg      return NULL;
65848b8605Smrg
66848b8605Smrg   scrnum = DefaultScreen( graw.display );
67848b8605Smrg   root = RootWindow( graw.display, scrnum );
68848b8605Smrg
69848b8605Smrg
70848b8605Smrg   if (graw.display == NULL)
71848b8605Smrg      goto fail;
72848b8605Smrg
73848b8605Smrg   xlib_handle = CALLOC_STRUCT(xlib_drawable);
74848b8605Smrg   if (xlib_handle == NULL)
75848b8605Smrg      goto fail;
76848b8605Smrg
77848b8605Smrg
78848b8605Smrg   mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
79848b8605Smrg   templat.screen = DefaultScreen(graw.display);
80848b8605Smrg   templat.depth = 32;
81848b8605Smrg   templat.class = TrueColor;
82848b8605Smrg
83848b8605Smrg   visinfo = XGetVisualInfo(graw.display, mask, &templat, &n);
84848b8605Smrg   if (!visinfo) {
85848b8605Smrg      printf("Error: couldn't get an RGB, Double-buffered visual\n");
86848b8605Smrg      exit(1);
87848b8605Smrg   }
88848b8605Smrg
89848b8605Smrg   /* See if the requirested pixel format matches the visual */
90848b8605Smrg   if (visinfo->red_mask == 0xff0000 &&
91848b8605Smrg       visinfo->green_mask == 0xff00 &&
92848b8605Smrg       visinfo->blue_mask == 0xff) {
93848b8605Smrg      if (format != PIPE_FORMAT_BGRA8888_UNORM)
94848b8605Smrg         goto fail;
95848b8605Smrg   }
96848b8605Smrg   else if (visinfo->red_mask == 0xff &&
97848b8605Smrg            visinfo->green_mask == 0xff00 &&
98848b8605Smrg            visinfo->blue_mask == 0xff0000) {
99848b8605Smrg      if (format != PIPE_FORMAT_RGBA8888_UNORM)
100848b8605Smrg         goto fail;
101848b8605Smrg   }
102848b8605Smrg   else {
103848b8605Smrg      goto fail;
104848b8605Smrg   }
105848b8605Smrg
106848b8605Smrg   /* window attributes */
107848b8605Smrg   attr.background_pixel = 0;
108848b8605Smrg   attr.border_pixel = 0;
109848b8605Smrg   attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone);
110848b8605Smrg   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
111848b8605Smrg   /* XXX this is a bad way to get a borderless window! */
112848b8605Smrg   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
113848b8605Smrg
114848b8605Smrg   win = XCreateWindow( graw.display, root, x, y, width, height,
115848b8605Smrg		        0, visinfo->depth, InputOutput,
116848b8605Smrg		        visinfo->visual, mask, &attr );
117848b8605Smrg
118848b8605Smrg
119848b8605Smrg   /* set hints and properties */
120848b8605Smrg   {
121848b8605Smrg      char *name = NULL;
122848b8605Smrg      XSizeHints sizehints;
123848b8605Smrg      sizehints.x = x;
124848b8605Smrg      sizehints.y = y;
125848b8605Smrg      sizehints.width  = width;
126848b8605Smrg      sizehints.height = height;
127848b8605Smrg      sizehints.flags = USSize | USPosition;
128848b8605Smrg      XSetNormalHints(graw.display, win, &sizehints);
129848b8605Smrg      XSetStandardProperties(graw.display, win, name, name,
130848b8605Smrg                              None, (char **)NULL, 0, &sizehints);
131848b8605Smrg   }
132848b8605Smrg
133848b8605Smrg   XMapWindow(graw.display, win);
134848b8605Smrg   while (1) {
135848b8605Smrg      XEvent e;
136848b8605Smrg      XNextEvent( graw.display, &e );
137848b8605Smrg      if (e.type == MapNotify && e.xmap.window == win) {
138848b8605Smrg	 break;
139848b8605Smrg      }
140848b8605Smrg   }
141848b8605Smrg
142848b8605Smrg   xlib_handle->visual = visinfo->visual;
143848b8605Smrg   xlib_handle->drawable = (Drawable)win;
144848b8605Smrg   xlib_handle->depth = visinfo->depth;
145848b8605Smrg   *handle = (void *)xlib_handle;
146848b8605Smrg
147848b8605Smrg   screen = graw_create_screen();
148848b8605Smrg   if (screen == NULL)
149848b8605Smrg      goto fail;
150848b8605Smrg
151848b8605Smrg   free(visinfo);
152848b8605Smrg   return screen;
153848b8605Smrg
154848b8605Smrgfail:
155848b8605Smrg   if (screen)
156848b8605Smrg      screen->destroy(screen);
157848b8605Smrg
158848b8605Smrg   FREE(xlib_handle);
159848b8605Smrg
160848b8605Smrg   free(visinfo);
161848b8605Smrg
162848b8605Smrg   if (win)
163848b8605Smrg      XDestroyWindow(graw.display, win);
164848b8605Smrg
165848b8605Smrg   return NULL;
166848b8605Smrg}
167848b8605Smrg
168848b8605Smrg
169848b8605Smrgvoid
170848b8605Smrggraw_set_display_func( void (*draw)( void ) )
171848b8605Smrg{
172848b8605Smrg   graw.draw = draw;
173848b8605Smrg}
174848b8605Smrg
175848b8605Smrgvoid
176848b8605Smrggraw_main_loop( void )
177848b8605Smrg{
178848b8605Smrg   int i;
179848b8605Smrg   for (i = 0; i < 10; i++) {
180848b8605Smrg      graw.draw();
181848b8605Smrg      sleep(1);
182848b8605Smrg   }
183848b8605Smrg}
184848b8605Smrg
185