first pass at multi-monitor capture
authorTony Cook <tony@develop-help.com>
Wed, 13 Oct 2010 08:46:56 +0000 (08:46 +0000)
committerTony Cook <tony@develop-help.com>
Wed, 13 Oct 2010 08:46:56 +0000 (08:46 +0000)
Screenshot.pm
Screenshot.xs
imss.h
scwin32.c

index dd051d0..7f6572d 100644 (file)
@@ -42,9 +42,10 @@ sub screenshot {
     defined &_win32
       or die "Win32 driver not enabled\n";
     $result = _win32($opts{hwnd}, $opts{decor}, $opts{left}, $opts{top},
-                    $opts{right}, $opts{bottom});
+                    $opts{right}, $opts{bottom}, $opts{display});
   }
   elsif (defined $opts{id}) { # X11 window id
+    exists $opts{display} or $opts{display} = 0;
     defined &_x11
       or die "X11 driver not enabled\n";
     $result = _x11($opts{display}, $opts{id}, $opts{left}, $opts{top},
@@ -87,7 +88,7 @@ sub screenshot {
   else {
     $result =
       defined &_win32 ? _win32(0, $opts{decor}, $opts{left}, $opts{top},
-                              $opts{right}, $opts{bottom}) :
+                              $opts{right}, $opts{bottom}, $opts{display}) :
       defined &_darwin ? _darwin($opts{left}, $opts{top},
                                 $opts{right}, $opts{bottom}) :
       defined &_x11 ? _x11($opts{display}, 0, $opts{left}, $opts{top},
index dd9dd0c..93d794c 100644 (file)
@@ -17,13 +17,14 @@ PROTOTYPES: DISABLE
 #ifdef SS_WIN32
 
 Imager::ImgRaw
-imss_win32(hwnd, include_decor = 0, left = 0, top = 0, right = 0, bottom = 0)
+imss_win32(hwnd, include_decor = 0, left = 0, top = 0, right = 0, bottom = 0, display = 0)
        unsigned hwnd
        int include_decor
        int left
        int top
        int right
        int bottom
+       int display
 
 #endif
 
diff --git a/imss.h b/imss.h
index c464b13..b8fdb81 100644 (file)
--- a/imss.h
+++ b/imss.h
@@ -2,7 +2,7 @@
 #define IMSS_H
 
 extern i_img *
-imss_win32(unsigned hwnd, int include_decor, int left, int top, int right, int bottom);
+imss_win32(unsigned hwnd, int include_decor, int left, int top, int right, int bottom, int display);
 
 extern i_img *
 imss_x11(unsigned long display, int window_id, int left, int top, int right, int bottom);
index 3d9f8c2..b356b23 100644 (file)
--- a/scwin32.c
+++ b/scwin32.c
@@ -5,11 +5,12 @@
 
 i_img *
 imss_win32(unsigned hwnd_u, int include_decor, int left, int top, 
-          int right, int bottom) {
+          int right, int bottom, int display) {
   HWND hwnd = (HWND)hwnd_u;
-  HDC wdc, bmdc;
-  RECT rect;
+  HDC cdc = 0, wdc, bmdc;
   HBITMAP work_bmp, old_dc_bmp;
+  int orig_x = 0;
+  int orig_y = 0;
   int window_width, window_height;
   BITMAPINFO bmi;
   unsigned char *di_bits;
@@ -18,24 +19,52 @@ imss_win32(unsigned hwnd_u, int include_decor, int left, int top,
 
   i_clear_error();
 
-  if (!hwnd)
-    hwnd = GetDesktopWindow();
+  if (hwnd) {
+    RECT rect;
+    if (include_decor) {
+      wdc = GetWindowDC(hwnd);
+      GetWindowRect(hwnd, &rect);
+    }
+    else {
+      wdc = GetDC(hwnd);
+      GetClientRect(hwnd, &rect);
+    }
+    if (!wdc) {
+      i_push_error(0, "Cannot get window DC - invalid hwnd?");
+      return NULL;
+    }
 
-  if (include_decor) {
-    wdc = GetWindowDC(hwnd);
-    GetWindowRect(hwnd, &rect);
+    window_width = rect.right - rect.left;
+    window_height = rect.bottom - rect.top;
   }
   else {
-    wdc = GetDC(hwnd);
-    GetClientRect(hwnd, &rect);
-  }
-  if (!wdc) {
-    i_push_error(0, "Cannot get window DC - invalid hwnd?");
-    return NULL;
-  }
+    if (display == -1) {
+      fprintf(stderr, "all desktops\n");
+      cdc = CreateDC("DISPLAY", NULL, NULL, NULL);
+      orig_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
+      orig_y = GetSystemMetrics(SM_YVIRTUALSCREEN);
+      window_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+      window_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+    }
+    else {
+      DISPLAY_DEVICE dd;
+      dd.cb = sizeof(dd);
 
-  window_width = rect.right - rect.left;
-  window_height = rect.bottom - rect.top;
+      if (EnumDisplayDevices(NULL, display, &dd, 0)) {
+       fprintf(stderr, "found %d ->  %s\n", display, dd.DeviceName);
+       cdc = CreateDC(dd.DeviceName, dd.DeviceName, NULL, NULL);
+      }
+      else {
+       i_push_errorf(0, "Cannot enumerate device %d: %ld", display, (long)GetLastError());
+       return NULL;
+      }
+
+      window_width = GetDeviceCaps(cdc, HORZRES);
+      window_height = GetDeviceCaps(cdc, VERTRES);
+    }
+
+    wdc = cdc;
+  }
 
   /* adjust negative/zero values to window size */
   if (left < 0)
@@ -68,7 +97,7 @@ imss_win32(unsigned hwnd_u, int include_decor, int left, int top,
   work_bmp = CreateCompatibleBitmap(wdc, width, height);
   bmdc = CreateCompatibleDC(wdc);
   old_dc_bmp = SelectObject(bmdc, work_bmp);
-  BitBlt(bmdc, 0, 0, width, height, wdc, left, top, SRCCOPY);
+  BitBlt(bmdc, 0, 0, width, height, wdc, orig_x + left, orig_y + top, SRCCOPY);
 
   /* make a dib */
   memset(&bmi, 0, sizeof(bmi));
@@ -112,7 +141,13 @@ imss_win32(unsigned hwnd_u, int include_decor, int left, int top,
   SelectObject(bmdc, old_dc_bmp);
   DeleteDC(bmdc);
   DeleteObject(work_bmp);
-  ReleaseDC(hwnd, wdc);
+
+  if (cdc) {
+    DeleteDC(cdc);
+  }
+  else {
+    ReleaseDC(hwnd, wdc);
+  }
 
   return result;
 }