6 /* the SDK headers supplied with cygwin, and with some older strawberry perls */
7 #ifndef DISPLAY_DEVICE_ACTIVE
8 #define DISPLAY_DEVICE_ACTIVE 1
13 i_img_dim orig_x, orig_y;
18 display_to_img(HDC dc, i_img *im, const RECT *src, int dest_x, int dest_y) {
22 i_img_dim width = src->right - src->left;
23 i_img_dim height = src->bottom - src->top;
26 unsigned char *di_bits;
28 work_bmp = CreateCompatibleBitmap(dc, width, height);
29 bmdc = CreateCompatibleDC(dc);
30 old_dc_bmp = SelectObject(bmdc, work_bmp);
31 BitBlt(bmdc, 0, 0, width, height, dc, src->left, src->top, SRCCOPY);
34 memset(&bmi, 0, sizeof(bmi));
35 bmi.bmiHeader.biSize = sizeof(bmi);
36 bmi.bmiHeader.biWidth = width;
37 bmi.bmiHeader.biHeight = -height;
38 bmi.bmiHeader.biPlanes = 1;
39 bmi.bmiHeader.biBitCount = 32;
40 bmi.bmiHeader.biCompression = BI_RGB;
42 di_bits = mymalloc(4 * width * height);
43 if (GetDIBits(bmdc, work_bmp, 0, height, di_bits, &bmi, DIB_RGB_COLORS)) {
44 i_color *line = mymalloc(sizeof(i_color) * width);
47 unsigned char *ch_pp = di_bits;
48 for (y = 0; y < height; ++y) {
50 for (x = 0; x < width; ++x) {
51 cp->rgba.b = *ch_pp++;
52 cp->rgba.g = *ch_pp++;
53 cp->rgba.r = *ch_pp++;
58 i_plin(im, dest_x, dest_x+width, dest_y + y, line);
64 i_push_errorf(0, "GetDIBits() failure %d", (long)GetLastError());
68 SelectObject(bmdc, old_dc_bmp);
70 DeleteObject(work_bmp);
76 monitor_enum(HMONITOR hmon, HDC dc, LPRECT r, LPARAM lp_ctx) {
77 struct monitor_ctx *ctx = (struct monitor_ctx *)lp_ctx;
79 if (!display_to_img(dc, ctx->out, r,
80 r->left - ctx->orig_x, r->top - ctx->orig_y)) {
89 imss_win32(unsigned hwnd_u, int include_decor, int left, int top,
90 int right, int bottom, int display) {
91 HWND hwnd = (HWND)hwnd_u;
95 int window_width, window_height;
105 wdc = GetWindowDC(hwnd);
106 GetWindowRect(hwnd, &rect);
110 GetClientRect(hwnd, &rect);
113 i_push_error(0, "Cannot get window DC - invalid hwnd?");
117 window_width = rect.right - rect.left;
118 window_height = rect.bottom - rect.top;
122 cdc = CreateDC("DISPLAY", NULL, NULL, NULL);
123 orig_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
124 orig_y = GetSystemMetrics(SM_YVIRTUALSCREEN);
125 window_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
126 window_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
133 if (EnumDisplayDevices(NULL, display, &dd, 0)) {
134 printf("Flags %lx\n", (unsigned long)dd.StateFlags);
135 if (dd.StateFlags & DISPLAY_DEVICE_ACTIVE) {
136 cdc = CreateDC(dd.DeviceName, dd.DeviceName, NULL, NULL);
139 i_push_errorf(0, "Display device %d not active", display);
144 i_push_errorf(0, "Cannot enumerate device %d: %ld", display, (long)GetLastError());
148 window_width = GetDeviceCaps(cdc, HORZRES);
149 window_height = GetDeviceCaps(cdc, VERTRES);
155 /* adjust negative/zero values to window size */
157 left += window_width;
159 top += window_height;
161 right += window_width;
163 bottom += window_height;
168 if (right > window_width)
169 right = window_width;
172 if (bottom > window_height)
173 bottom = window_height;
176 if (right <= left || bottom <= top) {
177 i_push_error(0, "image would be empty");
181 ReleaseDC(hwnd, wdc);
184 width = right - left;
185 height = bottom - top;
187 result = i_img_8_new(width, height, channels);
191 r.left = orig_x + left;
192 r.top = orig_y + top;
193 r.right = r.left + width;
194 r.bottom = r.top + height;
197 struct monitor_ctx ctx;
203 if (!EnumDisplayMonitors(wdc, &r, monitor_enum, (LPARAM)&ctx)
205 i_img_destroy(result);
210 if (!display_to_img(wdc, result, &r, 0, 0)) {
211 i_img_destroy(result);
216 i_tags_setn(&result->tags, "ss_window_width", window_width);
217 i_tags_setn(&result->tags, "ss_window_height", window_height);
218 i_tags_set(&result->tags, "ss_type", "Win32", 5);
219 i_tags_setn(&result->tags, "ss_left", left);
220 i_tags_setn(&result->tags, "ss_top", top);
228 ReleaseDC(hwnd, wdc);