#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h> /* only for GLfloat */
extern char *progname;
#include <X11/Xutil.h>
+#include <sys/time.h>
#undef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
}
-/* Returns an XImage structure containing an image of the desktop.
- (As a side-effect, that image will be painted onto the given Window.)
- This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the
- extra byte set to 0xFF.
- */
-XImage *
-screen_to_ximage (Screen *screen, Window window)
+static Bool
+bigendian (void)
+{
+ union { int i; char c[sizeof(int)]; } u;
+ u.i = 1;
+ return !u.c[0];
+}
+
+
+static XImage *
+screen_to_ximage_1 (Screen *screen, Window window, Pixmap pixmap)
{
Display *dpy = DisplayOfScreen (screen);
XWindowAttributes xgwa;
int win_width, win_height;
int tex_width, tex_height;
- grab_screen_image (screen, window);
-
XGetWindowAttributes (dpy, window, &xgwa);
win_width = xgwa.width;
win_height = xgwa.height;
tex_width = to_pow2(win_width);
tex_height = to_pow2(win_height);
- /* Convert the server-side Drawable to a client-side GL-ordered XImage.
+ /* Convert the server-side Pixmap to a client-side GL-ordered XImage.
*/
{
XImage *ximage1, *ximage2;
XColor *colors = 0;
- ximage1 = XGetImage (dpy, window, 0, 0, win_width, win_height, ~0L,
+ ximage1 = XGetImage (dpy, pixmap, 0, 0, win_width, win_height, ~0L,
ZPixmap);
+ XFreePixmap (dpy, pixmap);
+ pixmap = 0;
+
ximage2 = XCreateImage (dpy, xgwa.visual, 32, ZPixmap, 0, 0,
tex_width, tex_height, 32, 0);
*/
{
int x, y;
- int crpos, cgpos, cbpos, capos; /* bitfield positions */
- int srpos, sgpos, sbpos;
- int srmsk, sgmsk, sbmsk;
- int srsiz, sgsiz, sbsiz;
+ unsigned int crpos=0, cgpos=0, cbpos=0, capos=0; /* bitfield positions */
+ unsigned int srpos=0, sgpos=0, sbpos=0;
+ unsigned int srmsk=0, sgmsk=0, sbmsk=0;
+ unsigned int srsiz=0, sgsiz=0, sbsiz=0;
int i;
unsigned char spread_map[3][256];
if (colors == 0) /* truecolor */
{
- srmsk = ximage1->red_mask;
- sgmsk = ximage1->green_mask;
- sbmsk = ximage1->blue_mask;
+ srmsk = ximage2->red_mask;
+ sgmsk = ximage2->green_mask;
+ sbmsk = ximage2->blue_mask;
decode_mask (srmsk, &srpos, &srsiz);
decode_mask (sgmsk, &sgpos, &sgsiz);
we need to pack things in "RGBA" order on the client machine,
regardless of its endianness.
*/
- crpos = 0, cgpos = 8, cbpos = 16, capos = 24;
+ if (bigendian())
+ crpos = 24, cgpos = 16, cbpos = 8, capos = 0;
+ else
+ crpos = 0, cgpos = 8, cbpos = 16, capos = 24;
if (colors == 0) /* truecolor */
{
}
}
+ if (pixmap) XFreePixmap (dpy, pixmap);
if (colors) free (colors);
free (ximage1->data);
ximage1->data = 0;
return ximage2;
}
}
+
+
+/* Returns an XImage structure containing an image of the desktop.
+ (As a side-effect, that image *may* be painted onto the given Window.)
+ This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the
+ extra byte set to 0xFF.
+ */
+XImage *
+screen_to_ximage (Screen *screen, Window window, char **filename_return)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ Pixmap pixmap = 0;
+ XWindowAttributes xgwa;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+ pixmap = XCreatePixmap (dpy, window, xgwa.width, xgwa.height, xgwa.depth);
+ load_random_image (screen, window, pixmap, filename_return);
+
+ return screen_to_ximage_1 (screen, window, pixmap);
+}
+
+
+typedef struct {
+ void (*callback) (Screen *, Window, XImage *,
+ const char *name, void *closure, double cvt_time);
+ void *closure;
+ Pixmap pixmap;
+} img_closure;
+
+
+/* Returns the current time in seconds as a double.
+ */
+static double
+double_time (void)
+{
+ struct timeval now;
+# ifdef GETTIMEOFDAY_TWO_ARGS
+ struct timezone tzp;
+ gettimeofday(&now, &tzp);
+# else
+ gettimeofday(&now);
+# endif
+
+ return (now.tv_sec + ((double) now.tv_usec * 0.000001));
+}
+
+
+static void
+img_cb (Screen *screen, Window window, Drawable drawable,
+ const char *name, void *closure)
+{
+ XImage *ximage;
+ double cvt_time = double_time();
+ img_closure *data = (img_closure *) closure;
+ /* copy closure data to stack and free the original before running cb */
+ img_closure dd = *data;
+ memset (data, 0, sizeof (*data));
+ free (data);
+ data = 0;
+ ximage = screen_to_ximage_1 (screen, window, dd.pixmap);
+ dd.callback (screen, window, ximage, name, dd.closure, cvt_time);
+}
+
+
+/* Like the above, but loads the image in the background and runs the
+ given callback once it has been loaded.
+ */
+#include <X11/Intrinsic.h>
+extern XtAppContext app;
+
+void
+fork_screen_to_ximage (Screen *screen, Window window,
+ void (*callback) (Screen *, Window, XImage *,
+ const char *name,
+ void *closure,
+ double cvt_time),
+ void *closure)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ XWindowAttributes xgwa;
+ img_closure *data = (img_closure *) calloc (1, sizeof(*data));
+ data->callback = callback;
+ data->closure = closure;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+ data->pixmap = XCreatePixmap (dpy, window, xgwa.width, xgwa.height,
+ xgwa.depth);
+ fork_load_random_image (screen, window, data->pixmap, img_cb, data);
+}