-/* xscreensaver, Copyright (c) 1992-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2014 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#include "utils.h"
#include "grabscreen.h"
#include "resources.h"
+#include "yarandom.h"
#ifdef HAVE_COCOA
# include "jwxyz.h"
#else /* HAVE_COCOA */
+struct pipe_closure {
+ FILE *pipe;
+ XtInputId id;
+ Screen *screen;
+ Window xwindow;
+ Drawable drawable;
+ char *directory;
+ void (*callback) (Screen *, Window, Drawable,
+ const char *name, XRectangle *geom,
+ void *closure);
+ void *closure;
+};
+
+# ifndef USE_IPHONE
+
+# define BACKSLASH(c) \
+ (! ((c >= 'a' && c <= 'z') || \
+ (c >= 'A' && c <= 'Z') || \
+ (c >= '0' && c <= '9') || \
+ c == '.' || c == '_' || c == '-' || c == '+' || c == '/'))
+
/* Gets the name of an image file to load by running xscreensaver-getimage-file
at the end of a pipe. This can be very slow!
*/
static FILE *
open_image_name_pipe (const char *dir)
{
- char *cmd = malloc (strlen(dir) * 2 + 100);
char *s;
- strcpy (cmd, "xscreensaver-getimage-file --name ");
- s = cmd + strlen (cmd);
+
+# ifdef HAVE_COCOA
+ /* /bin/sh on OS X 10.10 wipes out the PATH. */
+ const char *path = getenv("PATH");
+ char *cmd = s = malloc ((strlen(dir) + strlen(path)) * 2 + 100);
+ strcpy (s, "/bin/sh -c 'export PATH=");
+ s += strlen (s);
+ while (*path) {
+ char c = *path++;
+ if (BACKSLASH(c)) *s++ = '\\';
+ *s++ = c;
+ }
+ strcpy (s, "; ");
+ s += strlen (s);
+# else
+ char *cmd = s = malloc (strlen(dir) * 2 + 100);
+# endif
+
+ strcpy (s, "xscreensaver-getimage-file --name ");
+ s += strlen (s);
while (*dir) {
char c = *dir++;
- /* put a backslash in front of any character that might confuse sh. */
- if (! ((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c == '.' || c == '_' || c == '-' || c == '+' || c == '/'))
- *s++ = '\\';
+ if (BACKSLASH(c)) *s++ = '\\';
*s++ = c;
}
+# ifdef HAVE_COCOA
+ strcpy (s, "'");
+ s += strlen (s);
+# endif
*s = 0;
FILE *pipe = popen (cmd, "r");
}
-struct pipe_closure {
- FILE *pipe;
- XtInputId id;
- Screen *screen;
- Window xwindow;
- Drawable drawable;
- char *directory;
- void (*callback) (Screen *, Window, Drawable,
- const char *name, XRectangle *geom,
- void *closure);
- void *closure;
-};
-
-
static void
pipe_cb (XtPointer closure, int *source, XtInputId *id)
{
char buf[10240];
const char *dir = clo2->directory;
char *absfile = 0;
+ *buf = 0;
fgets (buf, sizeof(buf)-1, clo2->pipe);
pclose (clo2->pipe);
clo2->pipe = 0;
geom.height = h;
}
+ /* Take the extension off of the file name. */
+ /* Duplicated in driver/xscreensaver-getimage.c. */
+ if (buf && *buf)
+ {
+ char *slash = strrchr (buf, '/');
+ char *dot = strrchr ((slash ? slash : buf), '.');
+ if (dot) *dot = 0;
+ /* Replace slashes with newlines */
+ /* while (dot = strchr(buf, '/')) *dot = '\n'; */
+ /* Replace slashes with spaces */
+ /* while ((dot = strchr(buf, '/'))) *dot = ' '; */
+ }
+
if (absfile) free (absfile);
clo2->callback (clo2->screen, clo2->xwindow, clo2->drawable, buf, &geom,
clo2->closure);
}
+# else /* USE_IPHONE */
+
+/* Callback for ios_load_random_image(), called after we have loaded an
+ image from the iOS device's Photo Library. See iosgrabimage.m.
+ */
+static void
+ios_load_random_image_cb (void *uiimage, const char *filename,
+ int width, int height, void *closure)
+{
+ struct pipe_closure *clo2 = (struct pipe_closure *) closure;
+ Display *dpy = DisplayOfScreen (clo2->screen);
+ XRectangle geom;
+ XWindowAttributes xgwa;
+ Window r;
+ int x, y;
+ unsigned int w, h, bbw, d;
+ int rot = 0;
+
+ XGetWindowAttributes (dpy, clo2->xwindow, &xgwa);
+ XGetGeometry (dpy, clo2->drawable, &r, &x, &y, &w, &h, &bbw, &d);
+
+ /* If the image is portrait and the window is landscape, or vice versa,
+ rotate the image. The idea is to fill up as many pixels as possible,
+ and assume the user will just rotate their phone until it looks right.
+ This makes "decayscreen", etc. much more easily viewable.
+ */
+ if (get_boolean_resource (dpy, "rotateImages", "RotateImages")) {
+ if ((width > height) != (w > h))
+ rot = 5;
+ }
+
+ if (uiimage)
+ {
+ jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (clo2->screen),
+ clo2->drawable,
+ True, uiimage, &geom,
+ rot);
+ }
+ else /* Probably means no images in the gallery. */
+ {
+ draw_colorbars (clo2->screen, xgwa.visual, clo2->drawable, xgwa.colormap,
+ 0, 0, w, h);
+ geom.x = geom.y = 0;
+ geom.width = w;
+ geom.height = h;
+ filename = 0;
+ }
+
+ clo2->callback (clo2->screen, clo2->xwindow, clo2->drawable,
+ filename, &geom, clo2->closure);
+ clo2->callback = 0;
+ if (clo2->directory) free (clo2->directory);
+ free (clo2);
+}
+
+# endif /* USE_IPHONE */
+
+
static void
osx_load_image_file_async (Screen *screen, Window xwindow, Drawable drawable,
const char *dir,
void *closure),
void *closure)
{
-#if 0 /* do it synchronously */
+# if 0 /* do it synchronously */
FILE *pipe = open_image_name_pipe (dir);
char buf[10240];
}
callback (screen, xwindow, drawable, buf, &geom, closure);
-#else /* do it asynchronously */
+# else /* do it asynchronously */
- Display *dpy = DisplayOfScreen (screen);
struct pipe_closure *clo2 = (struct pipe_closure *) calloc (1, sizeof(*clo2));
- clo2->directory = strdup (dir);
- clo2->pipe = open_image_name_pipe (dir);
- clo2->id = XtAppAddInput (XtDisplayToApplicationContext (dpy),
- fileno (clo2->pipe),
- (XtPointer) (XtInputReadMask | XtInputExceptMask),
- pipe_cb, (XtPointer) clo2);
+
clo2->screen = screen;
clo2->xwindow = xwindow;
clo2->drawable = drawable;
clo2->callback = callback;
clo2->closure = closure;
-#endif
+
+# ifndef USE_IPHONE
+ clo2->directory = strdup (dir);
+ clo2->pipe = open_image_name_pipe (dir);
+ clo2->id = XtAppAddInput (XtDisplayToApplicationContext (
+ DisplayOfScreen (screen)),
+ fileno (clo2->pipe),
+ (XtPointer) (XtInputReadMask | XtInputExceptMask),
+ pipe_cb, (XtPointer) clo2);
+# else /* USE_IPHONE */
+ ios_load_random_image (ios_load_random_image_cb, clo2);
+# endif /* USE_IPHONE */
+
+# endif
}
XRectangle geom_ret_2;
char *name_ret_2 = 0;
-# ifdef USE_IPHONE
- /* Currently, only screen-grabbing is implemented, not loading of
- images from the iPhone Photo Library. See osxgrabscreen.m.
- */
- deskp = True;
- filep = False;
-# endif
-
if (!drawable) abort();
if (callback) {
geom_ret->height = xgwa.height;
}
+# ifndef USE_IPHONE
if (filep)
dir = get_string_resource (dpy, "imageDirectory", "ImageDirectory");
if (!dir || !*dir)
filep = False;
+# endif /* ! USE_IPHONE */
if (deskp && filep) {
deskp = !(random() & 5); /* if both, desktop 1/5th of the time */
/* If we got here, we loaded synchronously even though they wanted async.
*/
callback (screen, window, drawable, name_ret_2, &geom_ret_2, closure);
+ if (name_ret_2) free (name_ret_2);
}
}
fn = 0;
XGetWindowAttributes (dpy, window, &xgwa);
- w = XTextWidth (f, text, strlen(text));
+ w = XTextWidth (f, text, (int) strlen(text));
gcv.foreground = get_pixel_resource (dpy, xgwa.colormap,
"foreground", "Foreground");
XDrawImageString (dpy, window, gc,
(xgwa.width - w) / 2,
(xgwa.height - (f->ascent + f->descent)) / 2 + f->ascent,
- text, strlen(text));
+ text, (int) strlen(text));
XFreeFont (dpy, f);
XFreeGC (dpy, gc);
XSync (dpy, False);