-/* xscreensaver, Copyright (c) 1992-2006 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2009 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
*/
#import <stdlib.h>
+#import <stdint.h>
#import <Cocoa/Cocoa.h>
#import "jwxyz.h"
#import "grabscreen.h"
#import "usleep.h"
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+
+ /* 10.4 code.
+
+ This version of the code works on 10.4, but is flaky. There is
+ a better way to do it on 10.5 and newer, but taking this path,
+ then we are being compiled against the 10.4 SDK instead of the
+ 10.5 SDK, and the newer API is not available to us.
+ */
+
static void
copy_framebuffer_to_ximage (CGDirectDisplayID cgdpy, XImage *xim,
int window_x, int window_y)
int ximw = xim->width;
int ximh = xim->height;
- unsigned long *odata = (unsigned long *) xim->data;
+ uint32_t *odata = (uint32_t *) xim->data;
switch (bpp) {
case 32:
if (spp != 3) abort();
if (bps != 5) abort();
for (y = 0; y < ximh; y++) {
- unsigned short *ip = (unsigned short *) data;
+ uint16_t *ip = (uint16_t *) data;
int x;
for (x = 0; x < ximw; x++) {
- unsigned short p = *ip++;
+ uint16_t p = *ip++;
// This should be ok on both PPC and Intel (ARGB, word order)
unsigned char r = (p >> 10) & 0x1F;
unsigned char g = (p >> 5) & 0x1F;
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
b = (b << 3) | (b >> 2);
- unsigned long pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
+ uint32_t pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
// XPutPixel (xim, x, y, pixel);
*odata++ = pixel;
}
CGDirectPaletteRef pal = CGPaletteCreateWithDisplay (cgdpy);
/* Map it to 32bpp pixels */
- unsigned long map[256];
+ uint32_t map[256];
for (y = 0; y < 256; y++) {
CGDeviceColor c = CGPaletteGetColorAtIndex (pal, y);
unsigned char r = c.red * 255.0;
unsigned char g = c.green * 255.0;
unsigned char b = c.blue * 255.0;
- unsigned long pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
+ uint32_t pixel = 0xFF000000 | (r << 16) | (g << 8) | b;
map[y] = pixel;
}
osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable)
{
Display *dpy = DisplayOfScreen (screen);
- XWindowAttributes xgwa;
NSView *nsview = jwxyz_window_view (xwindow);
NSWindow *nswindow = [nsview window];
+ XWindowAttributes xgwa;
int window_x, window_y;
Window unused;
- // figure out where this window is on the screen
+ // Figure out where this window is on the screen.
//
XGetWindowAttributes (dpy, xwindow, &xgwa);
XTranslateCoordinates (dpy, xwindow, RootWindowOfScreen (screen), 0, 0,
&window_x, &window_y, &unused);
-
+
// Use the size of the Drawable, not the Window.
{
Window r;
}
+#else /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+
+ 10.5+ code.
+
+ This version of the code is simpler and more reliable, but
+ uses an API that only exist on 10.5 and newer, so we can only
+ use it if when being compiled against the 10.5 SDK or later.
+ */
+
+/* Loads an image into the Drawable, returning once the image is loaded.
+ */
+void
+osx_grab_desktop_image (Screen *screen, Window xwindow, Drawable drawable)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ NSView *nsview = jwxyz_window_view (xwindow);
+ XWindowAttributes xgwa;
+ int window_x, window_y;
+ Window unused;
+
+ // Figure out where this window is on the screen.
+ //
+ XGetWindowAttributes (dpy, xwindow, &xgwa);
+ XTranslateCoordinates (dpy, xwindow, RootWindowOfScreen (screen), 0, 0,
+ &window_x, &window_y, &unused);
+
+ // Grab only the rectangle of the screen underlying this window.
+ //
+ CGRect cgrect;
+ cgrect.origin.x = window_x;
+ cgrect.origin.y = window_y;
+ cgrect.size.width = xgwa.width;
+ cgrect.size.height = xgwa.height;
+
+ // Grab a screen shot of those windows below this one
+ // (hey, X11 can't do that!)
+ //
+ CGImageRef img =
+ CGWindowListCreateImage (cgrect,
+ kCGWindowListOptionOnScreenBelowWindow,
+ [[nsview window] windowNumber],
+ kCGWindowImageDefault);
+
+ // Render the grabbed CGImage into the Drawable.
+ if (img) {
+ jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable,
+ False, img, NULL, 0);
+ CGImageRelease (img);
+ }
+}
+
+#endif /* 10.5+ code */
+
+
/* Returns the EXIF rotation property of the image, if any.
*/
static int
if (!img)
return False;
- jwxyz_draw_NSImage (DisplayOfScreen (screen), drawable, img, geom_ret,
- exif_rotation (filename));
+ jwxyz_draw_NSImage_or_CGImage (DisplayOfScreen (screen), drawable,
+ True, img, geom_ret,
+ exif_rotation (filename));
[img release];
return True;
}
+