aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_win32/ecore_win32_window.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_win32/ecore_win32_window.c')
-rw-r--r--libraries/ecore/src/lib/ecore_win32/ecore_win32_window.c1519
1 files changed, 1519 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_win32/ecore_win32_window.c b/libraries/ecore/src/lib/ecore_win32/ecore_win32_window.c
new file mode 100644
index 0000000..459f051
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_win32/ecore_win32_window.c
@@ -0,0 +1,1519 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdlib.h>
6#include <stdio.h> /* for printf */
7
8#define WIN32_LEAN_AND_MEAN
9#include <windows.h>
10#undef WIN32_LEAN_AND_MEAN
11
12#include <Eina.h>
13
14#include "Ecore_Win32.h"
15#include "ecore_win32_private.h"
16
17/*============================================================================*
18 * Local *
19 *============================================================================*/
20
21/**
22 * @cond LOCAL
23 */
24
25
26typedef enum _Ecore_Win32_Window_Z_Order Ecore_Win32_Window_Z_Order;
27enum _Ecore_Win32_Window_Z_Order
28{
29 ECORE_WIN32_WINDOW_Z_ORDER_BOTTOM,
30 ECORE_WIN32_WINDOW_Z_ORDER_NOTOPMOST,
31 ECORE_WIN32_WINDOW_Z_ORDER_TOP,
32 ECORE_WIN32_WINDOW_Z_ORDER_TOPMOST
33};
34
35static Ecore_Win32_Window *
36ecore_win32_window_internal_new(Ecore_Win32_Window *parent,
37 int x,
38 int y,
39 int width,
40 int height,
41 DWORD style)
42{
43 RECT rect;
44 Ecore_Win32_Window *w;
45 int minimal_width;
46 int minimal_height;
47
48 w = (Ecore_Win32_Window *)calloc(1, sizeof(Ecore_Win32_Window));
49 if (!w)
50 {
51 ERR("malloc() failed");
52 return NULL;
53 }
54
55 rect.left = 0;
56 rect.top = 0;
57 rect.right = width;
58 rect.bottom = height;
59 if (!AdjustWindowRectEx(&rect, style, FALSE, 0))
60 {
61 ERR("AdjustWindowRect() failed");
62 free(w);
63 return NULL;
64 }
65
66 minimal_width = GetSystemMetrics(SM_CXMIN);
67 minimal_height = GetSystemMetrics(SM_CYMIN);
68/* if (((rect.right - rect.left) < minimal_width) || */
69/* ((rect.bottom - rect.top) < minimal_height)) */
70/* { */
71/* fprintf (stderr, "[Ecore] [Win32] ERROR !!\n"); */
72/* fprintf (stderr, " Wrong size %ld\n", rect.right - rect.left); */
73/* free(w); */
74/* return NULL; */
75/* } */
76 if ((rect.right - rect.left) < minimal_width)
77 {
78 rect.right = rect.left + minimal_width;
79 }
80
81 w->window = CreateWindowEx(0,
82 ECORE_WIN32_WINDOW_CLASS, "",
83 style,
84 x, y,
85 rect.right - rect.left,
86 rect.bottom - rect.top,
87 parent ? parent->window : NULL,
88 NULL, _ecore_win32_instance, NULL);
89 if (!w->window)
90 {
91 ERR("CreateWindowEx() failed");
92 free(w);
93 return NULL;
94 }
95
96 SetLastError(0);
97 if (!SetWindowLongPtr(w->window, GWLP_USERDATA, (LONG_PTR)w) &&
98 (GetLastError() != 0))
99 {
100 ERR("SetWindowLongPtr() failed");
101 DestroyWindow(w->window);
102 free(w);
103 return NULL;
104 }
105
106 w->min_width = 0;
107 w->min_height = 0;
108 w->max_width = 32767;
109 w->max_height = 32767;
110 w->base_width = 0;
111 w->base_height = 0;
112 w->step_width = 1;
113 w->step_height = 1;
114
115 w->state.iconified = 0;
116 w->state.modal = 0;
117 w->state.sticky = 0;
118 w->state.maximized_vert = 0;
119 w->state.maximized_horz = 0;
120 w->state.shaded = 0;
121 w->state.hidden = 0;
122 w->state.fullscreen = 0;
123 w->state.above = 0;
124 w->state.below = 0;
125 w->state.demands_attention = 0;
126
127 w->type.desktop = 0;
128 w->type.dock = 0;
129 w->type.toolbar = 0;
130 w->type.menu = 0;
131 w->type.utility = 0;
132 w->type.splash = 0;
133 w->type.dialog = 0;
134 w->type.normal = 0;
135
136 w->pointer_is_in = 0;
137 w->borderless = 0;
138 w->iconified = 0;
139 w->fullscreen = 0;
140
141 return w;
142}
143
144/**
145 * @endcond
146 */
147
148
149/*============================================================================*
150 * Global *
151 *============================================================================*/
152
153/*============================================================================*
154 * API *
155 *============================================================================*/
156
157/**
158 * @addtogroup Ecore_Win32_Group Ecore_Win32 library
159 *
160 * @{
161 */
162
163/**
164 * @brief Creates a new window.
165 *
166 * @param parent The parent window.
167 * @param x The x coordinate of the top-left corner of the window.
168 * @param y The y coordinate of the top-left corner of the window.
169 * @param width The width of the window.
170 * @param height The height of hte window.
171 * @return A newly allocated window.
172 *
173 * This function creates a new window which parent is @p parent. @p width and
174 * @p height are the size of the window content (the client part),
175 * without the border and title bar. @p x and @p y are the system
176 * coordinates of the top left cerner of the window (that is, of the
177 * title bar). This function returns a newly created window on
178 * success, and @c NULL on failure.
179 */
180EAPI Ecore_Win32_Window *
181ecore_win32_window_new(Ecore_Win32_Window *parent,
182 int x,
183 int y,
184 int width,
185 int height)
186{
187 INF("creating window with border");
188
189 return ecore_win32_window_internal_new(parent,
190 x, y,
191 width, height,
192 WS_OVERLAPPEDWINDOW | WS_SIZEBOX);
193}
194
195/**
196 * @brief Creates a new borderless window.
197 *
198 * @param parent The parent window.
199 * @param x The x coordinate of the top-left corner of the window.
200 * @param y The y coordinate of the top-left corner of the window.
201 * @param width The width of the window.
202 * @param height The height of hte window.
203 * @return A newly allocated window.
204 *
205 * This function is the same than ecore_win32_window_override_new()
206 * but the returned window is borderless.
207 */
208EAPI Ecore_Win32_Window *
209ecore_win32_window_override_new(Ecore_Win32_Window *parent,
210 int x,
211 int y,
212 int width,
213 int height)
214{
215 INF("creating window without border");
216
217 return ecore_win32_window_internal_new(parent,
218 x, y,
219 width, height,
220 WS_POPUP);
221}
222
223/**
224 * @brief Free the given window.
225 *
226 * @param window The window to free.
227 *
228 * This function frees @p window. If @p window is @c NULL, this
229 * function does nothing.
230 */
231EAPI void
232ecore_win32_window_free(Ecore_Win32_Window *window)
233{
234 if (!window) return;
235
236 INF("destroying window");
237
238 if (window->shape.mask)
239 free(window->shape.mask);
240
241 DestroyWindow(window->window);
242 free(window);
243}
244
245/**
246 * @brief Return the window HANDLE associated to the given window.
247 *
248 * @param window The window to retrieve the HANDLE from.
249 *
250 * This function returns the window HANDLE associated to @p window. If
251 * @p window is @c NULL, this function returns @c NULL.
252 */
253EAPI void *
254ecore_win32_window_hwnd_get(Ecore_Win32_Window *window)
255{
256 if (!window) return NULL;
257
258 return window->window;
259}
260
261/*
262void
263ecore_win32_window_configure(Ecore_Win32_Window *window,
264 Ecore_Win32_Window_Z_Order order,
265 int x,
266 int y,
267 int width,
268 int height)
269{
270 HWND w;
271
272 switch (order)
273 {
274 case ECORE_WIN32_WINDOW_Z_ORDER_BOTTOM:
275 w = HWND_BOTTOM;
276 break;
277 case ECORE_WIN32_WINDOW_Z_ORDER_NOTOPMOST:
278 w = HWND_NOTOPMOST;
279 break;
280 case ECORE_WIN32_WINDOW_Z_ORDER_TOP:
281 w = HWND_TOP;
282 break;
283 case ECORE_WIN32_WINDOW_Z_ORDER_TOPMOST:
284 w = HWND_TOPMOST;
285 break;
286 default:
287 return;
288 }
289 SetWindowPos((Ecore_Win32_Window *)window->window, w, x, y, width, height, ???);
290}
291*/
292
293/**
294 * @brief Move the given window to a given position.
295 *
296 * @param window The window to move.
297 * @param x The x coordinate of the destination position.
298 * @param y The y coordinate of the destination position.
299 *
300 * This function move @p window to the new position of coordinates @p x
301 * and @p y. If @p window is @c NULL, or if it is fullscreen, or on
302 * error, this function does nothing.
303 */
304EAPI void
305ecore_win32_window_move(Ecore_Win32_Window *window,
306 int x,
307 int y)
308{
309 RECT rect;
310
311 /* FIXME: on fullscreen, should not move it */
312 if (!window) return;
313
314 INF("moving window (%dx%d)", x, y);
315
316 if (!GetWindowRect(window->window, &rect))
317 {
318 ERR("GetWindowRect() failed");
319 return;
320 }
321
322 if (!MoveWindow(window->window, x, y,
323 rect.right - rect.left,
324 rect.bottom - rect.top,
325 TRUE))
326 {
327 ERR("MoveWindow() failed");
328 }
329}
330
331/**
332 * @brief Resize the given window to a given size.
333 *
334 * @param window The window to resize.
335 * @param width The new width.
336 * @param height The new height.
337 *
338 * This function resize @p window to the new @p width and @p height.
339 * If @p window is @c NULL, or if it is fullscreen, or on error, this
340 * function does nothing.
341 */
342EAPI void
343ecore_win32_window_resize(Ecore_Win32_Window *window,
344 int width,
345 int height)
346{
347 RECT rect;
348 DWORD style;
349 int x;
350 int y;
351 int minimal_width;
352 int minimal_height;
353
354 /* FIXME: on fullscreen, should not resize it */
355 if (!window) return;
356
357 INF("resizing window (%dx%d)", width, height);
358
359 minimal_width = MAX(GetSystemMetrics(SM_CXMIN), (int)window->min_width);
360 minimal_height = MAX(GetSystemMetrics(SM_CYMIN), (int)window->min_height);
361
362 if (!GetWindowRect(window->window, &rect))
363 {
364 ERR("GetWindowRect() failed");
365 return;
366 }
367
368 x = rect.left;
369 y = rect.top;
370 rect.left = 0;
371 rect.top = 0;
372 if (width < minimal_width) width = minimal_width;
373 if (width > (int)window->max_width) width = window->max_width;
374 if (height < minimal_height) height = minimal_height;
375 if (height > (int)window->max_height) height = window->max_height;
376 rect.right = width;
377 rect.bottom = height;
378 if (!(style = GetWindowLong(window->window, GWL_STYLE)))
379 {
380 ERR("GetWindowLong() failed");
381 return;
382 }
383 if (!AdjustWindowRect(&rect, style, FALSE))
384 {
385 ERR("AdjustWindowRect() failed");
386 return;
387 }
388
389 if (!MoveWindow(window->window, x, y,
390 rect.right - rect.left,
391 rect.bottom - rect.top,
392 TRUE))
393 {
394 ERR("MoveWindow() failed");
395 }
396}
397
398/**
399 * @brief Move and resize the given window to a given position and size.
400 *
401 * @param window The window to move and resize.
402 * @param x The x coordinate of the destination position.
403 * @param y The x coordinate of the destination position.
404 * @param width The new width.
405 * @param height The new height.
406 *
407 * This function resize @p window to the new position of coordinates @p x
408 * and @p y and the new @p width and @p height. If @p window is @c NULL,
409 * or if it is fullscreen, or on error, this function does nothing.
410 */
411EAPI void
412ecore_win32_window_move_resize(Ecore_Win32_Window *window,
413 int x,
414 int y,
415 int width,
416 int height)
417{
418 RECT rect;
419 DWORD style;
420 int minimal_width;
421 int minimal_height;
422
423 /* FIXME: on fullscreen, should not move/resize it */
424 if (!window) return;
425
426 INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height);
427
428 minimal_width = MAX(GetSystemMetrics(SM_CXMIN), (int)window->min_width);
429 minimal_height = MAX(GetSystemMetrics(SM_CYMIN), (int)window->min_height);
430
431 rect.left = 0;
432 rect.top = 0;
433 if (width < minimal_width) width = minimal_width;
434 if (width > (int)window->max_width) width = window->max_width;
435 if (height < minimal_height) height = minimal_height;
436 if (height > (int)window->max_height) height = window->max_height;
437 rect.right = width;
438 rect.bottom = height;
439 if (!(style = GetWindowLong(window->window, GWL_STYLE)))
440 {
441 ERR("GetWindowLong() failed");
442 return;
443 }
444 if (!AdjustWindowRect(&rect, style, FALSE))
445 {
446 ERR("AdjustWindowRect() failed");
447 return;
448 }
449
450 if (!MoveWindow(window->window, x, y,
451 rect.right - rect.left,
452 rect.bottom - rect.top,
453 TRUE))
454 {
455 ERR("MoveWindow() failed");
456 }
457}
458
459/**
460 * @brief Get the geometry of the given window.
461 *
462 * @param window The window to retrieve the geometry from.
463 * @param x The x coordinate of the position.
464 * @param y The x coordinate of the position.
465 * @param width The width.
466 * @param height The height.
467 *
468 * This function retrieves the position and size of @p window. @p x,
469 * @p y, @p width and @p height can be buffers that will be filled with
470 * the corresponding values. If one of them is @c NULL, nothing will
471 * be done for that parameter. If @p window is @c NULL, and if the
472 * buffers are not @c NULL, they will be filled with respectively 0,
473 * 0, the size of the screen and the height of the screen.
474 */
475EAPI void
476ecore_win32_window_geometry_get(Ecore_Win32_Window *window,
477 int *x,
478 int *y,
479 int *width,
480 int *height)
481{
482 RECT rect;
483 int w;
484 int h;
485
486 INF("getting window geometry");
487
488 if (!window)
489 {
490 if (x) *x = 0;
491 if (y) *y = 0;
492 if (width) *width = GetSystemMetrics(SM_CXSCREEN);
493 if (height) *height = GetSystemMetrics(SM_CYSCREEN);
494
495 return;
496 }
497
498 if (!GetClientRect(window->window, &rect))
499 {
500 ERR("GetClientRect() failed");
501
502 if (x) *x = 0;
503 if (y) *y = 0;
504 if (width) *width = 0;
505 if (height) *height = 0;
506
507 return;
508 }
509
510 w = rect.right - rect.left;
511 h = rect.bottom - rect.top;
512
513 if (!GetWindowRect(window->window, &rect))
514 {
515 ERR("GetWindowRect() failed");
516
517 if (x) *x = 0;
518 if (y) *y = 0;
519 if (width) *width = 0;
520 if (height) *height = 0;
521
522 return;
523 }
524
525 if (x) *x = rect.left;
526 if (y) *y = rect.top;
527 if (width) *width = w;
528 if (height) *height = h;
529}
530
531/**
532 * @brief Get the size of the given window.
533 *
534 * @param window The window to retrieve the size from.
535 * @param width The width.
536 * @param height The height.
537 *
538 * This function retrieves the size of @p window. @p width and
539 * @p height can be buffers that will be filled with the corresponding
540 * values. If one of them is @c NULL, nothing will be done for that
541 * parameter. If @p window is @c NULL, and if the buffers are not
542 * @c NULL, they will be filled with respectively the size of the screen
543 * and the height of the screen.
544 */
545EAPI void
546ecore_win32_window_size_get(Ecore_Win32_Window *window,
547 int *width,
548 int *height)
549{
550 RECT rect;
551
552 INF("getting window size");
553
554 if (!window)
555 {
556 if (width) *width = GetSystemMetrics(SM_CXSCREEN);
557 if (height) *height = GetSystemMetrics(SM_CYSCREEN);
558
559 return;
560 }
561
562 if (!GetClientRect(window->window, &rect))
563 {
564 ERR("GetClientRect() failed");
565
566 if (width) *width = 0;
567 if (height) *height = 0;
568 }
569
570 if (width) *width = rect.right - rect.left;
571 if (height) *height = rect.bottom - rect.top;
572}
573
574/**
575 * @brief Set the minimum size of the given window.
576 *
577 * @param window The window.
578 * @param min_width The minimal width.
579 * @param min_height The minimal height.
580 *
581 * This function sets the minimum size of @p window to @p min_width
582 * and *p min_height. If @p window is @c NULL, this functions does
583 * nothing.
584 */
585EAPI void
586ecore_win32_window_size_min_set(Ecore_Win32_Window *window,
587 unsigned int min_width,
588 unsigned int min_height)
589{
590 if (!window) return;
591
592 printf ("ecore_win32_window_size_min_set : %p %d %d\n", window, min_width, min_height);
593 window->min_width = min_width;
594 window->min_height = min_height;
595}
596
597/**
598 * @brief Get the minimum size of the given window.
599 *
600 * @param window The window.
601 * @param min_width The minimal width.
602 * @param min_height The minimal height.
603 *
604 * This function fills the minimum size of @p window in the buffers
605 * @p min_width and *p min_height. They both can be @c NULL. If
606 * @p window is @c NULL, this functions does nothing.
607 */
608EAPI void
609ecore_win32_window_size_min_get(Ecore_Win32_Window *window,
610 unsigned int *min_width,
611 unsigned int *min_height)
612{
613 if (!window) return;
614
615 printf ("ecore_win32_window_size_min_get : %p %d %d\n", window, window->min_width, window->min_height);
616 if (min_width) *min_width = window->min_width;
617 if (min_height) *min_height = window->min_height;
618}
619
620/**
621 * @brief Set the maximum size of the given window.
622 *
623 * @param window The window.
624 * @param max_width The maximal width.
625 * @param max_height The maximal height.
626 *
627 * This function sets the maximum size of @p window to @p max_width
628 * and *p max_height. If @p window is @c NULL, this functions does
629 * nothing.
630 */
631EAPI void
632ecore_win32_window_size_max_set(Ecore_Win32_Window *window,
633 unsigned int max_width,
634 unsigned int max_height)
635{
636 if (!window) return;
637
638 printf ("ecore_win32_window_size_max_set : %p %d %d\n", window, max_width, max_height);
639 window->max_width = max_width;
640 window->max_height = max_height;
641}
642
643/**
644 * @brief Get the maximum size of the given window.
645 *
646 * @param window The window.
647 * @param max_width The maximal width.
648 * @param max_height The maximal height.
649 *
650 * This function fills the maximum size of @p window in the buffers
651 * @p max_width and *p max_height. They both can be @c NULL. If
652 * @p window is @c NULL, this functions does nothing.
653 */
654EAPI void
655ecore_win32_window_size_max_get(Ecore_Win32_Window *window,
656 unsigned int *max_width,
657 unsigned int *max_height)
658{
659 if (!window) return;
660
661 printf ("ecore_win32_window_size_max_get : %p %d %d\n", window, window->max_width, window->max_height);
662 if (max_width) *max_width = window->max_width;
663 if (max_height) *max_height = window->max_height;
664}
665
666/**
667 * @brief Set the base size of the given window.
668 *
669 * @param window The window.
670 * @param base_width The base width.
671 * @param base_height The base height.
672 *
673 * This function sets the base size of @p window to @p base_width
674 * and *p base_height. If @p window is @c NULL, this functions does
675 * nothing.
676 */
677EAPI void
678ecore_win32_window_size_base_set(Ecore_Win32_Window *window,
679 unsigned int base_width,
680 unsigned int base_height)
681{
682 printf ("ecore_win32_window_size_base_set : %p %d %d\n", window, base_width, base_height);
683 if (!window) return;
684
685 window->base_width = base_width;
686 window->base_height = base_height;
687}
688
689/**
690 * @brief Get the base size of the given window.
691 *
692 * @param window The window.
693 * @param base_width The base width.
694 * @param base_height The bas height.
695 *
696 * This function fills the base size of @p window in the buffers
697 * @p base_width and *p base_height. They both can be @c NULL. If
698 * @p window is @c NULL, this functions does nothing.
699 */
700EAPI void
701ecore_win32_window_size_base_get(Ecore_Win32_Window *window,
702 unsigned int *base_width,
703 unsigned int *base_height)
704{
705 if (!window) return;
706
707 printf ("ecore_win32_window_size_base_get : %p %d %d\n", window, window->base_width, window->base_height);
708 if (base_width) *base_width = window->base_width;
709 if (base_height) *base_height = window->base_height;
710}
711
712/**
713 * @brief Set the step size of the given window.
714 *
715 * @param window The window.
716 * @param step_width The step width.
717 * @param step_height The step height.
718 *
719 * This function sets the step size of @p window to @p step_width
720 * and *p step_height. If @p window is @c NULL, this functions does
721 * nothing.
722 */
723EAPI void
724ecore_win32_window_size_step_set(Ecore_Win32_Window *window,
725 unsigned int step_width,
726 unsigned int step_height)
727{
728 printf ("ecore_win32_window_size_step_set : %p %d %d\n", window, step_width, step_height);
729 if (!window) return;
730
731 window->step_width = step_width;
732 window->step_height = step_height;
733}
734
735/**
736 * @brief Get the step size of the given window.
737 *
738 * @param window The window.
739 * @param step_width The step width.
740 * @param step_height The bas height.
741 *
742 * This function fills the step size of @p window in the buffers
743 * @p step_width and *p step_height. They both can be @c NULL. If
744 * @p window is @c NULL, this functions does nothing.
745 */
746EAPI void
747ecore_win32_window_size_step_get(Ecore_Win32_Window *window,
748 unsigned int *step_width,
749 unsigned int *step_height)
750{
751 if (!window) return;
752
753 printf ("ecore_win32_window_size_step_get : %p %d %d\n", window, window->step_width, window->step_height);
754 if (step_width) *step_width = window->step_width;
755 if (step_height) *step_height = window->step_height;
756}
757
758EAPI void
759ecore_win32_window_shape_set(Ecore_Win32_Window *window,
760 unsigned short width,
761 unsigned short height,
762 unsigned char *mask)
763{
764 HRGN rgn;
765 int x;
766 int y;
767 OSVERSIONINFO version_info;
768
769 if (!window)
770 return;
771
772 if (!mask)
773 {
774 window->shape.enabled = 0;
775 if (window->shape.layered != 0)
776 {
777 window->shape.layered = 0;
778#if defined(WS_EX_LAYERED)
779 SetLastError(0);
780 if (!SetWindowLongPtr(window->window, GWL_EXSTYLE,
781 GetWindowLong(window->window, GWL_EXSTYLE) & (~WS_EX_LAYERED)) &&
782 (GetLastError() != 0))
783 {
784 ERR("SetWindowLongPtr() failed");
785 return;
786 }
787 if (!RedrawWindow(window->window, NULL, NULL,
788 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN))
789 {
790 ERR("RedrawWindow() failed");
791 return;
792 }
793#endif
794 }
795 else
796 if (!SetWindowRgn(window->window, NULL, TRUE))
797 {
798 ERR("SetWindowRgn() failed");
799 }
800 return;
801 }
802
803 if (width == 0 || height == 0)
804 return;
805
806 window->shape.enabled = 1;
807
808 if (width != window->shape.width || height != window->shape.height)
809 {
810 window->shape.width = width;
811 window->shape.height = height;
812 if (window->shape.mask)
813 {
814 free(window->shape.mask);
815 window->shape.mask = NULL;
816 }
817 window->shape.mask = malloc(width * height);
818 }
819 memcpy(window->shape.mask, mask, width * height);
820
821 window->shape.layered = 0;
822
823#if defined(WS_EX_LAYERED)
824 version_info.dwOSVersionInfoSize = sizeof(version_info);
825 if (GetVersionEx(&version_info) == TRUE && version_info.dwMajorVersion == 5)
826 {
827 SetLastError(0);
828 if (!SetWindowLongPtr(window->window, GWL_EXSTYLE,
829 GetWindowLong(window->window, GWL_EXSTYLE) | WS_EX_LAYERED) &&
830 (GetLastError() != 0))
831 {
832 ERR("SetWindowLongPtr() failed");
833 return;
834 }
835 window->shape.layered = 1;
836 return;
837 }
838#endif
839
840 if (!(rgn = CreateRectRgn(0, 0, 0, 0)))
841 {
842 ERR("CreateRectRgn() failed");
843 return;
844 }
845 for (y = 0; y < height; y++)
846 {
847 HRGN rgnLine;
848
849 if (!(rgnLine = CreateRectRgn(0, 0, 0, 0)))
850 {
851 ERR("CreateRectRgn() failed");
852 return;
853 }
854 for (x = 0; x < width; x++)
855 {
856 if (mask[y * width + x] > 0)
857 {
858 HRGN rgnDot;
859
860 if (!(rgnDot = CreateRectRgn(x, y, x + 1, y + 1)))
861 {
862 ERR("CreateRectRgn() failed");
863 return;
864 }
865 if (CombineRgn(rgnLine, rgnLine, rgnDot, RGN_OR) == ERROR)
866 {
867 ERR("CombineRgn() has not created a new region");
868 }
869 if (!DeleteObject(rgnDot))
870 {
871 ERR("DeleteObject() failed");
872 return;
873 }
874 }
875 }
876 if (CombineRgn(rgn, rgn, rgnLine, RGN_OR) == ERROR)
877 {
878 ERR("CombineRgn() has not created a new region");
879 }
880 if (!DeleteObject(rgnLine))
881 {
882 ERR("DeleteObject() failed");
883 return;
884 }
885 }
886 if (!SetWindowRgn(window->window, rgn, TRUE))
887 {
888 ERR("SetWindowRgn() failed");
889 }
890}
891
892/**
893 * @brief Show the given window.
894 *
895 * @param window The window to show.
896 *
897 * This function shows @p window. If @p window is @c NULL, or on
898 * error, this function does nothing.
899 */
900EAPI void
901ecore_win32_window_show(Ecore_Win32_Window *window)
902{
903 if (!window) return;
904
905 INF("showing window");
906
907 ShowWindow(window->window, SW_SHOWNORMAL);
908 if (!UpdateWindow(window->window))
909 {
910 ERR("UpdateWindow() failed");
911 }
912}
913
914/* FIXME: seems to block the taskbar */
915/**
916 * @brief Hide the given window.
917 *
918 * @param window The window to show.
919 *
920 * This function hides @p window. If @p window is @c NULL, or on
921 * error, this function does nothing.
922 */
923EAPI void
924ecore_win32_window_hide(Ecore_Win32_Window *window)
925{
926 if (!window) return;
927
928 INF("hiding window");
929
930 ShowWindow(window->window, SW_HIDE);
931}
932
933/**
934 * @brief Place the given window at the top of the Z order.
935 *
936 * @param window The window to place at the top.
937 *
938 * This function places @p window at the top of the Z order. If
939 * @p window is @c NULL, this function does nothing.
940 */
941EAPI void
942ecore_win32_window_raise(Ecore_Win32_Window *window)
943{
944 if (!window) return;
945
946 INF("raising window");
947
948 if (!SetWindowPos(window->window,
949 HWND_TOP, 0, 0, 0, 0,
950 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
951 {
952 ERR("SetWindowPos() failed");
953 }
954}
955
956/**
957 * @brief Place the given window at the bottom of the Z order.
958 *
959 * @param window The window to place at the bottom.
960 *
961 * This function places @p window at the bottom of the Z order. If
962 * @p window is @c NULL, this function does nothing.
963 */
964EAPI void
965ecore_win32_window_lower(Ecore_Win32_Window *window)
966{
967 if (!window) return;
968
969 INF("lowering window");
970
971 if (!SetWindowPos(window->window,
972 HWND_BOTTOM, 0, 0, 0, 0,
973 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
974 {
975 ERR("SetWindowPos() failed");
976 }
977}
978
979/**
980 * @brief Set the title of the given window.
981 *
982 * @param window The window to set the title.
983 * @param title The new title.
984 *
985 * This function sets the title of @p window to @p title. If @p window
986 * is @c NULL, or if @p title is @c NULL or empty, or on error, this
987 * function does nothing.
988 */
989EAPI void
990ecore_win32_window_title_set(Ecore_Win32_Window *window,
991 const char *title)
992{
993 if (!window) return;
994
995 if (!title || !title[0]) return;
996
997 INF("setting window title");
998
999 if (!SetWindowText(window->window, title))
1000 {
1001 ERR("SetWindowText() failed");
1002 }
1003}
1004
1005/**
1006 * @brief Set the focus to the given window.
1007 *
1008 * @param window The window to give focus to.
1009 *
1010 * This function gives the focus to @p window. If @p window is
1011 * @c NULL, this function does nothing.
1012 */
1013EAPI void
1014ecore_win32_window_focus_set(Ecore_Win32_Window *window)
1015{
1016 if (!window) return;
1017
1018 INF("focusing window");
1019
1020 if (!SetFocus(window->window))
1021 {
1022 ERR("SetFocus() failed");
1023 }
1024}
1025
1026/**
1027 * @brief Iconify or restore the given window.
1028 *
1029 * @param window The window.
1030 * @param on EINA_TRUE to iconify the window, EINA_FALSE to restore it.
1031 *
1032 * This function iconify or restore @p window. If @p on
1033 * is set to EINA_TRUE, the window will be iconified, if it is set to
1034 * EINA_FALSE, it will be restored. If @p window is @c NULL or if the
1035 * state does not change (like iconifying the window while it is
1036 * already iconified), this function does nothing.
1037 */
1038EAPI void
1039ecore_win32_window_iconified_set(Ecore_Win32_Window *window,
1040 Eina_Bool on)
1041{
1042 if (!window) return;
1043
1044 if (((window->iconified) && (on)) ||
1045 ((!window->iconified) && (!on)))
1046 return;
1047
1048 INF("iconifying window: %s", on ? "yes" : "no");
1049
1050 ShowWindow(window->window, on ? SW_MINIMIZE : SW_RESTORE);
1051 window->iconified = on;
1052}
1053
1054/**
1055 * @brief Remove or restore the border of the given window.
1056 *
1057 * @param window The window.
1058 * @param on EINA_TRUE to remove the border, EINA_FALSE to restore it.
1059 *
1060 * This function remove or restore the border of @p window. If @p on
1061 * is set to EINA_TRUE, the window will have no border, if it is set to
1062 * EINA_FALSE, it will have a border. If @p window is @c NULL or if the
1063 * state does not change (like setting to borderless while the window
1064 * has no border), this function does nothing.
1065 */
1066EAPI void
1067ecore_win32_window_borderless_set(Ecore_Win32_Window *window,
1068 Eina_Bool on)
1069{
1070 RECT rect;
1071 DWORD style;
1072
1073 if (!window) return;
1074
1075 if (((window->borderless) && (on)) ||
1076 ((!window->borderless) && (!on)))
1077 return;
1078
1079 INF("setting window without border: %s", on ? "yes" : "no");
1080
1081 style = GetWindowLong(window->window, GWL_STYLE);
1082 if (on)
1083 {
1084 if (!GetClientRect(window->window, &rect))
1085 {
1086 ERR("GetClientRect() failed");
1087 return;
1088 }
1089 SetLastError(0);
1090 if (!SetWindowLongPtr(window->window, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME)) &&
1091 (GetLastError() != 0))
1092 {
1093 ERR("SetWindowLongPtr() failed");
1094 return;
1095 }
1096 }
1097 else
1098 {
1099 if (!GetWindowRect(window->window, &rect))
1100 {
1101 ERR("GetWindowRect() failed");
1102 return;
1103 }
1104 style |= WS_CAPTION | WS_THICKFRAME;
1105 if (!AdjustWindowRect (&rect, style, FALSE))
1106 {
1107 ERR("AdjustWindowRect() failed");
1108 return;
1109 }
1110 SetLastError(0);
1111 if (!SetWindowLongPtr(window->window, GWL_STYLE, style) &&
1112 (GetLastError() != 0))
1113 {
1114 ERR("SetWindowLongPtr() failed");
1115 return;
1116 }
1117 }
1118 if (!SetWindowPos(window->window, HWND_TOPMOST,
1119 rect.left, rect.top,
1120 rect.right - rect.left, rect.bottom - rect.top,
1121 SWP_NOMOVE | SWP_FRAMECHANGED))
1122 {
1123 ERR("SetWindowPos() failed");
1124 return;
1125 }
1126
1127 window->borderless = on;
1128}
1129
1130/**
1131 * @brief Set the given window to fullscreen.
1132 *
1133 * @param window The window.
1134 * @param on EINA_TRUE for fullscreen mode, EINA_FALSE for windowed mode.
1135 *
1136 * This function set @p window to fullscreen or windowed mode. If @p on
1137 * is set to EINA_TRUE, the window will be fullscreen, if it is set to
1138 * EINA_FALSE, it will be windowed. If @p window is @c NULL or if the
1139 * state does not change (like setting to fullscreen while the window
1140 * is already fullscreen), this function does nothing.
1141 */
1142EAPI void
1143ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window,
1144 Eina_Bool on)
1145{
1146 if (!window) return;
1147
1148 if (((window->fullscreen) && (on)) ||
1149 ((!window->fullscreen) && (!on)))
1150 return;
1151
1152 INF("setting fullscreen: %s", on ? "yes" : "no");
1153
1154 window->fullscreen = !!on;
1155
1156 if (on)
1157 {
1158 DWORD style;
1159
1160 if (!GetWindowRect(window->window, &window->rect))
1161 {
1162 ERR("GetWindowRect() failed");
1163 return;
1164 }
1165 if (!(window->style = GetWindowLong(window->window, GWL_STYLE)))
1166 {
1167 ERR("GetWindowLong() failed");
1168 return;
1169 }
1170 style = window->style & ~WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX;
1171 style |= WS_VISIBLE | WS_POPUP;
1172 SetLastError(0);
1173 if (!SetWindowLongPtr(window->window, GWL_STYLE, style) &&
1174 (GetLastError() != 0))
1175 {
1176 ERR("SetWindowLongPtr() failed");
1177 return;
1178 }
1179 SetLastError(0);
1180 if (!SetWindowLongPtr(window->window, GWL_EXSTYLE, WS_EX_TOPMOST) &&
1181 (GetLastError() != 0))
1182 {
1183 ERR("SetWindowLongPtr() failed");
1184 return;
1185 }
1186 if (!SetWindowPos(window->window, HWND_TOPMOST, 0, 0,
1187 GetSystemMetrics (SM_CXSCREEN),
1188 GetSystemMetrics (SM_CYSCREEN),
1189 SWP_NOCOPYBITS | SWP_SHOWWINDOW))
1190 {
1191 ERR("SetWindowPos() failed");
1192 return;
1193 }
1194 }
1195 else
1196 {
1197 SetLastError(0);
1198 if (!SetWindowLongPtr(window->window, GWL_STYLE, window->style) &&
1199 (GetLastError() != 0))
1200 {
1201 ERR("SetWindowLongPtr() failed");
1202 return;
1203 }
1204 SetLastError(0);
1205 if (!SetWindowLongPtr(window->window, GWL_EXSTYLE, 0) &&
1206 (GetLastError() != 0))
1207 {
1208 ERR("SetWindowLongPtr() failed");
1209 return;
1210 }
1211 if (!SetWindowPos(window->window, HWND_NOTOPMOST,
1212 window->rect.left,
1213 window->rect.top,
1214 window->rect.right - window->rect.left,
1215 window->rect.bottom - window->rect.top,
1216 SWP_NOCOPYBITS | SWP_SHOWWINDOW))
1217 {
1218 ERR("SetWindowPos() failed");
1219 return;
1220 }
1221 }
1222}
1223
1224/**
1225 * @brief Set the given cursor to the given window.
1226 *
1227 * @param window The window to modify the cursor.
1228 * @param cursor The new cursor.
1229 *
1230 * This function sets @p cursor to @p window. @p cursor must have been
1231 * obtained by ecore_win32_cursor_new() or
1232 * ecore_win32_cursor_shaped_new(). If @p window or @p cursor is
1233 * @c NULL, the function does nothing.
1234 */
1235EAPI void
1236ecore_win32_window_cursor_set(Ecore_Win32_Window *window,
1237 Ecore_Win32_Cursor *cursor)
1238{
1239 INF("setting cursor");
1240
1241 if (!window || !cursor)
1242 return;
1243
1244 if (!SetClassLongPtr(window->window,
1245 GCLP_HCURSOR, (LONG_PTR)cursor))
1246 {
1247 ERR("SetClassLong() failed");
1248 }
1249}
1250
1251/**
1252 * @brief Set the state of the given window.
1253 *
1254 * @param window The window to modify the state.
1255 * @param state An array of the new states.
1256 * @param num The number of states in the array.
1257 *
1258 * This function set the state of @p window. @p state is an array of
1259 * states of size @p num. If @p window or @p state are @c NULL, or if
1260 * @p num is less or equal than 0, the function does nothing.
1261 */
1262EAPI void
1263ecore_win32_window_state_set(Ecore_Win32_Window *window,
1264 Ecore_Win32_Window_State *state,
1265 unsigned int num)
1266{
1267 unsigned int i;
1268
1269 if (!window || !state || (num <= 0))
1270 return;
1271
1272 INF("setting cursor state");
1273
1274 for (i = 0; i < num; i++)
1275 {
1276 switch (state[i])
1277 {
1278 case ECORE_WIN32_WINDOW_STATE_ICONIFIED:
1279 window->state.iconified = 1;
1280 break;
1281 case ECORE_WIN32_WINDOW_STATE_MODAL:
1282 window->state.modal = 1;
1283 break;
1284 case ECORE_WIN32_WINDOW_STATE_STICKY:
1285 window->state.sticky = 1;
1286 break;
1287 case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT:
1288 window->state.maximized_vert = 1;
1289 break;
1290 case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ:
1291 window->state.maximized_horz = 1;
1292 break;
1293 case ECORE_WIN32_WINDOW_STATE_MAXIMIZED:
1294 window->state.maximized_horz = 1;
1295 window->state.maximized_vert = 1;
1296 break;
1297 case ECORE_WIN32_WINDOW_STATE_SHADED:
1298 window->state.shaded = 1;
1299 break;
1300 case ECORE_WIN32_WINDOW_STATE_HIDDEN:
1301 window->state.hidden = 1;
1302 break;
1303 case ECORE_WIN32_WINDOW_STATE_FULLSCREEN:
1304 window->state.fullscreen = 1;
1305 break;
1306 case ECORE_WIN32_WINDOW_STATE_ABOVE:
1307 window->state.above = 1;
1308 break;
1309 case ECORE_WIN32_WINDOW_STATE_BELOW:
1310 window->state.below = 1;
1311 break;
1312 case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION:
1313 window->state.demands_attention = 1;
1314 break;
1315 case ECORE_WIN32_WINDOW_STATE_UNKNOWN:
1316 /* nothing to be done */
1317 break;
1318 }
1319 }
1320}
1321
1322/**
1323 * @brief Apply the modification of the state to the given window.
1324 *
1325 * @param window The window.
1326 * @param state The state to apply changes.
1327 * @param set The value of the state change.
1328 *
1329 * This function applies the modification of the state @p state of
1330 * @p window. @p set is used only for
1331 * #ECORE_WIN32_WINDOW_STATE_ICONIFIED and
1332 * #ECORE_WIN32_WINDOW_STATE_FULLSCREEN. If @p window is @c NULL, the
1333 * function does nothing.
1334 */
1335EAPI void
1336ecore_win32_window_state_request_send(Ecore_Win32_Window *window,
1337 Ecore_Win32_Window_State state,
1338 unsigned int set)
1339{
1340 if (!window) return;
1341
1342 INF("sending cursor state");
1343
1344 switch (state)
1345 {
1346 case ECORE_WIN32_WINDOW_STATE_ICONIFIED:
1347 if (window->state.iconified)
1348 ecore_win32_window_iconified_set(window, set);
1349 break;
1350 case ECORE_WIN32_WINDOW_STATE_MODAL:
1351 window->state.modal = 1;
1352 break;
1353 case ECORE_WIN32_WINDOW_STATE_STICKY:
1354 window->state.sticky = 1;
1355 break;
1356 case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT:
1357 if (window->state.maximized_vert)
1358 {
1359 RECT rect;
1360 int y;
1361 int height;
1362
1363 if (!SystemParametersInfo(SPI_GETWORKAREA, 0,
1364 &rect, 0))
1365 {
1366 ERR("SystemParametersInfo() failed");
1367 break;
1368 }
1369 y = rect.top;
1370 height = rect.bottom - rect.top;
1371
1372 if (!GetClientRect(window->window, &rect))
1373 {
1374 ERR("GetClientRect() failed");
1375 break;
1376 }
1377
1378 if (!MoveWindow(window->window, rect.left, y,
1379 rect.right - rect.left,
1380 height,
1381 TRUE))
1382 {
1383 ERR("MoveWindow() failed");
1384 }
1385 }
1386 break;
1387 case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ:
1388 if (window->state.maximized_horz)
1389 {
1390 RECT rect;
1391
1392 if (!GetClientRect(window->window, &rect))
1393 {
1394 ERR("GetClientRect() failed");
1395 break;
1396 }
1397
1398 if (!MoveWindow(window->window, 0, rect.top,
1399 GetSystemMetrics(SM_CXSCREEN),
1400 rect.bottom - rect.top,
1401 TRUE))
1402 {
1403 ERR("MoveWindow() failed");
1404 }
1405 }
1406 break;
1407 case ECORE_WIN32_WINDOW_STATE_MAXIMIZED:
1408 if (window->state.maximized_vert && window->state.maximized_horz)
1409 {
1410 RECT rect;
1411
1412 if (!SystemParametersInfo(SPI_GETWORKAREA, 0,
1413 &rect, 0))
1414 {
1415 ERR("SystemParametersInfo() failed");
1416 break;
1417 }
1418
1419 if (!MoveWindow(window->window, 0, 0,
1420 GetSystemMetrics(SM_CXSCREEN),
1421 rect.bottom - rect.top,
1422 TRUE))
1423 {
1424 ERR("MoveWindow() failed");
1425 }
1426 }
1427 break;
1428 case ECORE_WIN32_WINDOW_STATE_SHADED:
1429 window->state.shaded = 1;
1430 break;
1431 case ECORE_WIN32_WINDOW_STATE_HIDDEN:
1432 window->state.hidden = 1;
1433 break;
1434 case ECORE_WIN32_WINDOW_STATE_FULLSCREEN:
1435 if (window->state.fullscreen)
1436 ecore_win32_window_fullscreen_set(window, set);
1437 break;
1438 case ECORE_WIN32_WINDOW_STATE_ABOVE:
1439 if (window->state.above)
1440 if (!SetWindowPos(window->window, HWND_TOP,
1441 0, 0,
1442 0, 0,
1443 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW))
1444 {
1445 ERR("SetWindowPos() failed");
1446 }
1447 break;
1448 case ECORE_WIN32_WINDOW_STATE_BELOW:
1449 if (window->state.below)
1450 if (!SetWindowPos(window->window, HWND_BOTTOM,
1451 0, 0,
1452 0, 0,
1453 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW))
1454 {
1455 ERR("SetWindowPos() failed");
1456 }
1457 break;
1458 case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION:
1459 window->state.demands_attention = 1;
1460 break;
1461 case ECORE_WIN32_WINDOW_STATE_UNKNOWN:
1462 /* nothing to be done */
1463 break;
1464 }
1465}
1466
1467/**
1468 * @brief Set the type of the given window.
1469 *
1470 * @param window The window to modify the type.
1471 * @param type The nwindow types.
1472 *
1473 * This function set the type of @p window to @p type. If
1474 * @p window is @c NULL, the function does nothing.
1475 */
1476EAPI void
1477ecore_win32_window_type_set(Ecore_Win32_Window *window,
1478 Ecore_Win32_Window_Type type)
1479{
1480 if (!window)
1481 return;
1482
1483 INF("setting window type");
1484
1485 switch (type)
1486 {
1487 case ECORE_WIN32_WINDOW_TYPE_DESKTOP:
1488 window->type.desktop = 1;
1489 break;
1490 case ECORE_WIN32_WINDOW_TYPE_DOCK:
1491 window->type.dock = 1;
1492 break;
1493 case ECORE_WIN32_WINDOW_TYPE_TOOLBAR:
1494 window->type.toolbar = 1;
1495 break;
1496 case ECORE_WIN32_WINDOW_TYPE_MENU:
1497 window->type.menu = 1;
1498 break;
1499 case ECORE_WIN32_WINDOW_TYPE_UTILITY:
1500 window->type.utility = 1;
1501 break;
1502 case ECORE_WIN32_WINDOW_TYPE_SPLASH:
1503 window->type.splash = 1;
1504 break;
1505 case ECORE_WIN32_WINDOW_TYPE_DIALOG:
1506 window->type.dialog = 1;
1507 break;
1508 case ECORE_WIN32_WINDOW_TYPE_NORMAL:
1509 window->type.normal = 1;
1510 break;
1511 case ECORE_WIN32_WINDOW_TYPE_UNKNOWN:
1512 window->type.normal = 1;
1513 break;
1514 }
1515}
1516
1517/**
1518 * @}
1519 */