1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h"
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h"
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "target-helpers/inline_sw_helper.h"
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "target-helpers/inline_debug_helper.h"
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "state_tracker/xlib_sw_winsys.h"
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "state_tracker/graw.h"
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/Xlib.h>
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/Xlibint.h>
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/Xutil.h>
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h>
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct {
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Display *display;
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void (*draw)(void);
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} graw;
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_screen *
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggraw_create_screen( void )
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_screen *screen = NULL;
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct sw_winsys *winsys = NULL;
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Create the underlying winsys, which performs presents to Xlib
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * drawables:
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   winsys = xlib_create_sw_winsys( graw.display );
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (winsys == NULL)
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen = sw_screen_create( winsys );
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Inject any wrapping layers we want to here:
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return debug_screen_wrap( screen );
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_screen *
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggraw_create_window_and_screen( int x,
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               int y,
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               unsigned width,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               unsigned height,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               enum pipe_format format,
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               void **handle)
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_screen *screen = NULL;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct xlib_drawable *xlib_handle = NULL;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XSetWindowAttributes attr;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Window root;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Window win = 0;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XVisualInfo templat, *visinfo = NULL;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned mask;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int n;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int scrnum;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   graw.display = XOpenDisplay(NULL);
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (graw.display == NULL)
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   scrnum = DefaultScreen( graw.display );
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   root = RootWindow( graw.display, scrnum );
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (graw.display == NULL)
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto fail;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xlib_handle = CALLOC_STRUCT(xlib_drawable);
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xlib_handle == NULL)
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto fail;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templat.screen = DefaultScreen(graw.display);
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templat.depth = 32;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templat.class = TrueColor;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visinfo = XGetVisualInfo(graw.display, mask, &templat, &n);
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!visinfo) {
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("Error: couldn't get an RGB, Double-buffered visual\n");
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exit(1);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* See if the requirested pixel format matches the visual */
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (visinfo->red_mask == 0xff0000 &&
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       visinfo->green_mask == 0xff00 &&
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       visinfo->blue_mask == 0xff) {
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (format != PIPE_FORMAT_B8G8R8A8_UNORM)
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto fail;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (visinfo->red_mask == 0xff &&
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            visinfo->green_mask == 0xff00 &&
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            visinfo->blue_mask == 0xff0000) {
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (format != PIPE_FORMAT_R8G8B8A8_UNORM)
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto fail;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto fail;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* window attributes */
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   attr.background_pixel = 0;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   attr.border_pixel = 0;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX this is a bad way to get a borderless window! */
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   win = XCreateWindow( graw.display, root, x, y, width, height,
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		        0, visinfo->depth, InputOutput,
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		        visinfo->visual, mask, &attr );
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* set hints and properties */
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      char *name = NULL;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XSizeHints sizehints;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sizehints.x = x;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sizehints.y = y;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sizehints.width  = width;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sizehints.height = height;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sizehints.flags = USSize | USPosition;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XSetNormalHints(graw.display, win, &sizehints);
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XSetStandardProperties(graw.display, win, name, name,
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              None, (char **)NULL, 0, &sizehints);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XMapWindow(graw.display, win);
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (1) {
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XEvent e;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XNextEvent( graw.display, &e );
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (e.type == MapNotify && e.xmap.window == win) {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xlib_handle->visual = visinfo->visual;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xlib_handle->drawable = (Drawable)win;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xlib_handle->depth = visinfo->depth;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *handle = (void *)xlib_handle;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen = graw_create_screen();
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (screen == NULL)
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto fail;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFree(visinfo);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return screen;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail:
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (screen)
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      screen->destroy(screen);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xlib_handle)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(xlib_handle);
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (visinfo)
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XFree(visinfo);
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (win)
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XDestroyWindow(graw.display, win);
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggraw_set_display_func( void (*draw)( void ) )
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   graw.draw = draw;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggraw_main_loop( void )
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 10; i++) {
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      graw.draw();
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sleep(1);
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186