1 /********************************************************************/
2 /*                                                                  */
3 /*  drw_win.c     Graphic access using the windows capabilities.    */
4 /*  Copyright (C) 1989 - 2017, 2019 - 2021  Thomas Mertes           */
5 /*                                                                  */
6 /*  This file is part of the Seed7 Runtime Library.                 */
7 /*                                                                  */
8 /*  The Seed7 Runtime Library is free software; you can             */
9 /*  redistribute it and/or modify it under the terms of the GNU     */
10 /*  Lesser General Public License as published by the Free Software */
11 /*  Foundation; either version 2.1 of the License, or (at your      */
12 /*  option) any later version.                                      */
13 /*                                                                  */
14 /*  The Seed7 Runtime Library is distributed in the hope that it    */
15 /*  will be useful, but WITHOUT ANY WARRANTY; without even the      */
16 /*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /*  PURPOSE.  See the GNU Lesser General Public License for more    */
18 /*  details.                                                        */
19 /*                                                                  */
20 /*  You should have received a copy of the GNU Lesser General       */
21 /*  Public License along with this program; if not, write to the    */
22 /*  Free Software Foundation, Inc., 51 Franklin Street,             */
23 /*  Fifth Floor, Boston, MA  02110-1301, USA.                       */
24 /*                                                                  */
25 /*  Module: Seed7 Runtime Library                                   */
26 /*  File: seed7/src/drw_win.c                                       */
27 /*  Changes: 2005 - 2007, 2013 - 2017, 2019 - 2021  Thomas Mertes   */
28 /*  Content: Graphic access using the windows capabilities.         */
29 /*                                                                  */
30 /********************************************************************/
31 
32 #define LOG_FUNCTIONS 0
33 #define VERBOSE_EXCEPTIONS 0
34 
35 #include "version.h"
36 
37 #include "stdlib.h"
38 #include "stdio.h"
39 #include "string.h"
40 #include "limits.h"
41 #include "windows.h"
42 
43 #include "common.h"
44 #include "data_rtl.h"
45 #include "heaputl.h"
46 #include "striutl.h"
47 #include "kbd_drv.h"
48 #include "rtl_err.h"
49 
50 #undef EXTERN
51 #define EXTERN
52 #include "drw_drv.h"
53 
54 
55 #define TRACE_EVENTS 0
56 #if TRACE_EVENTS
57 #define traceEvent(traceStatements) traceStatements
58 #else
59 #define traceEvent(traceStatements)
60 #endif
61 
62 #define PI 3.141592653589793238462643383279502884197
63 
64 #define windowClass "MyWindowClass"
65 #define windowClassW L"MyWindowClass"
66 
67 static intType init_called = 0;
68 
69 typedef struct {
70     uintType usage_count;
71     /* Up to here the structure is identical to struct winStruct */
72     HWND hWnd;
73     HDC hdc;
74     HBITMAP backup;
75     HDC backup_hdc;
76     HBITMAP hBitmap;
77     HBITMAP oldBitmap;
78     boolType hasTransparentPixel;
79     UINT transparentPixel;
80     HBITMAP maskBitmap;
81     boolType is_pixmap;
82     unsigned int width;  /* Always <= INT_MAX: Cast to int is safe. */
83     unsigned int height; /* Always <= INT_MAX: Cast to int is safe. */
84     unsigned int backupWidth;  /* Always <= INT_MAX: Cast to int is safe. */
85     unsigned int backupHeight; /* Always <= INT_MAX: Cast to int is safe. */
86     unsigned int bruttoWidthDelta;
87     unsigned int bruttoHeightDelta;
88     boolType minimized;
89     intType clear_col;
90     int close_action;
91     boolType resizeReturnsKey;
92     boolType cursorVisible;
93   } win_winRecord, *win_winType;
94 
95 typedef const win_winRecord *const_win_winType;
96 
97 #define to_hwnd(win)                 (((const_win_winType) win)->hWnd)
98 #define to_hdc(win)                  (((const_win_winType) win)->hdc)
99 #define to_backup_hdc(win)           (((const_win_winType) win)->backup_hdc)
100 #define to_backup(win)               (((const_win_winType) win)->backup)
101 #define to_hBitmap(win)              (((const_win_winType) win)->hBitmap)
102 #define to_oldBitmap(win)            (((const_win_winType) win)->oldBitmap)
103 #define is_pixmap(win)               (((const_win_winType) win)->is_pixmap)
104 #define to_hasTransparentPixel(win)  (((const_win_winType) win)->hasTransparentPixel)
105 #define to_transparentPixel(win)     (((const_win_winType) win)->transparentPixel)
106 #define to_maskBitmap(win)           (((const_win_winType) win)->maskBitmap)
107 #define to_width(win)                (((const_win_winType) win)->width)
108 #define to_height(win)               (((const_win_winType) win)->height)
109 #define to_backupWidth(win)          (((const_win_winType) win)->backupWidth)
110 #define to_backupHeight(win)         (((const_win_winType) win)->backupHeight)
111 #define to_bruttoWidthDelta(win)     (((const_win_winType) win)->bruttoWidthDelta)
112 #define to_bruttoHeightDelta(win)    (((const_win_winType) win)->bruttoHeightDelta)
113 #define to_minimized(win)            (((const_win_winType) win)->minimized)
114 #define to_clear_col(win)            (((const_win_winType) win)->clear_col)
115 #define to_close_action(win)         (((const_win_winType) win)->close_action)
116 #define to_resizeReturnsKey(win)     (((const_win_winType) win)->resizeReturnsKey)
117 #define to_cursorVisible(win)        (((const_win_winType) win)->cursorVisible)
118 
119 #define to_var_hasTransparentPixel(win)  (((win_winType) win)->hasTransparentPixel)
120 #define to_var_transparentPixel(win)     (((win_winType) win)->transparentPixel)
121 #define to_var_maskBitmap(win)           (((win_winType) win)->maskBitmap)
122 #define to_var_clear_col(win)            (((win_winType) win)->clear_col)
123 #define to_var_close_action(win)         (((win_winType) win)->close_action)
124 #define to_var_resizeReturnsKey(win)     (((win_winType) win)->resizeReturnsKey)
125 #define to_var_cursorVisible(win)        (((win_winType) win)->cursorVisible)
126 
127 #ifndef WM_NCMOUSELEAVE
128 #define WM_NCMOUSELEAVE 674
129 #endif
130 
131 #ifndef WS_EX_NOACTIVATE
132 #define WS_EX_NOACTIVATE 0x08000000L
133 #endif
134 
135 typedef HWND (WINAPI *pGetConsoleWindowType)(void);
136 static pGetConsoleWindowType pGetConsoleWindow = NULL;
137 
138 
139 
140 winType find_window (HWND sys_window);
141 void enter_window (winType curr_window, HWND sys_window);
142 void remove_window (HWND sys_window);
143 
144 
145 
getCloseAction(winType actual_window)146 int getCloseAction (winType actual_window)
147 
148   { /* getCloseAction */
149     return to_close_action(actual_window);
150   } /* getCloseAction */
151 
152 
153 
drawRectangle(HDC hdc,intType x1,intType y1,intType x2,intType y2,intType col)154 static void drawRectangle (HDC hdc, intType x1, intType y1,
155     intType x2, intType y2, intType col)
156 
157   {
158     HPEN old_pen;
159     HPEN current_pen;
160     HBRUSH old_brush;
161     HBRUSH current_brush;
162 
163   /* drawRectangle */
164     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
165     current_brush = CreateSolidBrush((COLORREF) col);
166     if (unlikely(current_pen == NULL || current_brush == NULL)) {
167       raise_error(MEMORY_ERROR);
168     } else {
169       old_pen = (HPEN) SelectObject(hdc, current_pen);
170       old_brush = (HBRUSH) SelectObject(hdc, current_brush);
171       if (x1 == x2) {
172         if (y1 == y2) {
173           SetPixel(hdc, castToInt(x1), castToInt(y1), (COLORREF) col);
174         } else {
175           MoveToEx(hdc, castToInt(x1), castToInt(y1), NULL);
176           LineTo(hdc, castToInt(x1), castToInt(y2 + 1));
177         } /* if */
178       } else {
179         if (y1 == y2) {
180           MoveToEx(hdc, castToInt(x1), castToInt(y1), NULL);
181           LineTo(hdc, castToInt(x2 + 1), castToInt(y1));
182         } else {
183           Rectangle(hdc, castToInt(x1), castToInt(y1), castToInt(x2 + 1), castToInt(y2 + 1));
184         } /* if */
185       } /* if */
186       SelectObject(hdc, old_pen);
187       SelectObject(hdc, old_brush);
188       DeleteObject(current_pen);
189       DeleteObject(current_brush);
190     } /* if */
191   } /* drawRectangle */
192 
193 
194 
setResizeReturnsKey(winType resizeWindow,boolType active)195 void setResizeReturnsKey (winType resizeWindow, boolType active)
196 
197   { /* setResizeReturnsKey */
198     to_var_resizeReturnsKey(resizeWindow) = active;
199   } /* setResizeReturnsKey */
200 
201 
202 
getResizeReturnsKey(winType resizeWindow)203 boolType getResizeReturnsKey (winType resizeWindow)
204 
205   { /* getResizeReturnsKey */
206     return to_resizeReturnsKey(resizeWindow);
207   } /* getResizeReturnsKey */
208 
209 
210 
resize(win_winType resizeWindow,unsigned int width,unsigned int height)211 static void resize (win_winType resizeWindow, unsigned int width,
212     unsigned int height)
213 
214   {
215     HDC newBackupHdc;
216     HBITMAP newBackup;
217     unsigned int newWidth;
218     unsigned int newHeight;
219 
220   /* resize */
221     logFunction(printf("resize(" FMT_U_MEM ", %d, %d)\n",
222                        (memSizeType) resizeWindow, width, height););
223     if (resizeWindow != NULL && resizeWindow->backup_hdc != 0) {
224       if (resizeWindow->backupWidth < width ||
225           resizeWindow->backupHeight < height) {
226         newWidth = resizeWindow->backupWidth > width ? resizeWindow->backupWidth : width;
227         newHeight = resizeWindow->backupHeight > height ? resizeWindow->backupHeight : height;
228         newBackupHdc = CreateCompatibleDC(resizeWindow->hdc);
229         newBackup = CreateCompatibleBitmap(resizeWindow->hdc, (int) newWidth, (int) newHeight);
230         SelectObject(newBackupHdc, newBackup);
231         drawRectangle(newBackupHdc, 0, 0, newWidth - 1, newHeight - 1,
232                       resizeWindow->clear_col);
233         BitBlt(newBackupHdc, 0, 0,
234                (int) resizeWindow->backupWidth, (int) resizeWindow->backupHeight,
235                resizeWindow->backup_hdc, 0, 0, SRCCOPY);
236         DeleteObject(resizeWindow->backup);
237         DeleteDC(resizeWindow->backup_hdc);
238         resizeWindow->backup = newBackup;
239         resizeWindow->backup_hdc = newBackupHdc;
240         resizeWindow->backupWidth = newWidth;
241         resizeWindow->backupHeight = newHeight;
242       } /* if */
243       resizeWindow->width = width;
244       resizeWindow->height = height;
245     } /* if */
246     logFunction(printf("resize -->\n"););
247   } /* resize */
248 
249 
250 
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)251 LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
252   {
253     win_winType paint_window;
254     PAINTSTRUCT paintStruct;
255     RECT rect;
256     RECT rect2;
257     LRESULT result;
258 
259   /* WndProc */
260     logFunction(printf("WndProc message=%d, %lu, %d, %u\n",
261                        message, hWnd, wParam, lParam););
262     switch (message) {
263       case WM_PAINT:
264         traceEvent(printf("WndProc WM_PAINT hwnd=" FMT_U_MEM
265                           ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
266                           (memSizeType) hWnd, (uint64Type) wParam,
267                           (uint64Type) lParam););
268         paint_window = (win_winType) find_window(hWnd);
269         if (paint_window != NULL && paint_window->backup_hdc != 0) {
270           BeginPaint(paint_window->hWnd, &paintStruct);
271           /* printf("BeginPaint left=%ld, top=%ld, right=%ld, bottom=%ld\n",
272               paintStruct.rcPaint.left, paintStruct.rcPaint.top,
273               paintStruct.rcPaint.right, paintStruct.rcPaint.bottom); */
274           /* printf("WM_PAINT      %lu %d/%d %d/%d\n", hWnd,
275               paintStruct.rcPaint.left, paintStruct.rcPaint.top,
276               paintStruct.rcPaint.right - paintStruct.rcPaint.left,
277               paintStruct.rcPaint.bottom - paintStruct.rcPaint.top); */
278           BitBlt(to_hdc(paint_window),
279               paintStruct.rcPaint.left, paintStruct.rcPaint.top,
280               paintStruct.rcPaint.right - paintStruct.rcPaint.left,
281               paintStruct.rcPaint.bottom - paintStruct.rcPaint.top,
282               to_backup_hdc(paint_window),
283               paintStruct.rcPaint.left, paintStruct.rcPaint.top, SRCCOPY);
284           EndPaint(paint_window->hWnd, &paintStruct);
285         } else {
286           printf("paint_window=" FMT_U_MEM ", backup_hdc=" FMT_U_MEM "\n",
287               (memSizeType) paint_window,
288               (memSizeType) paint_window->backup_hdc);
289         } /* if */
290         result = 0;
291         break;
292       case WM_ERASEBKGND:
293         traceEvent(printf("WndProc WM_ERASEBKGND hwnd=" FMT_U_MEM
294                           ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
295                           (memSizeType) hWnd, (uint64Type) wParam,
296                           (uint64Type) lParam););
297         paint_window = (win_winType) find_window(hWnd);
298         if (paint_window != NULL && paint_window->backup_hdc != 0) {
299           if (GetUpdateRect(paint_window->hWnd, &rect, FALSE) != 0) {
300             /* printf("GetUpdateRect left=%ld, top=%ld, right=%ld, bottom=%ld\n",
301                rect.left, rect.top, rect.right, rect.bottom); */
302             /* printf("WM_ERASEBKGND %lu %d/%d %d/%d\n", hWnd,
303                 rect.left, rect.top,
304                 rect.right - rect.left,
305                 rect.bottom - rect.top); */
306           } else {
307             /* printf("GetUpdateRect no update region\n"); */
308             GetClientRect(paint_window->hWnd, &rect);
309             /* printf("GetClientRect left=%ld, top=%ld, right=%ld, bottom=%ld\n",
310                 rect.left, rect.top, rect.right, rect.bottom); */
311             /* printf("WM_ERASEBKGND %lu %d/%d %d/%d +\n", hWnd,
312                 rect.left, rect.top,
313                 rect.right - rect.left,
314                 rect.bottom - rect.top); */
315           } /* if */
316           /* printf("window width=%ld, height=%ld\n",
317               paint_window->width, paint_window->height); */
318           if (rect.right >= 0 && (unsigned int) rect.right >= paint_window->width) {
319             if (rect.left < 0 || (unsigned int) rect.left < paint_window->width) {
320               rect2.left = (LONG) paint_window->width;
321             } else {
322               rect2.left = rect.left;
323             } /* if */
324             if (rect.bottom >= 0 && (unsigned int) rect.bottom >= paint_window->height) {
325               rect2.bottom = (LONG) paint_window->height - 1;
326             } else {
327               rect2.bottom = rect.bottom;
328             } /* if */
329             /* printf("drawRectangle left=%ld, top=%ld, right=%ld, bottom=%ld\n",
330                 rect2.left, rect.top, rect.right, rect2.bottom); */
331             drawRectangle(paint_window->hdc, rect2.left, rect.top, rect.right, rect2.bottom,
332                 to_clear_col(paint_window));
333                 /* GetBkColor(paint_window->hWnd)); */
334           } /* if */
335           if (rect.bottom >= 0 && (unsigned int) rect.bottom >= paint_window->height) {
336             if (rect.top < 0 || (unsigned int) rect.top < paint_window->height) {
337               rect2.top = (LONG) paint_window->height;
338             } else {
339               rect2.top = rect.top;
340             } /* if */
341             /* printf("drawRectangle left=%ld, top=%ld, right=%ld, bottom=%ld\n",
342                 rect.left, rect2.top, rect.right, rect.bottom); */
343             drawRectangle(paint_window->hdc, rect.left, rect2.top, rect.right, rect.bottom,
344                 to_clear_col(paint_window));
345                 /* GetBkColor(paint_window->hWnd)); */
346           } /* if */
347         } else {
348           printf("paint_window=" FMT_U_MEM ", backup_hdc=" FMT_U_MEM "\n",
349               (memSizeType) paint_window,
350               (memSizeType) paint_window->backup_hdc);
351         } /* if */
352         result = 1;
353         break;
354       case WM_SIZE:
355         traceEvent(printf("WndProc WM_SIZE hwnd=" FMT_U_MEM
356                           ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
357                           (memSizeType) hWnd, (uint64Type) wParam,
358                           (uint64Type) lParam););
359         paint_window = (win_winType) find_window(hWnd);
360         resize(paint_window, (unsigned int) LOWORD(lParam),
361                (unsigned int) HIWORD(lParam));
362         result = 1;
363         break;
364       case WM_SETCURSOR:
365         traceEvent(printf("WndProc WM_SETCURSOR hwnd=" FMT_U_MEM
366                           ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
367                           (memSizeType) hWnd, (uint64Type) wParam,
368                           (uint64Type) lParam););
369         paint_window = (win_winType) find_window(hWnd);
370         if (LOWORD(lParam) == HTCLIENT && !paint_window->cursorVisible) {
371           SetCursor(NULL);
372           result = 1;
373         } else{
374           result = DefWindowProc(hWnd, message, wParam, lParam);
375         } /* if */
376         break;
377       case WM_SYSCOMMAND:
378         traceEvent(printf("WndProc WM_SYSCOMMAND: hwnd=" FMT_U_MEM
379                           ", wParam=" FMT_U64 ", lParam=" FMT_X64 "\n",
380                           (memSizeType) hWnd, (uint64Type) wParam,
381                           (uint64Type) lParam););
382         if (wParam == SC_MAXIMIZE || wParam == SC_RESTORE) {
383           /* printf("SC_MAXIMIZE / SC_RESTORE\n"); */
384           paint_window = (win_winType) find_window(hWnd);
385           if (paint_window != NULL) {
386             if (paint_window->minimized) {
387               paint_window->minimized = FALSE;
388             } else if (paint_window->resizeReturnsKey) {
389               /* printf("send WM_USER\n"); */
390               PostMessageA(hWnd, WM_USER, wParam, lParam);
391             } /* if */
392           } /* if */
393         } else if (wParam == SC_MINIMIZE) {
394           /* printf("SC_MINIMIZE\n"); */
395           paint_window = (win_winType) find_window(hWnd);
396           if (paint_window != NULL) {
397             paint_window->minimized = TRUE;
398           } /* if */
399         } /* if */
400         result = DefWindowProc(hWnd, message, wParam, lParam);
401         break;
402       default:
403         result = DefWindowProc(hWnd, message, wParam, lParam);
404         break;
405     } /* switch */
406     logFunction(printf("WndProc --> %d\n", result););
407     return result;
408   } /* WndProc */
409 
410 
411 
drawInit(void)412 static void drawInit (void)
413 
414   {
415     WNDCLASSEX wcex = {0};
416     HMODULE hntdll = 0;
417 
418   /* drawInit */
419     wcex.cbSize        = sizeof(WNDCLASSEX);
420     wcex.style         = /* CS_HREDRAW | CS_VREDRAW | */ CS_OWNDC;
421     wcex.lpfnWndProc   = (WNDPROC) WndProc;
422     wcex.hInstance     = NULL;
423     wcex.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
424     wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
425     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
426     wcex.lpszMenuName  = NULL;
427     wcex.lpszClassName = windowClass;
428     wcex.hIconSm       = NULL;
429     RegisterClassEx(&wcex);
430     hntdll = LoadLibraryA("kernel32.dll");
431     if (hntdll != 0) {
432       pGetConsoleWindow = (pGetConsoleWindowType) GetProcAddress(hntdll, "GetConsoleWindow");
433     } /* if */
434     init_called = 1;
435   } /* drawInit */
436 
437 
438 
439 /**
440  *  Return the X position of the pointer relative to the specified window.
441  *  The point of origin is the top left corner of the drawing area
442  *  of the given 'actual_window' (inside of the window decorations).
443  *  If 'actual_window' is the empty window the pointer X position is
444  *  relative to the top left corner of the screen.
445  */
drwPointerXpos(const_winType actual_window)446 intType drwPointerXpos (const_winType actual_window)
447 
448   {
449     POINT point;
450     intType xPos;
451 
452   /* drwPointerXpos */
453     logFunction(printf("drwPointerXpos(" FMT_U_MEM ")\n",
454                        (memSizeType) actual_window););
455     if (unlikely(GetCursorPos(&point) == 0)) {
456       raise_error(FILE_ERROR);
457       xPos = 0;
458     } else if (to_width(actual_window) == 0 && to_height(actual_window) == 0) {
459       xPos = point.x;
460     } else {
461       if (unlikely(ScreenToClient(to_hwnd(actual_window), &point) == 0)) {
462         raise_error(FILE_ERROR);
463         xPos = 0;
464       } else {
465         xPos = point.x;
466       } /* if */
467     } /* if */
468     logFunction(printf("drwPointerXpos(" FMT_U_MEM ") --> " FMT_D "\n",
469                        (memSizeType) actual_window, xPos););
470     return xPos;
471   } /* drwPointerXpos */
472 
473 
474 
475 /**
476  *  Return the Y position of the pointer relative to the specified window.
477  *  The point of origin is the top left corner of the drawing area
478  *  of the given 'actual_window' (inside of the window decorations).
479  *  If 'actual_window' is the empty window the pointer Y position is
480  *  relative to the top left corner of the screen.
481  */
drwPointerYpos(const_winType actual_window)482 intType drwPointerYpos (const_winType actual_window)
483 
484   {
485     POINT point;
486     intType yPos;
487 
488   /* drwPointerYpos */
489     logFunction(printf("drwPointerYpos(" FMT_U_MEM ")\n",
490                        (memSizeType) actual_window););
491     if (unlikely(GetCursorPos(&point) == 0)) {
492       raise_error(FILE_ERROR);
493       yPos = 0;
494     } else if (to_width(actual_window) == 0 && to_height(actual_window) == 0) {
495       yPos = point.y;
496     } else {
497       if (unlikely(ScreenToClient(to_hwnd(actual_window), &point) == 0)) {
498         raise_error(FILE_ERROR);
499         yPos = 0;
500       } else {
501         yPos = point.y;
502       } /* if */
503     } /* if */
504     logFunction(printf("drwPointerYpos(" FMT_U_MEM ") --> " FMT_D "\n",
505                        (memSizeType) actual_window, yPos););
506     return yPos;
507   } /* drwPointerYpos */
508 
509 
510 
drwArc(const_winType actual_window,intType x,intType y,intType radius,floatType startAngle,floatType sweepAngle)511 void drwArc (const_winType actual_window, intType x, intType y,
512     intType radius, floatType startAngle, floatType sweepAngle)
513 
514   {
515     FLOAT startAng, sweepAng;
516 
517   /* drwArc */
518     startAng = (FLOAT) (startAngle * (360.0 / (2 * PI)));
519     sweepAng = (FLOAT) (sweepAngle * (360.0 / (2 * PI)));
520     AngleArc(to_hdc(actual_window), castToInt(x), castToInt(y),
521              (unsigned) radius, startAng, sweepAng);
522   } /* drwArc */
523 
524 
525 
drwPArc(const_winType actual_window,intType x,intType y,intType radius,floatType startAngle,floatType sweepAngle,intType col)526 void drwPArc (const_winType actual_window, intType x, intType y,
527     intType radius, floatType startAngle, floatType sweepAngle, intType col)
528 
529   {
530     FLOAT startAng, sweepAng;
531     HPEN old_pen;
532     HPEN current_pen;
533 
534   /* drwPArc */
535     startAng = (FLOAT) (startAngle * (360.0 / (2 * PI)));
536     sweepAng = (FLOAT) (sweepAngle * (360.0 / (2 * PI)));
537     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
538     if (unlikely(current_pen == NULL)) {
539       raise_error(MEMORY_ERROR);
540     } else if (unlikely(!inIntRange(x) || !inIntRange(x))) {
541       raise_error(RANGE_ERROR);
542     } else {
543       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
544       /* MoveToEx(to_hdc(actual_window), x + radius, y, NULL); */
545       AngleArc(to_hdc(actual_window), (int) x, (int) y, (unsigned) radius, startAng, sweepAng);
546       SelectObject(to_hdc(actual_window), old_pen);
547       if (to_backup_hdc(actual_window) != 0) {
548         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
549         /* MoveToEx(to_backup_hdc(actual_window), x + radius, y, NULL); */
550         AngleArc(to_backup_hdc(actual_window), (int) x, (int) y, (unsigned) radius, startAng, sweepAng);
551         SelectObject(to_backup_hdc(actual_window), old_pen);
552       } /* if */
553       DeleteObject(current_pen);
554     } /* if */
555   } /* drwPArc */
556 
557 
558 
drwFArcChord(const_winType actual_window,intType x,intType y,intType radius,floatType startAngle,floatType sweepAngle)559 void drwFArcChord (const_winType actual_window, intType x, intType y,
560     intType radius, floatType startAngle, floatType sweepAngle)
561 
562   { /* drwFArcChord */
563   } /* drwFArcChord */
564 
565 
566 
drwPFArcChord(const_winType actual_window,intType x,intType y,intType radius,floatType startAngle,floatType sweepAngle,intType col)567 void drwPFArcChord (const_winType actual_window, intType x, intType y,
568     intType radius, floatType startAngle, floatType sweepAngle, intType col)
569 
570   { /* drwPFArcChord */
571   } /* drwPFArcChord */
572 
573 
574 
drwFArcPieSlice(const_winType actual_window,intType x,intType y,intType radius,floatType startAngle,floatType sweepAngle)575 void drwFArcPieSlice (const_winType actual_window, intType x, intType y,
576     intType radius, floatType startAngle, floatType sweepAngle)
577 
578   { /* drwFArcPieSlice */
579   } /* drwFArcPieSlice */
580 
581 
582 
drwPFArcPieSlice(const_winType actual_window,intType x,intType y,intType radius,floatType startAngle,floatType sweepAngle,intType col)583 void drwPFArcPieSlice (const_winType actual_window, intType x, intType y,
584     intType radius, floatType startAngle, floatType sweepAngle, intType col)
585 
586   {
587     FLOAT startAng, sweepAng;
588     HPEN old_pen;
589     HPEN current_pen;
590     HBRUSH old_brush;
591     HBRUSH current_brush;
592 
593   /* drwPFArcPieSlice */
594     if (sweepAngle != 0.0) {
595       startAng = (FLOAT) (startAngle * (360.0 / (2 * PI)));
596       sweepAng = (FLOAT) (sweepAngle * (360.0 / (2 * PI)));
597       current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
598       current_brush = CreateSolidBrush((COLORREF) col);
599       if (unlikely(current_pen == NULL || current_brush == NULL)) {
600         raise_error(MEMORY_ERROR);
601       } else if (unlikely(!inIntRange(x) || !inIntRange(x) ||
602                           !inIntRange(radius) || radius < 0)) {
603         raise_error(RANGE_ERROR);
604       } else {
605         old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
606         old_brush = (HBRUSH) SelectObject(to_hdc(actual_window), current_brush);
607         BeginPath(to_hdc(actual_window));
608         MoveToEx(to_hdc(actual_window), (int) x, (int) y, (LPPOINT) NULL);
609         AngleArc(to_hdc(actual_window), (int) x, (int) y, (DWORD) radius, startAng, sweepAng);
610         LineTo(to_hdc(actual_window), (int) x, (int) y);
611         EndPath(to_hdc(actual_window));
612         StrokeAndFillPath(to_hdc(actual_window));
613         SelectObject(to_hdc(actual_window), old_pen);
614         SelectObject(to_hdc(actual_window), old_brush);
615         if (to_backup_hdc(actual_window) != 0) {
616           old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
617           old_brush = (HBRUSH) SelectObject(to_backup_hdc(actual_window), current_brush);
618           BeginPath(to_backup_hdc(actual_window));
619           MoveToEx(to_backup_hdc(actual_window), (int) x, (int) y, (LPPOINT) NULL);
620           AngleArc(to_backup_hdc(actual_window), (int) x, (int) y, (DWORD) radius, startAng, sweepAng);
621           LineTo(to_backup_hdc(actual_window), (int) x, (int) y);
622           EndPath(to_backup_hdc(actual_window));
623           StrokeAndFillPath(to_backup_hdc(actual_window));
624           SelectObject(to_backup_hdc(actual_window), old_pen);
625           SelectObject(to_backup_hdc(actual_window), old_brush);
626         } /* if */
627         DeleteObject(current_pen);
628         DeleteObject(current_brush);
629       } /* if */
630     } /* if */
631   } /* drwPFArcPieSlice */
632 
633 
634 
drwArc2(const_winType actual_window,intType x1,intType y1,intType x2,intType y2,intType radius)635 void drwArc2 (const_winType actual_window,
636     intType x1, intType y1, intType x2, intType y2, intType radius)
637 
638   { /* drwArc2 */
639   } /* drwArc2 */
640 
641 
642 
643 /**
644  *  Determine the border widths of a window in pixels.
645  *  These are the widths of the window decorations in the succession
646  *  top, right, bottom, left.
647  *  @return an array with border widths (top, right, bottom, left).
648  */
drwBorder(const_winType actual_window)649 rtlArrayType drwBorder (const_winType actual_window)
650 
651   {
652     HWND hWnd;
653     RECT windowRect;
654     RECT clientRect;
655     POINT clientTopLeft;
656     POINT clientBottomRight;
657     rtlArrayType border;
658 
659   /* drwBorder */
660     logFunction(printf("drwBorder(" FMT_U_MEM ")\n",
661                        (memSizeType) actual_window););
662     hWnd = to_hwnd(actual_window);
663     if (is_pixmap(actual_window)) {
664       raise_error(RANGE_ERROR);
665       border = NULL;
666     } else if (unlikely(GetWindowRect(hWnd, &windowRect) == 0 ||
667                         GetClientRect(hWnd, &clientRect) == 0)) {
668       raise_error(FILE_ERROR);
669       border = NULL;
670     } else {
671       clientTopLeft.x = clientRect.left;
672       clientTopLeft.y = clientRect.top;
673       clientBottomRight.x = clientRect.right;
674       clientBottomRight.y = clientRect.bottom;
675       if (unlikely(ClientToScreen(hWnd, &clientTopLeft) == 0 ||
676                    ClientToScreen(hWnd, &clientBottomRight) == 0)) {
677         raise_error(FILE_ERROR);
678         border = NULL;
679       } else {
680         if (unlikely(!ALLOC_RTL_ARRAY(border, 4))) {
681           raise_error(MEMORY_ERROR);
682         } else {
683           border->min_position = 1;
684           border->max_position = 4;
685           border->arr[0].value.intValue = (intType) (clientTopLeft.y - windowRect.top);
686           border->arr[1].value.intValue = (intType) (windowRect.right - clientBottomRight.x);
687           border->arr[2].value.intValue = (intType) (windowRect.bottom - clientBottomRight.y);
688           border->arr[3].value.intValue = (intType) (clientTopLeft.x - windowRect.left);
689         } /* if */
690       } /* if */
691     } /* if */
692     logFunction(printf("drwBorder(" FMT_U_MEM ") -->"
693                        " %s[" FMT_D ", " FMT_D ", " FMT_D ", " FMT_D "]\n",
694                        (memSizeType) actual_window,
695                        border != NULL ? "" : "NULL ",
696                        border != NULL ? border->arr[0].value.intValue : 0,
697                        border != NULL ? border->arr[1].value.intValue : 0,
698                        border != NULL ? border->arr[2].value.intValue : 0,
699                        border != NULL ? border->arr[3].value.intValue : 0););
700     return border;
701   } /* drwBorder */
702 
703 
704 
drwCircle(const_winType actual_window,intType x,intType y,intType radius)705 void drwCircle (const_winType actual_window,
706     intType x, intType y, intType radius)
707 
708   { /* drwCircle */
709     AngleArc(to_hdc(actual_window), castToInt(x), castToInt(y), (unsigned) radius, 0.0, 360.0);
710   } /* drwCircle */
711 
712 
713 
drwPCircle(const_winType actual_window,intType x,intType y,intType radius,intType col)714 void drwPCircle (const_winType actual_window,
715     intType x, intType y, intType radius, intType col)
716 
717   {
718     HPEN old_pen;
719     HPEN current_pen;
720 
721   /* drwPCircle */
722     /* SetDCPenColor(to_hdc(actual_window), (COLORREF) col); */
723     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
724     if (unlikely(current_pen == NULL)) {
725       raise_error(MEMORY_ERROR);
726     } else {
727       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
728       MoveToEx(to_hdc(actual_window), castToInt(x + radius), castToInt(y), NULL);
729       AngleArc(to_hdc(actual_window), castToInt(x), castToInt(y), (unsigned) radius, 0.0, 360.0);
730       SelectObject(to_hdc(actual_window), old_pen);
731       if (to_backup_hdc(actual_window) != 0) {
732         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
733         MoveToEx(to_backup_hdc(actual_window), castToInt(x + radius), castToInt(y), NULL);
734         AngleArc(to_backup_hdc(actual_window), castToInt(x), castToInt(y), (unsigned) radius, 0.0, 360.0);
735         SelectObject(to_backup_hdc(actual_window), old_pen);
736       } /* if */
737       DeleteObject(current_pen);
738     } /* if */
739   } /* drwPCircle */
740 
741 
742 
drwClear(winType actual_window,intType col)743 void drwClear (winType actual_window, intType col)
744 
745   {
746     HPEN old_pen;
747     HPEN current_pen;
748     HBRUSH old_brush;
749     HBRUSH current_brush;
750 
751   /* drwClear */
752     logFunction(printf("drwClear(" FMT_U_MEM ", " F_X(08) ")\n",
753                        (memSizeType) actual_window, col););
754     to_var_clear_col(actual_window) = col;
755     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
756     current_brush = CreateSolidBrush((COLORREF) col);
757     if (unlikely(current_pen == NULL || current_brush == NULL)) {
758       raise_error(MEMORY_ERROR);
759     } else {
760       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
761       old_brush = (HBRUSH) SelectObject(to_hdc(actual_window), current_brush);
762       /* The main window is cleared with the real window size. */
763       Rectangle(to_hdc(actual_window), 0, 0,
764           (int) drwWidth(actual_window), (int) drwHeight(actual_window));
765       SelectObject(to_hdc(actual_window), old_pen);
766       SelectObject(to_hdc(actual_window), old_brush);
767       if (to_backup_hdc(actual_window) != 0) {
768         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
769         old_brush = (HBRUSH) SelectObject(to_backup_hdc(actual_window), current_brush);
770         Rectangle(to_backup_hdc(actual_window), 0, 0,
771             (int) to_backupWidth(actual_window), (int) to_backupHeight(actual_window));
772         SelectObject(to_backup_hdc(actual_window), old_pen);
773         SelectObject(to_backup_hdc(actual_window), old_brush);
774       } /* if */
775       DeleteObject(current_pen);
776       DeleteObject(current_brush);
777     } /* if */
778   } /* drwClear */
779 
780 
781 
782 /**
783  *  Copy a rectangular area from 'src_window' to 'dest_window'.
784  *  Coordinates are measured relative to the top left corner of the
785  *  corresponding window drawing area (inside of the window decorations).
786  *  @param src_window Source window.
787  *  @param dest_window Destination window.
788  *  @param src_x X-position of the top left corner of the source area.
789  *  @param src_y Y-position of the top left corner of the source area.
790  *  @param width Width of the rectangular area.
791  *  @param height Height of the rectangular area.
792  *  @param dest_x X-position of the top left corner of the destination area.
793  *  @param dest_y Y-position of the top left corner of the destination area.
794  */
drwCopyArea(const_winType src_window,const_winType dest_window,intType src_x,intType src_y,intType width,intType height,intType dest_x,intType dest_y)795 void drwCopyArea (const_winType src_window, const_winType dest_window,
796     intType src_x, intType src_y, intType width, intType height,
797     intType dest_x, intType dest_y)
798 
799   { /* drwCopyArea */
800     logFunction(printf("drwCopyArea(" FMT_U_MEM ", " FMT_U_MEM ", "
801                        FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ")\n",
802                        (memSizeType) src_window, (memSizeType) dest_window,
803                        src_x, src_y, width, height, dest_x, dest_y););
804     if (unlikely(!inIntRange(src_x) || !inIntRange(src_y) ||
805                  !inIntRange(width) || !inIntRange(height) ||
806                  !inIntRange(dest_x) || !inIntRange(dest_y) ||
807                  width < 1 || height < 1)) {
808       raise_error(RANGE_ERROR);
809     } else if (to_backup_hdc(src_window) != 0) {
810       BitBlt(to_hdc(dest_window), (int) dest_x, (int) dest_y, (int) width, (int) height,
811           to_backup_hdc(src_window), (int) src_x, (int) src_y, SRCCOPY);
812       if (to_backup_hdc(dest_window) != 0) {
813         BitBlt(to_backup_hdc(dest_window), (int) dest_x, (int) dest_y, (int) width, (int) height,
814             to_backup_hdc(src_window), (int) src_x, (int) src_y, SRCCOPY);
815       } /* if */
816     } else {
817       BitBlt(to_hdc(dest_window), (int) dest_x, (int) dest_y, (int) width, (int) height,
818           to_hdc(src_window), (int) src_x, (int) src_y, SRCCOPY);
819       if (to_backup_hdc(dest_window) != 0) {
820         BitBlt(to_backup_hdc(dest_window), (int) dest_x, (int) dest_y, (int) width, (int) height,
821             to_hdc(src_window), (int) src_x, (int) src_y, SRCCOPY);
822       } /* if */
823     } /* if */
824   } /* drwCopyArea */
825 
826 
827 
drwFCircle(const_winType actual_window,intType x,intType y,intType radius)828 void drwFCircle (const_winType actual_window,
829     intType x, intType y, intType radius)
830 
831   { /* drwFCircle */
832   } /* drwFCircle */
833 
834 
835 
drwPFCircle(const_winType actual_window,intType x,intType y,intType radius,intType col)836 void drwPFCircle (const_winType actual_window,
837     intType x, intType y, intType radius, intType col)
838 
839   {
840     HPEN old_pen;
841     HPEN current_pen;
842     HBRUSH old_brush;
843     HBRUSH current_brush;
844 
845   /* drwPFCircle */
846     /* SetDCPenColor(to_hdc(actual_window), (COLORREF) col); */
847     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
848     current_brush = CreateSolidBrush((COLORREF) col);
849     if (unlikely(current_pen == NULL || current_brush == NULL)) {
850       raise_error(MEMORY_ERROR);
851     } else {
852       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
853       old_brush = (HBRUSH) SelectObject(to_hdc(actual_window), current_brush);
854       Ellipse(to_hdc(actual_window), castToInt(x - radius), castToInt(y - radius),
855           castToInt(x + radius + 1), castToInt(y + radius + 1));
856       SelectObject(to_hdc(actual_window), old_pen);
857       SelectObject(to_hdc(actual_window), old_brush);
858       if (to_backup_hdc(actual_window) != 0) {
859         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
860         old_brush = (HBRUSH) SelectObject(to_backup_hdc(actual_window), current_brush);
861         Ellipse(to_backup_hdc(actual_window), castToInt(x - radius), castToInt(y - radius),
862             castToInt(x + radius + 1), castToInt(y + radius + 1));
863         SelectObject(to_backup_hdc(actual_window), old_pen);
864         SelectObject(to_backup_hdc(actual_window), old_brush);
865       } /* if */
866       DeleteObject(current_pen);
867       DeleteObject(current_brush);
868     } /* if */
869   } /* drwPFCircle */
870 
871 
872 
drwFEllipse(const_winType actual_window,intType x,intType y,intType width,intType height)873 void drwFEllipse (const_winType actual_window,
874     intType x, intType y, intType width, intType height)
875 
876   { /* drwFEllipse */
877   } /* drwFEllipse */
878 
879 
880 
drwPFEllipse(const_winType actual_window,intType x,intType y,intType width,intType height,intType col)881 void drwPFEllipse (const_winType actual_window,
882     intType x, intType y, intType width, intType height, intType col)
883 
884   {
885     HPEN old_pen;
886     HPEN current_pen;
887     HBRUSH old_brush;
888     HBRUSH current_brush;
889 
890   /* drwPFEllipse */
891     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
892     current_brush = CreateSolidBrush((COLORREF) col);
893     if (unlikely(current_pen == NULL || current_brush == NULL)) {
894       raise_error(MEMORY_ERROR);
895     } else {
896       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
897       old_brush = (HBRUSH) SelectObject(to_hdc(actual_window), current_brush);
898       Ellipse(to_hdc(actual_window), castToInt(x), castToInt(y),
899               castToInt(x + width), castToInt(y + height));
900       SelectObject(to_hdc(actual_window), old_pen);
901       SelectObject(to_hdc(actual_window), old_brush);
902       if (to_backup_hdc(actual_window) != 0) {
903         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
904         old_brush = (HBRUSH) SelectObject(to_backup_hdc(actual_window), current_brush);
905         Ellipse(to_backup_hdc(actual_window), castToInt(x), castToInt(y),
906                 castToInt(x + width), castToInt(y + height));
907         SelectObject(to_backup_hdc(actual_window), old_pen);
908         SelectObject(to_backup_hdc(actual_window), old_brush);
909       } /* if */
910       DeleteObject(current_pen);
911       DeleteObject(current_brush);
912     } /* if */
913   } /* drwPFEllipse */
914 
915 
916 
drwEmpty(void)917 winType drwEmpty (void)
918 
919   {
920     HDC screenDC;
921     win_winType emptyWindow;
922 
923   /* drwEmpty */
924     logFunction(printf("drwEmpty()\n"););
925     if (init_called == 0) {
926       drawInit();
927     } /* if */
928     if (unlikely(!ALLOC_RECORD2(emptyWindow, win_winRecord, count.win, count.win_bytes))) {
929       raise_error(MEMORY_ERROR);
930     } else {
931       memset(emptyWindow, 0, sizeof(win_winRecord));
932       emptyWindow->usage_count = 0;  /* Do not use reference counting (will not be freed). */
933       screenDC = GetDC(NULL);
934       emptyWindow->hdc = CreateCompatibleDC(screenDC);
935       emptyWindow->hBitmap = CreateCompatibleBitmap(screenDC, 0, 0);
936       ReleaseDC(NULL, screenDC);
937       emptyWindow->oldBitmap = (HBITMAP) SelectObject(emptyWindow->hdc, emptyWindow->hBitmap);
938       emptyWindow->hasTransparentPixel = FALSE;
939       emptyWindow->transparentPixel = 0;
940       emptyWindow->is_pixmap = TRUE;
941       emptyWindow->width = 0;
942       emptyWindow->height = 0;
943     } /* if */
944     logFunction(printf("drwEmpty --> " FMT_U_MEM " (usage=" FMT_U ")\n",
945                        (memSizeType) emptyWindow,
946                        emptyWindow != NULL ? emptyWindow->usage_count : (uintType) 0););
947     return (winType) emptyWindow;
948   } /* drwEmpty */
949 
950 
951 
drwFree(winType old_window)952 void drwFree (winType old_window)
953 
954   { /* drwFree */
955     logFunction(printf("drwFree(" FMT_U_MEM ") (usage=" FMT_U ")\n",
956                        (memSizeType) old_window,
957                        old_window != NULL ? old_window->usage_count : (uintType) 0););
958     if (is_pixmap(old_window)) {
959       SelectObject(to_hdc(old_window), to_oldBitmap(old_window));
960       DeleteObject(to_hBitmap(old_window));
961       DeleteDC(to_hdc(old_window));
962     } else {
963       DeleteObject(to_backup(old_window));
964       DeleteDC(to_backup_hdc(old_window));
965       DeleteDC(to_hdc(old_window));
966       DestroyWindow(to_hwnd(old_window));
967       remove_window(to_hwnd(old_window));
968     } /* if */
969     FREE_RECORD2(old_window, win_winRecord, count.win, count.win_bytes);
970   } /* drwFree */
971 
972 
973 
974 /**
975  *  Create a new pixmap with the given 'width' and 'height'.
976  *  A rectangle with the upper left corner at (left, upper) and the given
977  *  'width' and 'height' is copied from 'source_window' to the new pixmap.
978  *  @exception RANGE_ERROR If 'height' or 'width' are negative.
979  *  @return the new pixmap.
980  */
drwGet(const_winType source_window,intType left,intType upper,intType width,intType height)981 winType drwGet (const_winType source_window, intType left, intType upper,
982     intType width, intType height)
983 
984   {
985     win_winType pixmap;
986 
987   /* drwGet */
988     logFunction(printf("drwGet(" FMT_U_MEM ", " FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ")\n",
989                        (memSizeType) source_window, left, upper, width, height););
990     if (unlikely(!inIntRange(left) || !inIntRange(upper) ||
991                  !inIntRange(width) || !inIntRange(height) ||
992                  width < 1 || height < 1)) {
993       raise_error(RANGE_ERROR);
994       pixmap = NULL;
995     } else if (unlikely(!ALLOC_RECORD2(pixmap, win_winRecord, count.win, count.win_bytes))) {
996       raise_error(MEMORY_ERROR);
997     } else {
998       memset(pixmap, 0, sizeof(win_winRecord));
999       pixmap->usage_count = 1;
1000       pixmap->hdc = CreateCompatibleDC(to_hdc(source_window));
1001       pixmap->hBitmap = CreateCompatibleBitmap(to_hdc(source_window), (int) width, (int) height);
1002       if (unlikely(pixmap->hBitmap == NULL)) {
1003         free(pixmap);
1004         pixmap = NULL;
1005         raise_error(MEMORY_ERROR);
1006       } else {
1007         pixmap->oldBitmap = (HBITMAP) SelectObject(pixmap->hdc, pixmap->hBitmap);
1008         pixmap->hasTransparentPixel = FALSE;
1009         pixmap->transparentPixel = 0;
1010         pixmap->is_pixmap = TRUE;
1011         pixmap->width = (unsigned int) width;
1012         pixmap->height = (unsigned int) height;
1013         if (to_backup_hdc(source_window) != 0) {
1014           BitBlt(pixmap->hdc, 0, 0, (int) width, (int) height,
1015               to_backup_hdc(source_window), (int) left, (int) upper, SRCCOPY);
1016         } else {
1017           BitBlt(pixmap->hdc, 0, 0, (int) width, (int) height,
1018               to_hdc(source_window), (int) left, (int) upper, SRCCOPY);
1019         } /* if */
1020       } /* if */
1021     } /* if */
1022     logFunction(printf("drwGet --> " FMT_U_MEM " (usage=" FMT_U ")\n",
1023                        (memSizeType) pixmap,
1024                        pixmap != NULL ? pixmap->usage_count : (uintType) 0););
1025     return (winType) pixmap;
1026   } /* drwGet */
1027 
1028 
1029 
1030 /**
1031  *  Capture a rectangular area from the screen.
1032  *  The function takes a screenshot of the rectangular area.
1033  *  The 'left' and 'upper' coordinates are measured relative to
1034  *  the top left corner of the screen.
1035  *  @param left X-position of the upper left corner of the capture area.
1036  *  @param upper Y-position of the upper left corner of the capture area.
1037  *  @param width Width of the capture area.
1038  *  @param height Height of the capture area.
1039  *  @return the content of the rectangular screen area as pixmap.
1040  *  @exception RANGE_ERROR If 'height' or 'width' are negative.
1041  */
drwCapture(intType left,intType upper,intType width,intType height)1042 winType drwCapture (intType left, intType upper,
1043     intType width, intType height)
1044 
1045   {
1046     HDC screenDC;
1047     int horizRes;
1048     int vertRes;
1049     int desktopHorizRes;
1050     int desktopVertRes;
1051     win_winType pixmap;
1052 
1053   /* drwCapture */
1054     logFunction(printf("drwCapture(" FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ")\n",
1055                        left, upper, width, height););
1056     if (unlikely(!inIntRange(left) || !inIntRange(upper) ||
1057                  !inIntRange(width) || !inIntRange(height) ||
1058                  width < 1 || height < 1)) {
1059       raise_error(RANGE_ERROR);
1060       pixmap = NULL;
1061     } else if (unlikely(!ALLOC_RECORD2(pixmap, win_winRecord, count.win, count.win_bytes))) {
1062       raise_error(MEMORY_ERROR);
1063     } else {
1064       memset(pixmap, 0, sizeof(win_winRecord));
1065       pixmap->usage_count = 1;
1066       screenDC = GetDC(NULL);
1067       pixmap->hdc = CreateCompatibleDC(screenDC);
1068       pixmap->hBitmap = CreateCompatibleBitmap(screenDC, (int) width, (int) height);
1069       if (unlikely(pixmap->hBitmap == NULL)) {
1070         free(pixmap);
1071         pixmap = NULL;
1072         ReleaseDC(NULL, screenDC);
1073         raise_error(MEMORY_ERROR);
1074       } else {
1075         pixmap->oldBitmap = (HBITMAP) SelectObject(pixmap->hdc, pixmap->hBitmap);
1076         pixmap->hasTransparentPixel = FALSE;
1077         pixmap->transparentPixel = 0;
1078         pixmap->is_pixmap = TRUE;
1079         pixmap->width = (unsigned int) width;
1080         pixmap->height = (unsigned int) height;
1081         horizRes = GetDeviceCaps(screenDC, HORZRES);
1082         vertRes = GetDeviceCaps(screenDC, VERTRES);
1083         desktopHorizRes = GetDeviceCaps(screenDC, DESKTOPHORZRES);
1084         desktopVertRes = GetDeviceCaps(screenDC, DESKTOPVERTRES);
1085         if (horizRes == desktopHorizRes && vertRes == desktopVertRes) {
1086           BitBlt(pixmap->hdc, 0, 0, (int) width, (int) height,
1087                  screenDC, (int) left, (int) upper, SRCCOPY);
1088         } else {
1089           SetStretchBltMode(pixmap->hdc, COLORONCOLOR);
1090           StretchBlt(pixmap->hdc, 0, 0, (int) width, (int) height, screenDC,
1091                      (int) (left * desktopHorizRes / horizRes),
1092                      (int) (upper * desktopVertRes / vertRes),
1093                      (int) (width * desktopHorizRes / horizRes),
1094                      (int) (height * desktopVertRes / vertRes), SRCCOPY);
1095         } /* if */
1096         ReleaseDC(NULL, screenDC);
1097       } /* if */
1098     } /* if */
1099     logFunction(printf("drwCapture --> " FMT_U_MEM " (usage=" FMT_U ")\n",
1100                        (memSizeType) pixmap,
1101                        pixmap != NULL ? pixmap->usage_count : (uintType) 0););
1102     return (winType) pixmap;
1103   } /* drwCapture */
1104 
1105 
1106 
drwGetImage(const_winType source_window)1107 bstriType drwGetImage (const_winType source_window)
1108 
1109   {
1110     unsigned int xPos;
1111     unsigned int yPos;
1112     memSizeType result_size;
1113     uint32Type *image_data;
1114     bstriType result;
1115 
1116   /* drwGetImage */
1117     logFunction(printf("drwGetImage(" FMT_U_MEM ")\n", (memSizeType) source_window););
1118     result_size = to_width(source_window) * to_height(source_window) * sizeof(uint32Type);
1119     if (unlikely(!ALLOC_BSTRI_SIZE_OK(result, result_size))) {
1120       raise_error(MEMORY_ERROR);
1121     } else {
1122       result->size = result_size;
1123       image_data = (uint32Type *) result->mem;
1124       for (yPos = 0; yPos < to_height(source_window); yPos++) {
1125         for (xPos = 0; xPos < to_width(source_window); xPos++) {
1126           image_data[yPos * to_width(source_window) + xPos] =
1127               (uint32Type) GetPixel(to_hdc(source_window), (int) xPos, (int) yPos);
1128         } /* for */
1129       } /* for */
1130     } /* if */
1131     return result;
1132   } /* drwGetImage */
1133 
1134 
1135 
drwGetPixel(const_winType source_window,intType x,intType y)1136 intType drwGetPixel (const_winType source_window, intType x, intType y)
1137 
1138   { /* drwGetPixel */
1139     return (intType) GetPixel(to_hdc(source_window), castToInt(x), castToInt(y));
1140   } /* drwGetPixel */
1141 
1142 
1143 
1144 /**
1145  *  Determine the height of the window drawing area in pixels.
1146  *  This excludes window decorations at top and bottom. Add top and bottom
1147  *  border widths to get the height inclusive window decorations.
1148  */
drwHeight(const_winType actual_window)1149 intType drwHeight (const_winType actual_window)
1150 
1151   {
1152     RECT rect;
1153     intType height;
1154 
1155   /* drwHeight */
1156     logFunction(printf("drwHeight(" FMT_U_MEM "), usage=" FMT_U "\n",
1157                        (memSizeType) actual_window,
1158                        actual_window != 0 ? actual_window->usage_count: 0););
1159     if (is_pixmap(actual_window) ||
1160         GetClientRect(to_hwnd(actual_window), &rect) == 0) {
1161       height = to_height(actual_window);
1162     } else {
1163       height = (intType) ((unsigned int) (rect.bottom - rect.top));
1164     } /* if */
1165     logFunction(printf("drwHeight(" FMT_U_MEM ") --> " FMT_D "\n",
1166                        (memSizeType) actual_window, height););
1167     return height;
1168   } /* drwHeight */
1169 
1170 
1171 
drwImage(int32Type * image_data,memSizeType width,memSizeType height)1172 winType drwImage (int32Type *image_data, memSizeType width, memSizeType height)
1173 
1174   {
1175     memSizeType pos;
1176     int32Type color;
1177     HDC screenDC;
1178     win_winType pixmap;
1179 
1180   /* drwImage */
1181     logFunction(printf("drwImage(" FMT_U_MEM ", " FMT_U_MEM ")\n", width, height););
1182     if (unlikely(width < 1 || width > INTTYPE_MAX ||
1183                  height < 1 || height > INTTYPE_MAX)) {
1184       raise_error(RANGE_ERROR);
1185       pixmap = NULL;
1186     } else {
1187       if (init_called == 0) {
1188         drawInit();
1189       } /* if */
1190       if (unlikely(!ALLOC_RECORD2(pixmap, win_winRecord, count.win, count.win_bytes))) {
1191         raise_error(MEMORY_ERROR);
1192       } else {
1193         memset(pixmap, 0, sizeof(win_winRecord));
1194         pixmap->usage_count = 1;
1195         pos = height * width;
1196         do {
1197           pos--;
1198           color = image_data[pos];
1199           image_data[pos] = (GetRValue(color) << 16) | (GetGValue(color) << 8) | GetBValue(color);
1200         } while (pos != 0);
1201         screenDC = GetDC(NULL);
1202         pixmap->hdc = CreateCompatibleDC(screenDC);
1203         pixmap->hBitmap = CreateBitmap((int) width, (int) height, 1, 32, image_data);
1204         ReleaseDC(NULL, screenDC);
1205         pixmap->oldBitmap = (HBITMAP) SelectObject(pixmap->hdc, pixmap->hBitmap);
1206         pixmap->hasTransparentPixel = FALSE;
1207         pixmap->transparentPixel = 0;
1208         pixmap->is_pixmap = TRUE;
1209         pixmap->width = (unsigned int) width;
1210         pixmap->height = (unsigned int) height;
1211       } /* if */
1212     } /* if */
1213     logFunction(printf("drwImage --> " FMT_U_MEM " (usage=" FMT_U ")\n",
1214                        (memSizeType) pixmap,
1215                        pixmap != NULL ? pixmap->usage_count : (uintType) 0););
1216     return (winType) pixmap;
1217   } /* drwImage */
1218 
1219 
1220 
drwLine(const_winType actual_window,intType x1,intType y1,intType x2,intType y2)1221 void drwLine (const_winType actual_window,
1222     intType x1, intType y1, intType x2, intType y2)
1223 
1224   { /* drwLine */
1225     MoveToEx(to_hdc(actual_window), castToInt(x1), castToInt(y1), NULL);
1226     LineTo(to_hdc(actual_window), castToInt(x2), castToInt(y2));
1227     if (to_backup_hdc(actual_window) != 0) {
1228       MoveToEx(to_backup_hdc(actual_window), castToInt(x1), castToInt(y1), NULL);
1229       LineTo(to_backup_hdc(actual_window), castToInt(x2), castToInt(y2));
1230     } /* if */
1231   } /* drwLine */
1232 
1233 
1234 
drwPLine(const_winType actual_window,intType x1,intType y1,intType x2,intType y2,intType col)1235 void drwPLine (const_winType actual_window,
1236     intType x1, intType y1, intType x2, intType y2, intType col)
1237 
1238   {
1239     HPEN old_pen;
1240     HPEN current_pen;
1241 
1242   /* drwPLine */
1243     logFunction(printf("drwPLine(" FMT_U_MEM ", " FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ", " F_X(08) ")\n",
1244                        (memSizeType) actual_window, x1, y1, x2, y2, col););
1245     /* SetDCPenColor(to_hdc(actual_window), (COLORREF) col); */
1246     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
1247     if (unlikely(current_pen == NULL)) {
1248       raise_error(MEMORY_ERROR);
1249     } else {
1250       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
1251       MoveToEx(to_hdc(actual_window), castToInt(x1), castToInt(y1), NULL);
1252       LineTo(to_hdc(actual_window), castToInt(x2), castToInt(y2));
1253       SetPixel(to_hdc(actual_window), castToInt(x2), castToInt(y2), (COLORREF) col);
1254       SelectObject(to_hdc(actual_window), old_pen);
1255       if (to_backup_hdc(actual_window) != 0) {
1256         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
1257         MoveToEx(to_backup_hdc(actual_window), castToInt(x1), castToInt(y1), NULL);
1258         LineTo(to_backup_hdc(actual_window), castToInt(x2), castToInt(y2));
1259         SetPixel(to_backup_hdc(actual_window), castToInt(x2), castToInt(y2), (COLORREF) col);
1260         SelectObject(to_backup_hdc(actual_window), old_pen);
1261       } /* if */
1262       DeleteObject(current_pen);
1263     } /* if */
1264   } /* drwPLine */
1265 
1266 
1267 
drwNewPixmap(intType width,intType height)1268 winType drwNewPixmap (intType width, intType height)
1269 
1270   {
1271     HDC screenDC;
1272     win_winType pixmap;
1273 
1274   /* drwNewPixmap */
1275     logFunction(printf("drwNewPixmap(" FMT_D ", " FMT_D ")\n", width, height););
1276     if (unlikely(!inIntRange(width) || !inIntRange(height) ||
1277                  width < 1 || height < 1)) {
1278       raise_error(RANGE_ERROR);
1279       pixmap = NULL;
1280     } else {
1281       if (init_called == 0) {
1282         drawInit();
1283       } /* if */
1284       if (unlikely(!ALLOC_RECORD2(pixmap, win_winRecord, count.win, count.win_bytes))) {
1285         raise_error(MEMORY_ERROR);
1286       } else {
1287         memset(pixmap, 0, sizeof(win_winRecord));
1288         pixmap->usage_count = 1;
1289         screenDC = GetDC(NULL);
1290         pixmap->hdc = CreateCompatibleDC(screenDC);
1291         pixmap->hBitmap = CreateCompatibleBitmap(screenDC, (int) width, (int) height);
1292         ReleaseDC(NULL, screenDC);
1293         pixmap->oldBitmap = (HBITMAP) SelectObject(pixmap->hdc, pixmap->hBitmap);
1294         pixmap->hasTransparentPixel = FALSE;
1295         pixmap->transparentPixel = 0;
1296         pixmap->is_pixmap = TRUE;
1297         pixmap->width = (unsigned int) width;
1298         pixmap->height = (unsigned int) height;
1299       } /* if */
1300     } /* if */
1301     logFunction(printf("drwNewPixmap --> " FMT_U_MEM " (usage=" FMT_U ")\n",
1302                        (memSizeType) pixmap,
1303                        pixmap != NULL ? pixmap->usage_count : (uintType) 0););
1304     return (winType) pixmap;
1305   } /* drwNewPixmap */
1306 
1307 
1308 
drwNewBitmap(const_winType actual_window,intType width,intType height)1309 winType drwNewBitmap (const_winType actual_window, intType width, intType height)
1310 
1311   {
1312     win_winType result;
1313 
1314   /* drwNewBitmap */
1315     logFunction(printf("drwNewBitmap(" FMT_D ", " FMT_D ")\n", width, height););
1316     result = NULL;
1317     logFunction(printf("drwNewBitmap --> " FMT_U_MEM " (usage=" FMT_U ")\n",
1318                        (memSizeType) result,
1319                        result != NULL ? result->usage_count : (uintType) 0););
1320     return (winType) result;
1321   } /* drwNewBitmap */
1322 
1323 
1324 
privateConsole(void)1325 static boolType privateConsole (void)
1326 
1327   {
1328     HWND consoleWnd;
1329     DWORD dwProcessId;
1330     CONSOLE_SCREEN_BUFFER_INFO conBufInfo;
1331     boolType private;
1332 
1333   /* privateConsole */
1334     logFunction(printf("privateConsole\n"););
1335     if (pGetConsoleWindow != NULL) {
1336       consoleWnd = pGetConsoleWindow();
1337       GetWindowThreadProcessId(consoleWnd, &dwProcessId);
1338       private = GetCurrentProcessId() == dwProcessId;
1339     } else if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &conBufInfo)) {
1340       private = FALSE;
1341     } else {
1342       /* If the cursor position is (0,0) the console is assumed to be private. */
1343       private = conBufInfo.dwCursorPosition.X == 0 && conBufInfo.dwCursorPosition.Y == 0;
1344     } /* if */
1345     logFunction(printf("privateConsole --> %d\n", private););
1346     return private;
1347   } /* privateConsole */
1348 
1349 
1350 
drwOpen(intType xPos,intType yPos,intType width,intType height,const const_striType windowName)1351 winType drwOpen (intType xPos, intType yPos,
1352     intType width, intType height, const const_striType windowName)
1353 
1354   {
1355     int bruttoWidthDelta;
1356     int bruttoHeightDelta;
1357     os_striType winName;
1358     HFONT std_font;
1359     errInfoType err_info = OKAY_NO_ERROR;
1360     win_winType result = NULL;
1361 
1362   /* drwOpen */
1363     logFunction(printf("drwOpen(" FMT_D ", " FMT_D ", " FMT_D ", " FMT_D
1364                        ", \"%s\")\n", xPos, yPos, width, height,
1365                        striAsUnquotedCStri(windowName)););
1366     bruttoWidthDelta = 2 * GetSystemMetrics(SM_CXSIZEFRAME);
1367     bruttoHeightDelta = 2 * GetSystemMetrics(SM_CYSIZEFRAME) +
1368         GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1369     if (unlikely(!inIntRange(xPos) || !inIntRange(yPos) ||
1370                  bruttoWidthDelta < 0 || bruttoHeightDelta < 0 ||
1371                  width < 1 || width > INT_MAX - bruttoWidthDelta ||
1372                  height < 1 || height > INT_MAX - bruttoHeightDelta)) {
1373       raise_error(RANGE_ERROR);
1374     } else {
1375       if (init_called == 0) {
1376         drawInit();
1377       } /* if */
1378       if (init_called != 0) {
1379         winName = stri_to_os_stri(windowName, &err_info);
1380         if (unlikely(winName == NULL)) {
1381           raise_error(err_info);
1382         } else {
1383           if (privateConsole()) {
1384             /* printf("private_session\n"); */
1385             if (pGetConsoleWindow != NULL) {
1386               ShowWindow(pGetConsoleWindow(), SW_HIDE);
1387             } else {
1388               FreeConsole();
1389             } /* if */
1390           } /* if */
1391           if (ALLOC_RECORD2(result, win_winRecord, count.win, count.win_bytes)) {
1392             memset(result, 0, sizeof(win_winRecord));
1393             result->usage_count = 1;
1394 #ifdef OUT_OF_ORDER
1395             printf("SM_CXBORDER=%d\n",    GetSystemMetrics(SM_CXBORDER));
1396             printf("SM_CYBORDER=%d\n",    GetSystemMetrics(SM_CYBORDER));
1397             printf("SM_CXSIZE=%d\n",      GetSystemMetrics(SM_CXSIZE));
1398             printf("SM_CYSIZE=%d\n",      GetSystemMetrics(SM_CYSIZE));
1399             printf("SM_CXSIZEFRAME=%d\n", GetSystemMetrics(SM_CXSIZEFRAME));
1400             printf("SM_CYSIZEFRAME=%d\n", GetSystemMetrics(SM_CYSIZEFRAME));
1401             printf("SM_CXEDGE=%d\n",      GetSystemMetrics(SM_CXEDGE));
1402             printf("SM_CYEDGE=%d\n",      GetSystemMetrics(SM_CYEDGE));
1403             printf("width=%d\n",          width + 2 * GetSystemMetrics(SM_CXSIZEFRAME));
1404             printf("height=%d\n",         height + 2 * GetSystemMetrics(SM_CYSIZEFRAME) +
1405                 GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER));
1406 #endif
1407             result->bruttoWidthDelta = (unsigned int) bruttoWidthDelta;
1408             result->bruttoHeightDelta = (unsigned int) bruttoHeightDelta;
1409             result->hWnd = CreateWindowW(windowClassW, winName,
1410                 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
1411                 (int) xPos, (int) yPos,
1412                 (int) width + bruttoWidthDelta,
1413                 (int) height + bruttoHeightDelta,
1414                 (HWND) NULL, (HMENU) NULL, NULL, NULL);
1415             enter_window((winType) result, result->hWnd);
1416             /* printf("hWnd=%lu\n", result->hWnd); */
1417             if (result->hWnd != NULL) {
1418               result->hdc = GetDC(result->hWnd);
1419               /* printf("hdc=%lu\n", result->hdc); */
1420               result->hasTransparentPixel = FALSE;
1421               result->transparentPixel = 0;
1422               result->is_pixmap = FALSE;
1423               result->width = (unsigned int) width;
1424               result->height = (unsigned int) height;
1425               result->backupWidth = (unsigned int) width;
1426               result->backupHeight = (unsigned int) height;
1427               result->minimized = FALSE;
1428               result->clear_col = (intType) RGB(0, 0, 0); /* black */
1429               result->cursorVisible = TRUE;
1430               result->backup_hdc = CreateCompatibleDC(result->hdc);
1431               result->backup = CreateCompatibleBitmap(result->hdc, (int) width, (int) height);
1432               SelectObject(result->backup_hdc, result->backup);
1433               std_font = CreateFont(16, 6, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
1434                   ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
1435                   DEFAULT_QUALITY, FIXED_PITCH | FF_SWISS, NULL);
1436               SelectObject(result->hdc, std_font);
1437               SelectObject(result->backup_hdc, std_font);
1438               ShowWindow(result->hWnd, SW_SHOWDEFAULT);
1439               UpdateWindow(result->hWnd);
1440             } /* if */
1441           } /* if */
1442           os_stri_free(winName);
1443         } /* if */
1444       } /* if */
1445     } /* if */
1446     logFunction(printf("drwOpen --> " FMT_U_MEM " (usage=" FMT_U ")\n",
1447                        (memSizeType) result,
1448                        result != NULL ? result->usage_count : (uintType) 0););
1449     return (winType) result;
1450   } /* drwOpen */
1451 
1452 
1453 
1454 /**
1455  *  Create a sub window inside of 'parent_window'.
1456  *  The new sub window has no window decorations and is not managed by
1457  *  the window manager. If the empty window is used as 'parent_window'
1458  *  an unmanaged top level window without window decorations is generated.
1459  *  The coordinates 'xPos' and 'yPos' are measured relative to the top
1460  *  left corner of the 'parent_window' drawing area (inside of the window
1461  *  decorations). If the empty window is used as 'parent_window' the
1462  *  coordinates 'xPos' and 'yPos' are measured relative to the top left
1463  *  corner of the screen.
1464  *  @param parent-window Parent window (can be the empty window).
1465  *  @param xPos X-position of the left corner of the new window.
1466  *  @param yPos Y-position of the left corner of the new window.
1467  *  @param width Width of the new window.
1468  *  @param height Height of the new window.
1469  *  @return the new generated window.
1470  */
drwOpenSubWindow(const_winType parent_window,intType xPos,intType yPos,intType width,intType height)1471 winType drwOpenSubWindow (const_winType parent_window, intType xPos, intType yPos,
1472     intType width, intType height)
1473 
1474   {
1475     HFONT std_font;
1476     win_winType result;
1477 
1478   /* drwOpenSubWindow */
1479     logFunction(printf("drwOpenSubWindow(" FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ")\n",
1480                        xPos, yPos, width, height););
1481     result = NULL;
1482     if (unlikely(!inIntRange(xPos) || !inIntRange(yPos) ||
1483                  !inIntRange(width) || !inIntRange(height) ||
1484                  width < 1 || height < 1)) {
1485       raise_error(RANGE_ERROR);
1486     } else {
1487       if (init_called == 0) {
1488         drawInit();
1489       } /* if */
1490       if (init_called != 0) {
1491         if (ALLOC_RECORD2(result, win_winRecord, count.win, count.win_bytes)) {
1492           memset(result, 0, sizeof(win_winRecord));
1493           result->usage_count = 1;
1494 #ifdef OUT_OF_ORDER
1495           printf("SM_CXBORDER=%d\n",    GetSystemMetrics(SM_CXBORDER));
1496           printf("SM_CYBORDER=%d\n",    GetSystemMetrics(SM_CYBORDER));
1497           printf("SM_CXSIZE=%d\n",      GetSystemMetrics(SM_CXSIZE));
1498           printf("SM_CYSIZE=%d\n",      GetSystemMetrics(SM_CYSIZE));
1499           printf("SM_CXSIZEFRAME=%d\n", GetSystemMetrics(SM_CXSIZEFRAME));
1500           printf("SM_CYSIZEFRAME=%d\n", GetSystemMetrics(SM_CYSIZEFRAME));
1501           printf("SM_CXEDGE=%d\n",      GetSystemMetrics(SM_CXEDGE));
1502           printf("SM_CYEDGE=%d\n",      GetSystemMetrics(SM_CYEDGE));
1503           printf("width=%d\n",          width + 2 * GetSystemMetrics(SM_CXSIZEFRAME));
1504           printf("height=%d\n",         height + 2 * GetSystemMetrics(SM_CYSIZEFRAME) +
1505               GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER));
1506           printf("WS_OVERLAPPEDWINDOW = %lx\n", WS_OVERLAPPEDWINDOW);
1507           printf("WS_BORDER           = %lx\n", WS_BORDER);
1508           printf("WS_THICKFRAME       = %lx\n", WS_THICKFRAME);
1509           printf("WS_DLGFRAME         = %lx\n", WS_DLGFRAME);
1510           printf("WS_CAPTION          = %lx\n", WS_CAPTION);
1511           printf("WS_CHILD            = %lx\n", WS_CHILD);
1512 #endif
1513 
1514           result->bruttoWidthDelta = 0;
1515           result->bruttoHeightDelta = 0;
1516           if (to_width(parent_window) == 0 && to_height(parent_window) == 0) {
1517             result->hWnd = CreateWindowEx(WS_EX_NOACTIVATE, windowClass, "",
1518                 WS_POPUP,
1519                 (int) xPos, (int) yPos, (int) width, (int) height,
1520                 (HWND) NULL, (HMENU) NULL, NULL, NULL);
1521           } else {
1522             result->hWnd = CreateWindow(windowClass, "",
1523                 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
1524                 (int) xPos, (int) yPos, (int) width, (int) height,
1525                 to_hwnd(parent_window), (HMENU) NULL, NULL, NULL);
1526           } /* if */
1527           enter_window((winType) result, result->hWnd);
1528           /* printf("hWnd=%lu\n", result->hWnd); */
1529           if (result->hWnd != NULL) {
1530             SetWindowLong(result->hWnd , GWL_STYLE, GetWindowLong(result->hWnd , GWL_STYLE) &~ WS_CAPTION);
1531             SetWindowPos(result->hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
1532             result->hdc = GetDC(result->hWnd);
1533             /* printf("hdc=%lu\n", result->hdc); */
1534             result->hasTransparentPixel = FALSE;
1535             result->transparentPixel = 0;
1536             result->is_pixmap = FALSE;
1537             result->width = (unsigned int) width;
1538             result->height = (unsigned int) height;
1539             result->backupWidth = (unsigned int) width;
1540             result->backupHeight = (unsigned int) height;
1541             result->minimized = FALSE;
1542             result->clear_col = (intType) RGB(0, 0, 0); /* black */
1543             result->cursorVisible = TRUE;
1544             result->backup_hdc = CreateCompatibleDC(result->hdc);
1545             result->backup = CreateCompatibleBitmap(result->hdc, (int) width, (int) height);
1546             SelectObject(result->backup_hdc, result->backup);
1547             std_font = CreateFont(16, 6, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
1548                 ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
1549                 DEFAULT_QUALITY, FIXED_PITCH | FF_SWISS, NULL);
1550             SelectObject(result->hdc, std_font);
1551             SelectObject(result->backup_hdc, std_font);
1552             ShowWindow(result->hWnd, SW_SHOW /*SW_SHOWDEFAULT*/);
1553             UpdateWindow(result->hWnd);
1554           } /* if */
1555         } /* if */
1556       } /* if */
1557     } /* if */
1558     logFunction(printf("drwOpenSubWindow --> " FMT_U_MEM " (usage=" FMT_U ")\n",
1559                        (memSizeType) result,
1560                        result != NULL ? result->usage_count : (uintType) 0););
1561     return (winType) result;
1562   } /* drwOpenSubWindow */
1563 
1564 
1565 
drwSetCloseAction(winType actual_window,intType closeAction)1566 void drwSetCloseAction (winType actual_window, intType closeAction)
1567 
1568   { /* drwSetCloseAction */
1569     if (closeAction < 0 || closeAction > 2) {
1570       raise_error(RANGE_ERROR);
1571     } else {
1572       to_var_close_action(actual_window) = (int) closeAction;
1573     } /* if */
1574   } /* drwSetCloseAction */
1575 
1576 
1577 
1578 /**
1579  *  Set the visibility of the mouse cursor in 'aWindow'.
1580  *  @param aWindow Window for which the mouse cursor visibility is set.
1581  *  @param visible TRUE, if the mouse cursor should be visible in 'aWindow', or
1582  *                 FALSE, if the mouse curser should be invisible in 'aWindow'.
1583  */
drwSetCursorVisible(winType aWindow,boolType visible)1584 void drwSetCursorVisible (winType aWindow, boolType visible)
1585 
1586   {
1587     POINT point;
1588 
1589   /* drwSetCursorVisible */
1590     logFunction(printf("drwSetCursorVisible(" FMT_U_MEM ", %d)\n"););
1591     to_var_cursorVisible(aWindow) = visible;
1592     if (GetCursorPos(&point) != 0) {
1593       SetCursorPos(point.x, point.y);
1594     } /* if */
1595   } /* drwSetCursorVisible */
1596 
1597 
1598 
drwPoint(const_winType actual_window,intType x,intType y)1599 void drwPoint (const_winType actual_window, intType x, intType y)
1600 
1601   { /* drwPoint */
1602     MoveToEx(to_hdc(actual_window), castToInt(x), castToInt(y), NULL);
1603     LineTo(to_hdc(actual_window), castToInt(x + 1), castToInt(y + 1));
1604     if (to_backup_hdc(actual_window) != 0) {
1605       MoveToEx(to_backup_hdc(actual_window), castToInt(x), castToInt(y), NULL);
1606       LineTo(to_backup_hdc(actual_window), castToInt(x + 1), castToInt(y + 1));
1607     } /* if */
1608   } /* drwPoint */
1609 
1610 
1611 
drwPPoint(const_winType actual_window,intType x,intType y,intType col)1612 void drwPPoint (const_winType actual_window, intType x, intType y, intType col)
1613 
1614   { /* drwPPoint */
1615     logFunction(printf("drwPPoint(" FMT_U_MEM ", " FMT_D ", " FMT_D ", " F_X(08) ")\n",
1616                        (memSizeType) actual_window, x, y, col););
1617     SetPixel(to_hdc(actual_window), castToInt(x), castToInt(y), (COLORREF) col);
1618     if (to_backup_hdc(actual_window) != 0) {
1619       SetPixel(to_backup_hdc(actual_window), castToInt(x), castToInt(y), (COLORREF) col);
1620     } /* if */
1621   } /* drwPPoint */
1622 
1623 
1624 
drwConvPointList(const const_bstriType pointList)1625 rtlArrayType drwConvPointList (const const_bstriType pointList)
1626 
1627   {
1628     memSizeType len;
1629     POINT *points;
1630     memSizeType pos;
1631     rtlArrayType xyArray;
1632 
1633   /* drwConvPointList */
1634     len = pointList->size / sizeof(POINT);
1635     if (unlikely(!ALLOC_RTL_ARRAY(xyArray, len << 1))) {
1636       raise_error(MEMORY_ERROR);
1637     } else {
1638       xyArray->min_position = 1;
1639       xyArray->max_position = (intType) (len << 1);
1640       points = (POINT *) pointList->mem;
1641       for (pos = 0; pos < len; pos ++) {
1642         xyArray->arr[ pos << 1     ].value.intValue = (intType) points[pos].x;
1643         xyArray->arr[(pos << 1) + 1].value.intValue = (intType) points[pos].y;
1644       } /* for */
1645     } /* if */
1646     return xyArray;
1647   } /* drwConvPointList */
1648 
1649 
1650 
drwGenPointList(const const_rtlArrayType xyArray)1651 bstriType drwGenPointList (const const_rtlArrayType xyArray)
1652 
1653   {
1654     memSizeType num_elements;
1655     memSizeType len;
1656     POINT *points;
1657     memSizeType pos;
1658     bstriType result;
1659 
1660   /* drwGenPointList */
1661     logFunction(printf("drwGenPointList(" FMT_D " .. " FMT_D ")\n",
1662                        xyArray->min_position, xyArray->max_position););
1663     num_elements = arraySize(xyArray);
1664     if (unlikely(num_elements & 1)) {
1665       raise_error(RANGE_ERROR);
1666       result = NULL;
1667     } else {
1668       len = num_elements >> 1;
1669       if (unlikely(len > MAX_BSTRI_LEN / sizeof(POINT) || len > MAX_MEM_INDEX)) {
1670         raise_error(MEMORY_ERROR);
1671         result = NULL;
1672       } else {
1673         if (unlikely(!ALLOC_BSTRI_SIZE_OK(result, len * sizeof(POINT)))) {
1674           raise_error(MEMORY_ERROR);
1675         } else {
1676           result->size = len * sizeof(POINT);
1677           if (len > 0) {
1678             points = (POINT *) result->mem;
1679             for (pos = 0; pos < len; pos ++) {
1680               points[pos].x = castToLong(xyArray->arr[ pos << 1     ].value.intValue);
1681               points[pos].y = castToLong(xyArray->arr[(pos << 1) + 1].value.intValue);
1682             } /* for */
1683           } /* if */
1684         } /* if */
1685       } /* if */
1686     } /* if */
1687     return result;
1688   } /* drwGenPointList */
1689 
1690 
1691 
drwLngPointList(bstriType point_list)1692 intType drwLngPointList (bstriType point_list)
1693 
1694   { /* drwLngPointList */
1695     return (intType) (point_list->size / sizeof(POINT));
1696   } /* drwLngPointList */
1697 
1698 
1699 
drwPolyLine(const_winType actual_window,intType x,intType y,bstriType point_list,intType col)1700 void drwPolyLine (const_winType actual_window,
1701     intType x, intType y, bstriType point_list, intType col)
1702 
1703   {
1704     POINT *points;
1705     memSizeType numPoints;
1706     memSizeType pos;
1707     HPEN old_pen;
1708     HPEN current_pen;
1709 
1710   /* drwPolyLine */
1711     points = (POINT *) point_list->mem;
1712     numPoints = point_list->size / sizeof(POINT);
1713     if (numPoints >= 2) {
1714       current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
1715       if (unlikely(current_pen == NULL)) {
1716         raise_error(MEMORY_ERROR);
1717       } else {
1718         old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
1719         MoveToEx(to_hdc(actual_window), (int) x + points[0].x, (int) y + points[0].y, NULL);
1720         for (pos = 1; pos < numPoints; pos ++) {
1721           LineTo(to_hdc(actual_window), (int) x + points[pos].x, (int) y + points[pos].y);
1722         } /* for */
1723         SetPixel(to_hdc(actual_window), (int) x + points[numPoints - 1].x, (int) y + points[numPoints - 1].y, (COLORREF) col);
1724         SelectObject(to_hdc(actual_window), old_pen);
1725         if (to_backup_hdc(actual_window) != 0) {
1726           old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
1727           MoveToEx(to_backup_hdc(actual_window), (int) x + points[0].x, (int) y + points[0].y, NULL);
1728           for (pos = 1; pos < numPoints; pos ++) {
1729             LineTo(to_backup_hdc(actual_window), (int) x + points[pos].x, (int) y + points[pos].y);
1730           } /* for */
1731           SetPixel(to_backup_hdc(actual_window), (int) x + points[numPoints - 1].x, (int) y + points[numPoints - 1].y, (COLORREF) col);
1732           SelectObject(to_backup_hdc(actual_window), old_pen);
1733         } /* if */
1734         DeleteObject(current_pen);
1735       } /* if */
1736     } /* if */
1737   } /* drwPolyLine */
1738 
1739 
1740 
drwFPolyLine(const_winType actual_window,intType x,intType y,bstriType point_list,intType col)1741 void drwFPolyLine (const_winType actual_window,
1742     intType x, intType y, bstriType point_list, intType col)
1743 
1744   {
1745     POINT *points;
1746     memSizeType numPoints;
1747     memSizeType pos;
1748     HPEN old_pen;
1749     HPEN current_pen;
1750     HBRUSH old_brush;
1751     HBRUSH current_brush;
1752 
1753   /* drwFPolyLine */
1754     points = (POINT *) point_list->mem;
1755     numPoints = point_list->size / sizeof(POINT);
1756     for (pos = 0; pos < numPoints; pos ++) {
1757       points[pos].x += (int) x;
1758       points[pos].y += (int) y;
1759     } /* for */
1760     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
1761     current_brush = CreateSolidBrush((COLORREF) col);
1762     if (unlikely(current_pen == NULL || current_brush == NULL || numPoints > INT_MAX)) {
1763       raise_error(MEMORY_ERROR);
1764     } else {
1765       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
1766       old_brush = (HBRUSH) SelectObject(to_hdc(actual_window), current_brush);
1767       Polygon(to_hdc(actual_window), points, (int) numPoints);
1768       SelectObject(to_hdc(actual_window), old_pen);
1769       SelectObject(to_hdc(actual_window), old_brush);
1770       if (to_backup_hdc(actual_window) != 0) {
1771         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
1772         old_brush = (HBRUSH) SelectObject(to_backup_hdc(actual_window), current_brush);
1773         Polygon(to_backup_hdc(actual_window), points, (int) numPoints);
1774         SelectObject(to_backup_hdc(actual_window), old_pen);
1775         SelectObject(to_backup_hdc(actual_window), old_brush);
1776       } /* if */
1777       DeleteObject(current_pen);
1778       DeleteObject(current_brush);
1779     } /* if */
1780     for (pos = 0; pos < numPoints; pos ++) {
1781       points[pos].x -= (int) x;
1782       points[pos].y -= (int) y;
1783     } /* for */
1784   } /* drwFPolyLine */
1785 
1786 
1787 
drwPut(const_winType destWindow,intType xDest,intType yDest,const_winType pixmap)1788 void drwPut (const_winType destWindow, intType xDest, intType yDest,
1789     const_winType pixmap)
1790 
1791   {
1792     HDC hdcMem;
1793 
1794   /* drwPut */
1795     logFunction(printf("drwPut(" FMT_U_MEM ", " FMT_D ", " FMT_D ", " FMT_U_MEM ")\n",
1796                        (memSizeType) destWindow, xDest, yDest, (memSizeType) pixmap););
1797     if (pixmap != NULL) {
1798       if (to_hasTransparentPixel(pixmap)) {
1799         hdcMem = CreateCompatibleDC(0);
1800         SelectObject(hdcMem, to_maskBitmap(pixmap));
1801         BitBlt(to_hdc(destWindow), castToInt(xDest), castToInt(yDest),
1802                (int) to_width(pixmap), (int) to_height(pixmap), hdcMem, 0, 0, SRCAND);
1803         BitBlt(to_hdc(destWindow), castToInt(xDest), castToInt(yDest),
1804                (int) to_width(pixmap), (int) to_height(pixmap), to_hdc(pixmap), 0, 0, SRCPAINT);
1805         if (to_backup_hdc(destWindow) != 0) {
1806           SelectObject(hdcMem, to_maskBitmap(pixmap));
1807           BitBlt(to_backup_hdc(destWindow), castToInt(xDest), castToInt(yDest),
1808                  (int) to_width(pixmap), (int) to_height(pixmap), hdcMem, 0, 0, SRCAND);
1809           BitBlt(to_backup_hdc(destWindow), castToInt(xDest), castToInt(yDest),
1810                  (int) to_width(pixmap), (int) to_height(pixmap), to_hdc(pixmap), 0, 0, SRCPAINT);
1811         } /* if */
1812         DeleteDC(hdcMem);
1813       } else {
1814         BitBlt(to_hdc(destWindow), castToInt(xDest), castToInt(yDest),
1815                (int) to_width(pixmap), (int) to_height(pixmap), to_hdc(pixmap), 0, 0, SRCCOPY);
1816         if (to_backup_hdc(destWindow) != 0) {
1817           BitBlt(to_backup_hdc(destWindow), castToInt(xDest), castToInt(yDest),
1818                  (int) to_width(pixmap), (int) to_height(pixmap), to_hdc(pixmap), 0, 0, SRCCOPY);
1819         } /* if */
1820       } /* if */
1821     } /* if */
1822   } /* drwPut */
1823 
1824 
1825 
drwPutScaled(const_winType destWindow,intType xDest,intType yDest,intType width,intType height,const_winType pixmap)1826 void drwPutScaled (const_winType destWindow, intType xDest, intType yDest,
1827     intType width, intType height, const_winType pixmap)
1828 
1829   { /* drwPutScaled */
1830     logFunction(printf("drwPutScaled(" FMT_U_MEM  ", " FMT_D ", " FMT_D ", "
1831                        FMT_D ", " FMT_D ", " FMT_U_MEM")\n",
1832                        (memSizeType) destWindow, xDest, yDest,
1833                        width, height, (memSizeType) pixmap););
1834     if (unlikely(!inIntRange(xDest) || !inIntRange(yDest) ||
1835                  !inIntRange(width) || width < 0 ||
1836                  !inIntRange(height) || height < 0)) {
1837       raise_error(RANGE_ERROR);
1838     } else if (pixmap != NULL) {
1839       SetStretchBltMode(to_hdc(destWindow), COLORONCOLOR);
1840       StretchBlt(to_hdc(destWindow), (int) xDest, (int) yDest,
1841                  (int) width, (int) height, to_hdc(pixmap), 0, 0,
1842                  (int) to_width(pixmap), (int) to_height(pixmap), SRCCOPY);
1843       if (to_backup_hdc(destWindow) != 0) {
1844         SetStretchBltMode(to_backup_hdc(destWindow), COLORONCOLOR);
1845         StretchBlt(to_backup_hdc(destWindow), (int) xDest, (int) yDest,
1846                    (int) width, (int) height, to_hdc(pixmap), 0, 0,
1847                    (int) to_width(pixmap), (int) to_height(pixmap), SRCCOPY);
1848       } /* if */
1849     } /* if */
1850   } /* drwPutScaled */
1851 
1852 
1853 
drwRect(const_winType actual_window,intType x,intType y,intType width,intType height)1854 void drwRect (const_winType actual_window,
1855     intType x, intType y, intType width, intType height)
1856 
1857   { /* drwRect */
1858     logFunction(printf("drwRect(" FMT_U_MEM ", " FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ")\n",
1859                        (memSizeType) actual_window, x, y, width, height););
1860     Rectangle(to_hdc(actual_window), castToInt(x), castToInt(y),
1861               castToInt(x + width), castToInt(y + height));
1862     if (to_backup_hdc(actual_window) != 0) {
1863       Rectangle(to_backup_hdc(actual_window), castToInt(x), castToInt(y),
1864                 castToInt(x + width), castToInt(y + height));
1865     } /* if */
1866   } /* drwRect */
1867 
1868 
1869 
drwPRect(const_winType actual_window,intType x,intType y,intType width,intType height,intType col)1870 void drwPRect (const_winType actual_window,
1871     intType x, intType y, intType width, intType height, intType col)
1872 
1873   {
1874     HPEN old_pen;
1875     HPEN current_pen;
1876     HBRUSH old_brush;
1877     HBRUSH current_brush;
1878 
1879   /* drwPRect */
1880     logFunction(printf("drwPRect(" FMT_U_MEM ", " FMT_D ", " FMT_D ", " FMT_D ", " FMT_D ", " F_X(08) ")\n",
1881                        (memSizeType) actual_window, x, y, width, height, col););
1882     /* SetDCPenColor(to_hdc(actual_window), (COLORREF) col); */
1883 #ifdef OUT_OF_ORDER
1884     if (width == 0 && height == 0) {
1885       printf("width == 0 && height == 0\n");
1886     } /* if */
1887     if (width == 1 && height == 1) {
1888       printf("width == 1 && height == 1\n");
1889     } /* if */
1890 #endif
1891     current_pen = CreatePen(PS_SOLID, 1, (COLORREF) col);
1892     current_brush = CreateSolidBrush((COLORREF) col);
1893     if (unlikely(current_pen == NULL || current_brush == NULL)) {
1894       raise_error(MEMORY_ERROR);
1895     } else {
1896       old_pen = (HPEN) SelectObject(to_hdc(actual_window), current_pen);
1897       old_brush = (HBRUSH) SelectObject(to_hdc(actual_window), current_brush);
1898       if (width == 1) {
1899         if (height == 1) {
1900           SetPixel(to_hdc(actual_window), castToInt(x), castToInt(y), (COLORREF) col);
1901         } else {
1902           MoveToEx(to_hdc(actual_window), castToInt(x), castToInt(y), NULL);
1903           LineTo(to_hdc(actual_window), castToInt(x), castToInt(y + height));
1904         } /* if */
1905       } else {
1906         if (height == 1) {
1907           MoveToEx(to_hdc(actual_window), castToInt(x), castToInt(y), NULL);
1908           LineTo(to_hdc(actual_window), castToInt(x + width), castToInt(y));
1909         } else {
1910           Rectangle(to_hdc(actual_window), castToInt(x), castToInt(y), castToInt(x + width), castToInt(y + height));
1911         } /* if */
1912       } /* if */
1913       SelectObject(to_hdc(actual_window), old_pen);
1914       SelectObject(to_hdc(actual_window), old_brush);
1915       if (to_backup_hdc(actual_window) != 0) {
1916         old_pen = (HPEN) SelectObject(to_backup_hdc(actual_window), current_pen);
1917         old_brush = (HBRUSH) SelectObject(to_backup_hdc(actual_window), current_brush);
1918         if (width == 1) {
1919           if (height == 1) {
1920             SetPixel(to_backup_hdc(actual_window), castToInt(x), castToInt(y), (COLORREF) col);
1921           } else {
1922             MoveToEx(to_backup_hdc(actual_window), castToInt(x), castToInt(y), NULL);
1923             LineTo(to_backup_hdc(actual_window), castToInt(x), castToInt(y + height));
1924           } /* if */
1925         } else {
1926           if (height == 1) {
1927             MoveToEx(to_backup_hdc(actual_window), castToInt(x), castToInt(y), NULL);
1928             LineTo(to_backup_hdc(actual_window), castToInt(x + width), castToInt(y));
1929           } else {
1930             Rectangle(to_backup_hdc(actual_window), castToInt(x), castToInt(y), castToInt(x + width), castToInt(y + height));
1931           } /* if */
1932         } /* if */
1933         SelectObject(to_backup_hdc(actual_window), old_pen);
1934         SelectObject(to_backup_hdc(actual_window), old_brush);
1935       } /* if */
1936       DeleteObject(current_pen);
1937       DeleteObject(current_brush);
1938     } /* if */
1939   } /* drwPRect */
1940 
1941 
1942 
drwRgbColor(intType redLight,intType greenLight,intType blueLight)1943 intType drwRgbColor (intType redLight, intType greenLight, intType blueLight)
1944 
1945   { /* drwRgbColor */
1946     logFunction(printf("drwRgbColor(" FMT_D ", " FMT_D ", " FMT_D ")\n",
1947                        redLight, greenLight, blueLight););
1948     return (intType) RGB(((uintType) redLight) >> 8,
1949                          ((uintType) greenLight) >> 8,
1950                          ((uintType) blueLight) >> 8);
1951   } /* drwRgbColor */
1952 
1953 
1954 
drwPixelToRgb(intType col,intType * redLight,intType * greenLight,intType * blueLight)1955 void drwPixelToRgb (intType col, intType *redLight, intType *greenLight, intType *blueLight)
1956 
1957   { /* drwPixelToRgb */
1958     *redLight   = GetRValue(col) << 8;
1959     *greenLight = GetGValue(col) << 8;
1960     *blueLight  = GetBValue(col) << 8;
1961   } /* drwPixelToRgb */
1962 
1963 
1964 
drwBackground(intType col)1965 void drwBackground (intType col)
1966 
1967   { /* drwBackground */
1968   } /* drwBackground */
1969 
1970 
1971 
drwColor(intType col)1972 void drwColor (intType col)
1973 
1974   { /* drwColor */
1975       /* SetDCPenColor(to_hdc(actual_window), (COLORREF) col); */
1976   } /* drwColor */
1977 
1978 
1979 
1980 /**
1981  *  Determine the height of the screen in pixels.
1982  */
drwScreenHeight(void)1983 intType drwScreenHeight (void)
1984 
1985   {
1986     int height;
1987 
1988   /* drwScreenHeight */
1989     logFunction(printf("drwScreenHeight()\n"););
1990     height = GetSystemMetrics(SM_CYSCREEN);
1991     logFunction(printf("drwScreenHeight() --> %u\n", height););
1992     return (intType) height;
1993   } /* drwScreenHeight */
1994 
1995 
1996 
1997 /**
1998  *  Determine the width of the screen in pixels.
1999  */
drwScreenWidth(void)2000 intType drwScreenWidth (void)
2001 
2002   {
2003     int width;
2004 
2005   /* drwScreenWidth */
2006     logFunction(printf("drwScreenWidth()\n"););
2007     width = GetSystemMetrics(SM_CXSCREEN);
2008     logFunction(printf("drwScreenWidth() --> %u\n", width););
2009     return (intType) width;
2010   } /* drwScreenWidth */
2011 
2012 
2013 
drwSetContent(const_winType actual_window,const_winType pixmap)2014 void drwSetContent (const_winType actual_window, const_winType pixmap)
2015 
2016   { /* drwSetContent */
2017     /* printf("begin drwSetContent(%lu, %lu)\n",
2018         to_hwnd(actual_window), to_hwnd(pixmap)); */
2019     if (pixmap != NULL) {
2020       BitBlt(to_hdc(actual_window), 0, 0,
2021              (int) to_width(pixmap), (int) to_height(pixmap),
2022              to_hdc(pixmap), 0, 0, SRCCOPY);
2023       if (to_backup_hdc(actual_window) != 0) {
2024         BitBlt(to_backup_hdc(actual_window), 0, 0,
2025                (int) to_width(pixmap), (int) to_height(pixmap),
2026                to_hdc(pixmap), 0, 0, SRCCOPY);
2027       } /* if */
2028     } /* if */
2029     /* printf("end drwSetContent(%lu, %lu)\n",
2030         to_hwnd(actual_window), to_hwnd(pixmap)); */
2031   } /* drwSetContent */
2032 
2033 
2034 
2035 /**
2036  *  Move the top left corner of a window to the coordinates x/y.
2037  *  If window decorations are present the top left corner of the
2038  *  window decorations will be at the position x/y. For a sub window
2039  *  the position is relative to the top left corner of the parent window
2040  *  drawing area (inside of the window decorations). For top level windows
2041  *  the position is relative to the top left corner of the screen.
2042  */
drwSetPos(const_winType actual_window,intType xPos,intType yPos)2043 void drwSetPos (const_winType actual_window, intType xPos, intType yPos)
2044 
2045   { /* drwSetPos */
2046     /* printf("begin drwSetPos(%lu, %ld, %ld)\n",
2047         to_hwnd(actual_window), xPos, yPos); */
2048     SetWindowPos(to_hwnd(actual_window), 0, castToInt(xPos), castToInt(yPos), 0, 0,
2049         /* SWP_NOSENDCHANGING | */ SWP_NOZORDER | SWP_NOSIZE);
2050     gkbKeyPressed();
2051     /* printf("end drwSetPos(%lu, %ld, %ld)\n",
2052         to_hwnd(actual_window), xPos, yPos); */
2053   } /* drwSetPos */
2054 
2055 
2056 
createMaskBitmap(HDC pixmapHdc,int width,int height,COLORREF transparentColor)2057 static HBITMAP createMaskBitmap (HDC pixmapHdc, int width, int height,
2058     COLORREF transparentColor)
2059 
2060   {
2061     HDC maskHdc;
2062     COLORREF oldBackgroundColor;
2063     HBITMAP maskBitmap;
2064 
2065   /* createMaskBitmap */
2066     /* Create monochrome (1 bit) maskBitmap. */
2067     maskBitmap = CreateBitmap(width, height, 1, 1, NULL);
2068     maskHdc = CreateCompatibleDC(0);
2069     SelectObject(maskHdc, maskBitmap);
2070     oldBackgroundColor = SetBkColor(pixmapHdc, transparentColor);
2071     /* Copy the bits from pixmapHdc to the B+W mask. */
2072     /* Everything with the background colour ends up */
2073     /* white and everythig else ends up black.       */
2074     BitBlt(maskHdc, 0, 0, width, height, pixmapHdc, 0, 0, SRCCOPY);
2075     /* Take the new mask and use it to turn the      */
2076     /* transparent colour in the pixmapHdc image to  */
2077     /* black so the transparency effect works right. */
2078     BitBlt(pixmapHdc, 0, 0, width, height, maskHdc, 0, 0, SRCINVERT);
2079     DeleteDC(maskHdc);
2080     SetBkColor(pixmapHdc, oldBackgroundColor);
2081     return maskBitmap;
2082   } /* createMaskBitmap */
2083 
2084 
2085 
drwSetTransparentColor(winType pixmap,intType col)2086 void drwSetTransparentColor (winType pixmap, intType col)
2087 
2088   { /* drwSetTransparentColor */
2089     logFunction(printf("drwSetTransparentColor(" FMT_U_MEM ", " F_X(08) ")\n",
2090                        (memSizeType) pixmap, col););
2091     to_var_hasTransparentPixel(pixmap) = TRUE;
2092     to_var_transparentPixel(pixmap) = (UINT) col;
2093     to_var_maskBitmap(pixmap) = createMaskBitmap(to_hdc(pixmap),
2094         (int) to_width(pixmap), (int) to_height(pixmap), (COLORREF) col);
2095   } /* drwSetTransparentColor */
2096 
2097 
2098 
drwSetWindowName(winType aWindow,const const_striType windowName)2099 void drwSetWindowName (winType aWindow, const const_striType windowName)
2100 
2101   {
2102     os_striType winName;
2103     BOOL funcRes;
2104     errInfoType err_info = OKAY_NO_ERROR;
2105 
2106   /* drwSetWindowName */
2107     logFunction(printf("drwSetWindowName(" FMT_U_MEM ", \"%s\")\n",
2108                        (memSizeType) aWindow,
2109                        striAsUnquotedCStri(windowName)););
2110     winName = stri_to_os_stri(windowName, &err_info);
2111     if (unlikely(winName == NULL)) {
2112       raise_error(err_info);
2113     } else {
2114       funcRes = SetWindowTextW(to_hwnd(aWindow), (LPCWSTR) winName);
2115       os_stri_free(winName);
2116       if (unlikely(funcRes == 0)) {
2117         logError(printf("SetWindowTextW(" FMT_U_MEM ", \"%s\") failed\n",
2118                         (memSizeType) aWindow,
2119                         striAsUnquotedCStri(windowName)););
2120         raise_error(FILE_ERROR);
2121       } /* if */
2122     } /* if */
2123     logFunction(printf("drwSetWindowName -->\n"););
2124   } /* drwSetWindowName */
2125 
2126 
2127 
drwText(const_winType actual_window,intType x,intType y,const const_striType stri,intType col,intType bkcol)2128 void drwText (const_winType actual_window, intType x, intType y,
2129     const const_striType stri, intType col, intType bkcol)
2130 
2131   {
2132     wchar_t *stri_buffer;
2133     wchar_t *wstri;
2134     strElemType *strelem;
2135     memSizeType len;
2136 
2137   /* drwText */
2138     if (unlikely(!inIntRange(x) || !inIntRange(y) ||
2139                  stri->size >= (unsigned int) INT_MAX)) {
2140       raise_error(RANGE_ERROR);
2141     } else if (unlikely(stri->size > MAX_WSTRI_LEN ||
2142                         !ALLOC_WSTRI(stri_buffer, stri->size))) {
2143       raise_error(MEMORY_ERROR);
2144     } else {
2145       wstri = stri_buffer;
2146       strelem = stri->mem;
2147       len = stri->size;
2148       for (; len > 0; wstri++, strelem++, len--) {
2149         if (unlikely(*strelem >= 65536)) {
2150           UNALLOC_WSTRI(stri_buffer, stri->size);
2151           raise_error(RANGE_ERROR);
2152           return;
2153         } /* if */
2154         *wstri = (wchar_t) *strelem;
2155       } /* for */
2156 
2157       SetTextColor(to_hdc(actual_window), (COLORREF) col);
2158       SetBkColor(to_hdc(actual_window), (COLORREF) bkcol);
2159       SetTextAlign(to_hdc(actual_window), TA_BASELINE | TA_LEFT);
2160       TextOutW(to_hdc(actual_window), (int) x, (int) y, stri_buffer, (int) stri->size);
2161       if (to_backup_hdc(actual_window) != 0) {
2162         SetTextColor(to_backup_hdc(actual_window), (COLORREF) col);
2163         SetBkColor(to_backup_hdc(actual_window), (COLORREF) bkcol);
2164         SetTextAlign(to_backup_hdc(actual_window), TA_BASELINE | TA_LEFT);
2165         TextOutW(to_backup_hdc(actual_window), (int) x, (int) y, stri_buffer, (int) stri->size);
2166       } /* if */
2167       UNALLOC_WSTRI(stri_buffer, stri->size);
2168     } /* if */
2169   } /* drwText */
2170 
2171 
2172 
2173 /**
2174  *  Lower a window to the bottom so that it does not obscure any other window.
2175  */
drwToBottom(const_winType actual_window)2176 void drwToBottom (const_winType actual_window)
2177 
2178   { /* drwToBottom */
2179     /* printf("begin drwToBottom(%lu)\n", to_hwnd(actual_window)); */
2180     SetWindowPos(to_hwnd(actual_window), HWND_BOTTOM, 0, 0, 0, 0,
2181         /* SWP_NOSENDCHANGING | */ SWP_NOMOVE | SWP_NOSIZE);
2182     /* printf("end drwToBottom(%lu)\n", to_hwnd(actual_window)); */
2183   } /* drwToBottom */
2184 
2185 
2186 
2187 /**
2188  *  Raise a window to the top so that no other window obscures it.
2189  */
drwToTop(const_winType actual_window)2190 void drwToTop (const_winType actual_window)
2191 
2192   { /* drwToTop */
2193     /* printf("begin drwToTop(%lu)\n", to_hwnd(actual_window)); */
2194     SetWindowPos(to_hwnd(actual_window), HWND_TOP, 0, 0, 0, 0,
2195         /* SWP_NOSENDCHANGING | */ SWP_NOMOVE | SWP_NOSIZE);
2196     /* printf("end drwToTop(%lu)\n", to_hwnd(actual_window)); */
2197   } /* drwToTop */
2198 
2199 
2200 
2201 /**
2202  *  Determine the width of the window drawing area in pixels.
2203  *  This excludes window declarations left and right. Add left and right
2204  *  border widths to get the width inclusive window decorations.
2205  */
drwWidth(const_winType actual_window)2206 intType drwWidth (const_winType actual_window)
2207 
2208   {
2209     RECT rect;
2210     intType width;
2211 
2212   /* drwWidth */
2213     logFunction(printf("drwWidth(" FMT_U_MEM "), usage=" FMT_U "\n",
2214                        (memSizeType) actual_window,
2215                        actual_window != 0 ? actual_window->usage_count: 0););
2216     if (is_pixmap(actual_window) ||
2217         GetClientRect(to_hwnd(actual_window), &rect) == 0) {
2218       width = to_width(actual_window);
2219     } else {
2220       width = (intType) ((unsigned int) (rect.right - rect.left));
2221     } /* if */
2222     logFunction(printf("drwWidth(" FMT_U_MEM ") --> " FMT_D "\n",
2223                        (memSizeType) actual_window, width););
2224     return width;
2225   } /* drwWidth */
2226 
2227 
2228 
2229 /**
2230  *  Determine the X position of the top left corner of a window in pixels.
2231  *  If window decorations are present this uses the top left corner of
2232  *  the window decorations. For a sub window the X position is relative
2233  *  to the top left corner of the parent window drawing area (inside of
2234  *  the window decorations). For top level windows the X position is
2235  *  relative to the top left corner of the screen.
2236  *  @exception RANGE_ERROR If 'actual_window' is a pixmap.
2237  */
drwXPos(const_winType actual_window)2238 intType drwXPos (const_winType actual_window)
2239 
2240   {
2241     RECT rect;
2242     POINT point;
2243     intType xPos;
2244 
2245   /* drwXPos */
2246     if (is_pixmap(actual_window)) {
2247       raise_error(RANGE_ERROR);
2248       xPos = 0;
2249     } else if (unlikely(GetWindowRect(to_hwnd(actual_window), &rect) == 0)) {
2250       raise_error(FILE_ERROR);
2251       xPos = 0;
2252     } else {
2253       point.x = rect.left;
2254       point.y = rect.top;
2255       ScreenToClient(GetParent(to_hwnd(actual_window)), &point);
2256       xPos = point.x;
2257     } /* if */
2258     logFunction(printf("drwXPos(" FMT_U_MEM ") --> " FMT_D "\n",
2259                        (memSizeType) actual_window, xPos););
2260     return xPos;
2261   } /* drwXPos */
2262 
2263 
2264 
2265 /**
2266  *  Determine the Y position of the top left corner of a window in pixels.
2267  *  If window decorations are present this uses the top left corner of
2268  *  the window decorations. For a sub window the Y position is relative
2269  *  to the top left corner of the parent window drawing area (inside of
2270  *  the window decorations). For top level windows the Y position is
2271  *  relative to the top left corner of the screen.
2272  *  @exception RANGE_ERROR If 'actual_window' is a pixmap.
2273  */
drwYPos(const_winType actual_window)2274 intType drwYPos (const_winType actual_window)
2275 
2276   {
2277     RECT rect;
2278     POINT point;
2279     intType yPos;
2280 
2281   /* drwYPos */
2282     if (is_pixmap(actual_window)) {
2283       raise_error(RANGE_ERROR);
2284       yPos = 0;
2285     } else if (unlikely(GetWindowRect(to_hwnd(actual_window), &rect) == 0)) {
2286       raise_error(FILE_ERROR);
2287       yPos = 0;
2288     } else {
2289       point.x = rect.left;
2290       point.y = rect.top;
2291       ScreenToClient(GetParent(to_hwnd(actual_window)), &point);
2292       yPos = point.y;
2293     } /* if */
2294     logFunction(printf("drwYPos(" FMT_U_MEM ") --> " FMT_D "\n",
2295                        (memSizeType) actual_window, yPos););
2296     return yPos;
2297   } /* drwYPos */
2298