#include "pipe/p_compiler.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "target-helpers/inline_sw_helper.h"
#include "target-helpers/inline_debug_helper.h"
#include "state_tracker/xlibsw_api.h"
#include "state_tracker/graw.h"
#include "sw/xlib/xlib_sw_winsys.h"
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include <stdio.h>
static struct {
Display *display;
void (*draw)(void);
} graw;
static struct pipe_screen *
graw_create_screen( void )
{
struct pipe_screen *screen = NULL;
struct sw_winsys *winsys = NULL;
/* Create the underlying winsys, which performs presents to Xlib
* drawables:
*/
winsys = xlib_create_sw_winsys( graw.display );
if (winsys == NULL)
return NULL;
screen = sw_screen_create( winsys );
/* Inject any wrapping layers we want to here:
*/
return debug_screen_wrap( screen );
}
struct pipe_screen *
graw_create_window_and_screen( int x,
int y,
unsigned width,
unsigned height,
enum pipe_format format,
void **handle)
{
struct pipe_screen *screen = NULL;
struct xlib_drawable *xlib_handle = NULL;
XSetWindowAttributes attr;
Window root;
Window win = 0;
XVisualInfo templat, *visinfo = NULL;
unsigned mask;
int n;
int scrnum;
graw.display = XOpenDisplay(NULL);
if (graw.display == NULL)
return NULL;
scrnum = DefaultScreen( graw.display );
root = RootWindow( graw.display, scrnum );
if (graw.display == NULL)
goto fail;
xlib_handle = CALLOC_STRUCT(xlib_drawable);
if (xlib_handle == NULL)
goto fail;
mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
templat.screen = DefaultScreen(graw.display);
templat.depth = 32;
templat.class = TrueColor;
visinfo = XGetVisualInfo(graw.display, mask, &templat, &n);
if (!visinfo) {
printf("Error: couldn't get an RGB, Double-buffered visual\n");
exit(1);
}
/* See if the requirested pixel format matches the visual */
if (visinfo->red_mask == 0xff0000 &&
visinfo->green_mask == 0xff00 &&
visinfo->blue_mask == 0xff) {
if (format != PIPE_FORMAT_BGRA8888_UNORM)
goto fail;
}
else if (visinfo->red_mask == 0xff &&
visinfo->green_mask == 0xff00 &&
visinfo->blue_mask == 0xff0000) {
if (format != PIPE_FORMAT_RGBA8888_UNORM)
goto fail;
}
else {
goto fail;
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
/* XXX this is a bad way to get a borderless window! */
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( graw.display, root, x, y, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr );
/* set hints and properties */
{
char *name = NULL;
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(graw.display, win, &sizehints);
XSetStandardProperties(graw.display, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
XMapWindow(graw.display, win);
while (1) {
XEvent e;
XNextEvent( graw.display, &e );
if (e.type == MapNotify && e.xmap.window == win) {
break;
}
}
xlib_handle->visual = visinfo->visual;
xlib_handle->drawable = (Drawable)win;
xlib_handle->depth = visinfo->depth;
*handle = (void *)xlib_handle;
screen = graw_create_screen();
if (screen == NULL)
goto fail;
free(visinfo);
return screen;
fail:
if (screen)
screen->destroy(screen);
FREE(xlib_handle);
free(visinfo);
if (win)
XDestroyWindow(graw.display, win);
return NULL;
}
void
graw_set_display_func( void (*draw)( void ) )
{
graw.draw = draw;
}
void
graw_main_loop( void )
{
int i;
for (i = 0; i < 10; i++) {
graw.draw();
sleep(1);
}
}