polish/test darwin support
[imager-screenshot.git] / scwin32.c
index 228d182..3d9f8c2 100644 (file)
--- a/scwin32.c
+++ b/scwin32.c
-#include "imext.h"\r
-#include <windows.h>\r
-#include <string.h>\r
-\r
-i_img *\r
-imss_win32(unsigned hwnd_u, int include_decor) {\r
-  HWND hwnd = (HWND)hwnd_u;\r
-  HDC wdc, bmdc;\r
-  RECT rect;\r
-  HBITMAP work_bmp, old_dc_bmp;\r
-  int width, height;\r
-  BITMAPINFO bmi;\r
-  unsigned char *di_bits;\r
-  i_img *result = NULL;\r
-\r
-  i_clear_error();\r
-\r
-  if (!hwnd)\r
-    hwnd = GetDesktopWindow();\r
-\r
-  if (include_decor) {\r
-    wdc = GetWindowDC(hwnd);\r
-    GetWindowRect(hwnd, &rect);\r
-  }\r
-  else {\r
-    wdc = GetDC(hwnd);\r
-    GetClientRect(hwnd, &rect);\r
-  }\r
-  if (!wdc) {\r
-    i_push_error(0, "Cannot get window DC - invalid hwnd?");\r
-    return NULL;\r
-  }\r
-\r
-  width = rect.right - rect.left;\r
-  height = rect.bottom - rect.top;\r
-  work_bmp = CreateCompatibleBitmap(wdc, width, height);\r
-  bmdc = CreateCompatibleDC(wdc);\r
-  old_dc_bmp = SelectObject(bmdc, work_bmp);\r
-  BitBlt(bmdc, 0, 0, width, height, wdc, 0, 0, SRCCOPY);\r
-\r
-  /* make a dib */\r
-  memset(&bmi, 0, sizeof(bmi));\r
-  bmi.bmiHeader.biSize = sizeof(bmi);\r
-  bmi.bmiHeader.biWidth = width;\r
-  bmi.bmiHeader.biHeight = -height;\r
-  bmi.bmiHeader.biPlanes = 1;\r
-  bmi.bmiHeader.biBitCount = 32;\r
-  bmi.bmiHeader.biCompression = BI_RGB;\r
-\r
-  di_bits = mymalloc(4 * width * height);\r
-  if (GetDIBits(bmdc, work_bmp, 0, height, di_bits, &bmi, DIB_RGB_COLORS)) {\r
-    i_color *line = mymalloc(sizeof(i_color) * width);\r
-    i_color *cp;\r
-    int x, y;\r
-    unsigned char *ch_pp = di_bits;\r
-    result = i_img_8_new(width, height, 3);\r
-\r
-    for (y = 0; y < height; ++y) {\r
-      cp = line;\r
-      for (x = 0; x < width; ++x) {\r
-       cp->rgb.b = *ch_pp++;\r
-       cp->rgb.g = *ch_pp++;\r
-       cp->rgb.r = *ch_pp++;\r
-       ch_pp++;\r
-       cp++;\r
-      }\r
-      i_plin(result, 0, width, y, line);\r
-    }\r
-    myfree(line);\r
-  }\r
-\r
-  /* clean up */\r
-  myfree(di_bits);\r
-  SelectObject(bmdc, old_dc_bmp);\r
-  DeleteDC(bmdc);\r
-  DeleteObject(work_bmp);\r
-  ReleaseDC(hwnd, wdc);\r
-\r
-  return result;\r
-}\r
+#include "imext.h"
+#include <windows.h>
+#include <string.h>
+#include "imss.h"
+
+i_img *
+imss_win32(unsigned hwnd_u, int include_decor, int left, int top, 
+          int right, int bottom) {
+  HWND hwnd = (HWND)hwnd_u;
+  HDC wdc, bmdc;
+  RECT rect;
+  HBITMAP work_bmp, old_dc_bmp;
+  int window_width, window_height;
+  BITMAPINFO bmi;
+  unsigned char *di_bits;
+  i_img *result = NULL;
+  int width, height;
+
+  i_clear_error();
+
+  if (!hwnd)
+    hwnd = GetDesktopWindow();
+
+  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;
+  }
+
+  window_width = rect.right - rect.left;
+  window_height = rect.bottom - rect.top;
+
+  /* adjust negative/zero values to window size */
+  if (left < 0)
+    left += window_width;
+  if (top < 0)
+    top += window_height;
+  if (right <= 0)
+    right += window_width;
+  if (bottom <= 0)
+    bottom += window_height;
+  
+  /* clamp */
+  if (left < 0)
+    left = 0;
+  if (right > window_width)
+    right = window_width;
+  if (top < 0)
+    top = 0;
+  if (bottom > window_height)
+    bottom = window_height;
+
+  /* validate */
+  if (right <= left || bottom <= top) {
+    i_push_error(0, "image would be empty");
+    return NULL;
+  }
+  width = right - left;
+  height = bottom - 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);
+
+  /* make a dib */
+  memset(&bmi, 0, sizeof(bmi));
+  bmi.bmiHeader.biSize = sizeof(bmi);
+  bmi.bmiHeader.biWidth = width;
+  bmi.bmiHeader.biHeight = -height;
+  bmi.bmiHeader.biPlanes = 1;
+  bmi.bmiHeader.biBitCount = 32;
+  bmi.bmiHeader.biCompression = BI_RGB;
+
+  di_bits = mymalloc(4 * width * height);
+  if (GetDIBits(bmdc, work_bmp, 0, height, di_bits, &bmi, DIB_RGB_COLORS)) {
+    i_color *line = mymalloc(sizeof(i_color) * width);
+    i_color *cp;
+    int x, y;
+    unsigned char *ch_pp = di_bits;
+    result = i_img_8_new(width, height, 3);
+
+    for (y = 0; y < height; ++y) {
+      cp = line;
+      for (x = 0; x < width; ++x) {
+       cp->rgb.b = *ch_pp++;
+       cp->rgb.g = *ch_pp++;
+       cp->rgb.r = *ch_pp++;
+       ch_pp++;
+       cp++;
+      }
+      i_plin(result, 0, width, y, line);
+    }
+    myfree(line);
+  }
+
+  i_tags_setn(&result->tags, "ss_window_width", window_width);
+  i_tags_setn(&result->tags, "ss_window_height", window_height);
+  i_tags_set(&result->tags, "ss_type", "Win32", 5);
+  i_tags_setn(&result->tags, "ss_left", left);
+  i_tags_setn(&result->tags, "ss_top", top);
+
+  /* clean up */
+  myfree(di_bits);
+  SelectObject(bmdc, old_dc_bmp);
+  DeleteDC(bmdc);
+  DeleteObject(work_bmp);
+  ReleaseDC(hwnd, wdc);
+
+  return result;
+}