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