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