various distribution fixes:
[imager-screenshot.git] / scwin32.c
1 #include "imext.h"
2 #include <windows.h>
3 #include <string.h>
4
5 i_img *
6 imss_win32(unsigned hwnd_u, int include_decor) {
7   HWND hwnd = (HWND)hwnd_u;
8   HDC wdc, bmdc;
9   RECT rect;
10   HBITMAP work_bmp, old_dc_bmp;
11   int width, height;
12   BITMAPINFO bmi;
13   unsigned char *di_bits;
14   i_img *result = NULL;
15
16   i_clear_error();
17
18   if (!hwnd)
19     hwnd = GetDesktopWindow();
20
21   if (include_decor) {
22     wdc = GetWindowDC(hwnd);
23     GetWindowRect(hwnd, &rect);
24   }
25   else {
26     wdc = GetDC(hwnd);
27     GetClientRect(hwnd, &rect);
28   }
29   if (!wdc) {
30     i_push_error(0, "Cannot get window DC - invalid hwnd?");
31     return NULL;
32   }
33
34   width = rect.right - rect.left;
35   height = rect.bottom - rect.top;
36   work_bmp = CreateCompatibleBitmap(wdc, width, height);
37   bmdc = CreateCompatibleDC(wdc);
38   old_dc_bmp = SelectObject(bmdc, work_bmp);
39   BitBlt(bmdc, 0, 0, width, height, wdc, 0, 0, SRCCOPY);
40
41   /* make a dib */
42   memset(&bmi, 0, sizeof(bmi));
43   bmi.bmiHeader.biSize = sizeof(bmi);
44   bmi.bmiHeader.biWidth = width;
45   bmi.bmiHeader.biHeight = -height;
46   bmi.bmiHeader.biPlanes = 1;
47   bmi.bmiHeader.biBitCount = 32;
48   bmi.bmiHeader.biCompression = BI_RGB;
49
50   di_bits = mymalloc(4 * width * height);
51   if (GetDIBits(bmdc, work_bmp, 0, height, di_bits, &bmi, DIB_RGB_COLORS)) {
52     i_color *line = mymalloc(sizeof(i_color) * width);
53     i_color *cp;
54     int x, y;
55     unsigned char *ch_pp = di_bits;
56     result = i_img_8_new(width, height, 3);
57
58     for (y = 0; y < height; ++y) {
59       cp = line;
60       for (x = 0; x < width; ++x) {
61         cp->rgb.b = *ch_pp++;
62         cp->rgb.g = *ch_pp++;
63         cp->rgb.r = *ch_pp++;
64         ch_pp++;
65         cp++;
66       }
67       i_plin(result, 0, width, y, line);
68     }
69     myfree(line);
70   }
71
72   /* clean up */
73   myfree(di_bits);
74   SelectObject(bmdc, old_dc_bmp);
75   DeleteDC(bmdc);
76   DeleteObject(work_bmp);
77   ReleaseDC(hwnd, wdc);
78
79   return result;
80 }