From ddca0591a646afc37242b62e06ed9858f577799e Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Sun, 27 Apr 2014 00:14:12 -0400 Subject: examples/cogl-x11-tfp: Add a --gears option to run glxgears If --gears is passed on the command line, glxgears is run, and is used for the source window rather than drawing solid rectangles into a window we create outselves. Reviewed-by: Robert Bragg --- examples/cogl-x11-tfp.c | 177 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 151 insertions(+), 26 deletions(-) diff --git a/examples/cogl-x11-tfp.c b/examples/cogl-x11-tfp.c index c63fa2ea..5f364fcc 100644 --- a/examples/cogl-x11-tfp.c +++ b/examples/cogl-x11-tfp.c @@ -3,9 +3,14 @@ #include #include #include +#include +#include +#include +#include #include #include +#include #include @@ -19,6 +24,84 @@ #define TFP_XWIN_WIDTH 200 #define TFP_XWIN_HEIGHT 200 +static pid_t gears_pid = 0; + +static void +spawn_gears (void) +{ + pid_t pid = fork(); + + if (pid == 0) + execlp ("glxgears", "glxgears", + NULL); + + gears_pid = pid; +} + +static XID +find_gears_toplevel (Display *xdpy, + Window window) +{ + Atom window_state = XInternAtom (xdpy, "WM_STATE", False); + Atom type; + int format; + unsigned long n_items; + unsigned long bytes_after; + unsigned char *data; + CoglBool result = FALSE; + + if (window == None) + window = DefaultRootWindow (xdpy); + + XGetWindowProperty (xdpy, window, window_state, + 0, G_MAXLONG, False, window_state, + &type, &format, &n_items, &bytes_after, &data); + + if (type == window_state) + { + XFree (data); + + XGetWindowProperty (xdpy, window, XA_WM_NAME, + 0, G_MAXLONG, False, XA_STRING, + &type, &format, &n_items, &bytes_after, &data); + + if (type == XA_STRING) + { + if (format == 8 && strcmp ((char *)data, "glxgears") == 0) + result = window; + + XFree (data); + } + } + else + { + Window root, parent; + Window *children; + unsigned int n_children; + unsigned int i; + + XQueryTree (xdpy, window, + &root, &parent, &children, &n_children); + + for (i = 0; i < n_children; i++) + { + result = find_gears_toplevel (xdpy, children[i]); + if (result != None) + break; + } + + XFree (children); + } + + return result; +} + +static void +kill_gears (void) +{ + kill (gears_pid, SIGTERM); +} + static void update_cogl_x11_event_mask (CoglOnscreen *onscreen, uint32_t event_mask, @@ -58,10 +141,24 @@ main (int argc, char **argv) Atom atom_wm_protocols; Atom atom_wm_delete_window; int screen; - Window tfp_xwin; + CoglBool gears = FALSE; + Window tfp_xwin = None; Pixmap pixmap; CoglTexturePixmapX11 *tfp; - GC gc; + CoglTexture *right_texture; + GC gc = None; + int i; + + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "--gears") == 0) + gears = TRUE; + else + { + g_printerr ("Usage: cogl-x11-tfp [--gears]\n"); + return 1; + } + } g_print ("NB: Don't use this example as a benchmark since there is " "no synchonization between X window updates and onscreen " @@ -88,6 +185,19 @@ main (int argc, char **argv) } } + if (gears) + { + spawn_gears (); + while (TRUE) + { + tfp_xwin = find_gears_toplevel (xdpy, None); + if (tfp_xwin != None) + break; + + g_usleep (10000); + } + } + /* Choose a means to render... */ renderer = cogl_renderer_new (); cogl_xlib_renderer_set_foreign_display (renderer, xdpy); @@ -165,27 +275,37 @@ main (int argc, char **argv) xdpy); XMapWindow (xdpy, xwin); - - XCompositeRedirectSubwindows (xdpy, xwin, CompositeRedirectManual); + cogl_onscreen_show (onscreen); screen = DefaultScreen (xdpy); - tfp_xwin = XCreateSimpleWindow (xdpy, xwin, - 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT, - 0, - WhitePixel (xdpy, screen), - WhitePixel (xdpy, screen)); - XMapWindow (xdpy, tfp_xwin); - gc = XCreateGC (xdpy, tfp_xwin, 0, NULL); - - while (TRUE) + if (gears) + { + XCompositeRedirectWindow (xdpy, tfp_xwin, CompositeRedirectAutomatic); + } + else { XEvent xev; - XWindowEvent (xdpy, xwin, StructureNotifyMask, &xev); + XCompositeRedirectSubwindows (xdpy, xwin, CompositeRedirectManual); + + tfp_xwin = XCreateSimpleWindow (xdpy, xwin, + 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT, + 0, + WhitePixel (xdpy, screen), + WhitePixel (xdpy, screen)); + + XMapWindow (xdpy, tfp_xwin); - if (xev.xany.type == MapNotify) - break; + while (TRUE) + { + XWindowEvent (xdpy, xwin, StructureNotifyMask, &xev); + + if (xev.xany.type == MapNotify) + break; + } + + gc = XCreateGC (xdpy, tfp_xwin, 0, NULL); } pixmap = XCompositeNameWindowPixmap (xdpy, tfp_xwin); @@ -215,25 +335,28 @@ main (int argc, char **argv) case KeyRelease: keysym = XLookupKeysym (&event.xkey, 0); if (keysym == XK_q || keysym == XK_Q || keysym == XK_Escape) - return 0; + goto out; break; case ClientMessage: if (event.xclient.message_type == atom_wm_protocols && event.xclient.data.l[0] == atom_wm_delete_window) - return 0; + goto out; break; } cogl_xlib_renderer_handle_event (renderer, &event); } - pixel = - g_random_int_range (0, 255) << 24 | - g_random_int_range (0, 255) << 16 | - g_random_int_range (0, 255) << 8; - g_random_int_range (0, 255); - XSetForeground (xdpy, gc, pixel); - XFillRectangle (xdpy, tfp_xwin, gc, 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT); - XFlush (xdpy); + if (!gears) + { + pixel = + g_random_int_range (0, 255) << 24 | + g_random_int_range (0, 255) << 16 | + g_random_int_range (0, 255) << 8; + g_random_int_range (0, 255); + XSetForeground (xdpy, gc, pixel); + XFillRectangle (xdpy, tfp_xwin, gc, 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT); + XFlush (xdpy); + } cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); pipeline = cogl_pipeline_new (ctx); @@ -243,5 +366,7 @@ main (int argc, char **argv) cogl_onscreen_swap_buffers (onscreen); } + out: + kill_gears (); return 0; } -- cgit v1.2.1