102ea69f8fb768c1cbae8bbc442dcf248c1eb919
[profile/ivi/ecore.git] / src / lib / ecore_win32 / ecore_win32_window.c
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_WINNT 0x0500  // For WS_EX_LAYERED
9
10 #define WIN32_LEAN_AND_MEAN
11 #include <windows.h>
12 #undef WIN32_LEAN_AND_MEAN
13
14 #include <Eina.h>
15
16 #include "Ecore_Win32.h"
17 #include "ecore_win32_private.h"
18
19
20 /***** Private declarations *****/
21
22
23 typedef enum _Ecore_Win32_Window_Z_Order Ecore_Win32_Window_Z_Order;
24 enum _Ecore_Win32_Window_Z_Order
25 {
26   ECORE_WIN32_WINDOW_Z_ORDER_BOTTOM,
27   ECORE_WIN32_WINDOW_Z_ORDER_NOTOPMOST,
28   ECORE_WIN32_WINDOW_Z_ORDER_TOP,
29   ECORE_WIN32_WINDOW_Z_ORDER_TOPMOST
30 };
31
32 static Ecore_Win32_Window *ecore_win32_window_internal_new(Ecore_Win32_Window *parent,
33                                                            int                 x,
34                                                            int                 y,
35                                                            int                 width,
36                                                            int                 height,
37                                                            DWORD               style);
38
39
40 /***** API *****/
41
42 Ecore_Win32_Window *
43 ecore_win32_window_new(Ecore_Win32_Window *parent,
44                        int                 x,
45                        int                 y,
46                        int                 width,
47                        int                 height)
48 {
49    INF("creating window with border");
50
51    return ecore_win32_window_internal_new(parent,
52                                           x, y,
53                                           width, height,
54                                           WS_OVERLAPPEDWINDOW | WS_SIZEBOX);
55 }
56
57 /* simulate X11 override windows */
58 Ecore_Win32_Window *
59 ecore_win32_window_override_new(Ecore_Win32_Window *parent,
60                                 int                 x,
61                                 int                 y,
62                                 int                 width,
63                                 int                 height)
64 {
65    INF("creating window without border");
66
67    return ecore_win32_window_internal_new(parent,
68                                           x, y,
69                                           width, height,
70                                           WS_POPUP);
71 }
72
73 void
74 ecore_win32_window_free(Ecore_Win32_Window *window)
75 {
76    struct _Ecore_Win32_Window *wnd = window;
77
78    if (!window) return;
79
80    INF("destroying window");
81
82    if (wnd->shape.mask)
83       free(wnd->shape.mask);
84
85    DestroyWindow(((struct _Ecore_Win32_Window *)window)->window);
86    free(window);
87 }
88
89 void *
90 ecore_win32_window_hwnd_get(Ecore_Win32_Window *window)
91 {
92    if (!window) return NULL;
93
94    return ((struct _Ecore_Win32_Window *)window)->window;
95 }
96
97 /*
98 void
99 ecore_win32_window_configure(Ecore_Win32_Window        *window,
100                              Ecore_Win32_Window_Z_Order order,
101                              int                        x,
102                              int                        y,
103                              int                        width,
104                              int                        height)
105 {
106   HWND w;
107
108   switch (order)
109     {
110     case ECORE_WIN32_WINDOW_Z_ORDER_BOTTOM:
111       w = HWND_BOTTOM;
112       break;
113     case ECORE_WIN32_WINDOW_Z_ORDER_NOTOPMOST:
114       w = HWND_NOTOPMOST;
115       break;
116     case ECORE_WIN32_WINDOW_Z_ORDER_TOP:
117       w = HWND_TOP;
118       break;
119     case ECORE_WIN32_WINDOW_Z_ORDER_TOPMOST:
120       w = HWND_TOPMOST;
121       break;
122     default:
123       return;
124     }
125   SetWindowPos((struct _Ecore_Win32_Window *)window->window, w, x, y, width, height, ???);
126 }
127 */
128
129 void
130 ecore_win32_window_move(Ecore_Win32_Window *window,
131                         int                 x,
132                         int                 y)
133 {
134    RECT rect;
135    HWND w;
136
137    if (!window) return;
138
139    INF("moving window (%dx%d)", x, y);
140
141    w = ((struct _Ecore_Win32_Window *)window)->window;
142    if (!GetWindowRect(w, &rect))
143      {
144         ERR("GetWindowRect() failed");
145         return;
146      }
147
148    if (!MoveWindow(w, x, y,
149                    rect.right - rect.left,
150                    rect.bottom - rect.top,
151                    TRUE))
152      {
153         ERR("MoveWindow() failed");
154      }
155 }
156
157 void
158 ecore_win32_window_resize(Ecore_Win32_Window *window,
159                           int                 width,
160                           int                 height)
161 {
162    RECT                        rect;
163    struct _Ecore_Win32_Window *w;
164    DWORD                       style;
165    int                         x;
166    int                         y;
167
168    if (!window) return;
169
170    INF("resizing window (%dx%d)", width, height);
171
172    w = (struct _Ecore_Win32_Window *)window;
173    if (!GetWindowRect(w->window, &rect))
174      {
175         ERR("GetWindowRect() failed");
176         return;
177      }
178
179    x = rect.left;
180    y = rect.top;
181    rect.left = 0;
182    rect.top = 0;
183 /*    if (width < w->min_width) width = w->min_width; */
184 /*    if (width > w->max_width) width = w->max_width; */
185 /*    printf ("ecore_win32_window_resize 1 : %d %d %d\n", w->min_height, w->max_height, height); */
186 /*    if (height < w->min_height) height = w->min_height; */
187 /*    printf ("ecore_win32_window_resize 2 : %d %d\n", w->max_height, height); */
188 /*    if (height > w->max_height) height = w->max_height; */
189 /*    printf ("ecore_win32_window_resize 3 : %d %d\n", w->max_height, height); */
190    rect.right = width;
191    rect.bottom = height;
192    if (!(style = GetWindowLong(w->window, GWL_STYLE)))
193      {
194         ERR("GetWindowLong() failed");
195         return;
196      }
197    if (!AdjustWindowRect(&rect, style, FALSE))
198      {
199         ERR("AdjustWindowRect() failed");
200         return;
201      }
202
203    if (!MoveWindow(w->window, x, y,
204                    rect.right - rect.left,
205                    rect.bottom - rect.top,
206                    TRUE))
207      {
208         ERR("MoveWindow() failed");
209      }
210 }
211
212 void
213 ecore_win32_window_move_resize(Ecore_Win32_Window *window,
214                                int                 x,
215                                int                 y,
216                                int                 width,
217                                int                 height)
218 {
219    RECT                        rect;
220    struct _Ecore_Win32_Window *w;
221    DWORD                       style;
222
223    if (!window) return;
224
225    INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height);
226
227    w = ((struct _Ecore_Win32_Window *)window);
228    rect.left = 0;
229    rect.top = 0;
230    if ((unsigned int)width < w->min_width) width = w->min_width;
231    if ((unsigned int)width > w->max_width) width = w->max_width;
232    if ((unsigned int)height < w->min_height) height = w->min_height;
233    if ((unsigned int)height > w->max_height) height = w->max_height;
234    rect.right = width;
235    rect.bottom = height;
236    if (!(style = GetWindowLong(w->window, GWL_STYLE)))
237      {
238         ERR("GetWindowLong() failed");
239         return;
240      }
241    if (!AdjustWindowRect(&rect, style, FALSE))
242      {
243         ERR("AdjustWindowRect() failed");
244         return;
245      }
246
247    if (!MoveWindow(w->window, x, y,
248                    rect.right - rect.left,
249                    rect.bottom - rect.top,
250                    TRUE))
251      {
252         ERR("MoveWindow() failed");
253      }
254 }
255
256 void
257 ecore_win32_window_geometry_get(Ecore_Win32_Window *window,
258                                 int                *x,
259                                 int                *y,
260                                 int                *width,
261                                 int                *height)
262 {
263    RECT rect;
264    int  w;
265    int  h;
266
267    INF("getting window geometry");
268
269    if (!window)
270      {
271         if (x) *x = 0;
272         if (y) *y = 0;
273         if (width) *width = GetSystemMetrics(SM_CXSCREEN);
274         if (height) *height = GetSystemMetrics(SM_CYSCREEN);
275
276         return;
277      }
278
279    if (!GetClientRect(((struct _Ecore_Win32_Window *)window)->window,
280                       &rect))
281      {
282         ERR("GetClientRect() failed");
283
284         if (x) *x = 0;
285         if (y) *y = 0;
286         if (width) *width = 0;
287         if (height) *height = 0;
288
289         return;
290      }
291
292    w = rect.right - rect.left;
293    h = rect.bottom - rect.top;
294
295    if (!GetWindowRect(((struct _Ecore_Win32_Window *)window)->window,
296                       &rect))
297      {
298         ERR("GetWindowRect() failed");
299
300         if (x) *x = 0;
301         if (y) *y = 0;
302         if (width) *width = 0;
303         if (height) *height = 0;
304
305         return;
306      }
307
308    if (x) *x = rect.left;
309    if (y) *y = rect.top;
310    if (width) *width = w;
311    if (height) *height = h;
312 }
313
314 void
315 ecore_win32_window_size_get(Ecore_Win32_Window *window,
316                             int                *width,
317                             int                *height)
318 {
319    RECT rect;
320
321    INF("getting window size");
322
323    if (!window)
324      {
325         if (width) *width = GetSystemMetrics(SM_CXSCREEN);
326         if (height) *height = GetSystemMetrics(SM_CYSCREEN);
327
328         return;
329      }
330
331    if (!GetClientRect(((struct _Ecore_Win32_Window *)window)->window,
332                       &rect))
333      {
334         ERR("GetClientRect() failed");
335
336         if (width) *width = 0;
337         if (height) *height = 0;
338      }
339
340    if (width) *width = rect.right - rect.left;
341    if (height) *height = rect.bottom - rect.top;
342 }
343
344 void
345 ecore_win32_window_size_min_set(Ecore_Win32_Window *window,
346                                 unsigned int        min_width,
347                                 unsigned int        min_height)
348 {
349    struct _Ecore_Win32_Window *w;
350
351    if (!window) return;
352
353    printf ("ecore_win32_window_size_min_set : %p  %d %d\n", window, min_width, min_height);
354    w = (struct _Ecore_Win32_Window *)window;
355    w->min_width = min_width;
356    w->min_height = min_height;
357 }
358
359 void
360 ecore_win32_window_size_min_get(Ecore_Win32_Window *window,
361                                 unsigned int       *min_width,
362                                 unsigned int       *min_height)
363 {
364    struct _Ecore_Win32_Window *w;
365
366    if (!window) return;
367
368    w = (struct _Ecore_Win32_Window *)window;
369    printf ("ecore_win32_window_size_min_get : %p  %d %d\n", window, w->min_width, w->min_height);
370    if (min_width) *min_width = w->min_width;
371    if (min_height) *min_height = w->min_height;
372 }
373
374 void
375 ecore_win32_window_size_max_set(Ecore_Win32_Window *window,
376                                 unsigned int        max_width,
377                                 unsigned int        max_height)
378 {
379    struct _Ecore_Win32_Window *w;
380
381    if (!window) return;
382
383    printf ("ecore_win32_window_size_max_set : %p  %d %d\n", window, max_width, max_height);
384    w = (struct _Ecore_Win32_Window *)window;
385    w->max_width = max_width;
386    w->max_height = max_height;
387 }
388
389 void
390 ecore_win32_window_size_max_get(Ecore_Win32_Window *window,
391                                 unsigned int       *max_width,
392                                 unsigned int       *max_height)
393 {
394    struct _Ecore_Win32_Window *w;
395
396    if (!window) return;
397
398    w = (struct _Ecore_Win32_Window *)window;
399    printf ("ecore_win32_window_size_max_get : %p  %d %d\n", window, w->max_width, w->max_height);
400    if (max_width) *max_width = w->max_width;
401    if (max_height) *max_height = w->max_height;
402 }
403
404 void
405 ecore_win32_window_size_base_set(Ecore_Win32_Window *window,
406                                  unsigned int        base_width,
407                                  unsigned int        base_height)
408 {
409    struct _Ecore_Win32_Window *w;
410
411    printf ("ecore_win32_window_size_base_set : %p  %d %d\n", window, base_width, base_height);
412    if (!window) return;
413
414    w = (struct _Ecore_Win32_Window *)window;
415    w->base_width = base_width;
416    w->base_height = base_height;
417 }
418
419 void
420 ecore_win32_window_size_base_get(Ecore_Win32_Window *window,
421                                  unsigned int       *base_width,
422                                  unsigned int       *base_height)
423 {
424    struct _Ecore_Win32_Window *w;
425
426    if (!window) return;
427
428    w = (struct _Ecore_Win32_Window *)window;
429    printf ("ecore_win32_window_size_base_get : %p  %d %d\n", window, w->base_width, w->base_height);
430    if (base_width) *base_width = w->base_width;
431    if (base_height) *base_height = w->base_height;
432 }
433
434 void
435 ecore_win32_window_size_step_set(Ecore_Win32_Window *window,
436                                  unsigned int        step_width,
437                                  unsigned int        step_height)
438 {
439    struct _Ecore_Win32_Window *w;
440
441    printf ("ecore_win32_window_size_step_set : %p  %d %d\n", window, step_width, step_height);
442    if (!window) return;
443
444    w = (struct _Ecore_Win32_Window *)window;
445    w->step_width = step_width;
446    w->step_height = step_height;
447 }
448
449 void
450 ecore_win32_window_size_step_get(Ecore_Win32_Window *window,
451                                  unsigned int       *step_width,
452                                  unsigned int       *step_height)
453 {
454    struct _Ecore_Win32_Window *w;
455
456    if (!window) return;
457
458    w = (struct _Ecore_Win32_Window *)window;
459    printf ("ecore_win32_window_size_step_get : %p  %d %d\n", window, w->step_width, w->step_height);
460    if (step_width) *step_width = w->step_width;
461    if (step_height) *step_height = w->step_height;
462 }
463
464 void
465 ecore_win32_window_shape_set(Ecore_Win32_Window *window,
466                              unsigned short      width,
467                              unsigned short      height,
468                              unsigned char      *mask)
469 {
470    struct _Ecore_Win32_Window *wnd;
471    HRGN                        rgn;
472    int                         x;
473    int                         y;
474    OSVERSIONINFO               version_info;
475
476    if (!window)
477       return;
478
479    wnd = (struct _Ecore_Win32_Window *)window;
480
481    if (!mask)
482      {
483         wnd->shape.enabled = 0;
484         if (wnd->shape.layered != 0)
485           {
486              wnd->shape.layered = 0;
487 #if defined(WS_EX_LAYERED)
488              SetLastError(0);
489              if (!SetWindowLongPtr(wnd->window, GWL_EXSTYLE,
490                                    GetWindowLong(wnd->window, GWL_EXSTYLE) & (~WS_EX_LAYERED)) &&
491                  (GetLastError() != 0))
492                {
493                   ERR("SetWindowLongPtr() failed");
494                   return;
495                }
496              if (!RedrawWindow(wnd->window, NULL, NULL,
497                                RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN))
498                {
499                   ERR("RedrawWindow() failed");
500                   return;
501                }
502 #endif
503           }
504         else
505           if (!SetWindowRgn(wnd->window, NULL, TRUE))
506             {
507                ERR("SetWindowRgn() failed");
508             }
509         return;
510      }
511
512    if (width == 0 || height == 0)
513      return;
514
515    wnd->shape.enabled = 1;
516
517    if (width != wnd->shape.width || height != wnd->shape.height)
518      {
519        wnd->shape.width = width;
520        wnd->shape.height = height;
521        if (wnd->shape.mask)
522          {
523            free(wnd->shape.mask);
524            wnd->shape.mask = NULL;
525          }
526        wnd->shape.mask = malloc(width * height);
527      }
528    memcpy(wnd->shape.mask, mask, width * height);
529
530    wnd->shape.layered = 0;
531
532 #if defined(WS_EX_LAYERED)
533    version_info.dwOSVersionInfoSize = sizeof(version_info);
534    if (GetVersionEx(&version_info) == TRUE && version_info.dwMajorVersion == 5)
535      {
536        SetLastError(0);
537        if (!SetWindowLongPtr(wnd->window, GWL_EXSTYLE,
538                              GetWindowLong(wnd->window, GWL_EXSTYLE) | WS_EX_LAYERED) &&
539            (GetLastError() != 0))
540             {
541                ERR("SetWindowLongPtr() failed");
542                return;
543             }
544        wnd->shape.layered = 1;
545        return;
546      }
547 #endif
548
549    if (!(rgn = CreateRectRgn(0, 0, 0, 0)))
550      {
551         ERR("CreateRectRgn() failed");
552         return;
553      }
554    for (y = 0; y < height; y++)
555      {
556         HRGN rgnLine;
557
558         if (!(rgnLine = CreateRectRgn(0, 0, 0, 0)))
559           {
560              ERR("CreateRectRgn() failed");
561              return;
562           }
563         for (x = 0; x < width; x++)
564           {
565              if (mask[y * width + x] > 0)
566                {
567                   HRGN rgnDot;
568
569                   if (!(rgnDot = CreateRectRgn(x, y, x + 1, y + 1)))
570                     {
571                        ERR("CreateRectRgn() failed");
572                        return;
573                     }
574                   if (CombineRgn(rgnLine, rgnLine, rgnDot, RGN_OR) == ERROR)
575                     {
576                        ERR("CombineRgn() has not created a new region");
577                     }
578                   if (!DeleteObject(rgnDot))
579                     {
580                        ERR("DeleteObject() failed");
581                        return;
582                     }
583                }
584           }
585         if (CombineRgn(rgn, rgn, rgnLine, RGN_OR) == ERROR)
586           {
587              ERR("CombineRgn() has not created a new region");
588           }
589         if (!DeleteObject(rgnLine))
590           {
591              ERR("DeleteObject() failed");
592              return;
593           }
594      }
595    if (!SetWindowRgn(wnd->window, rgn, TRUE))
596      {
597         ERR("SetWindowRgn() failed");
598      }
599 }
600
601 void
602 ecore_win32_window_show(Ecore_Win32_Window *window)
603 {
604    if (!window) return;
605
606    INF("showing window");
607
608    ShowWindow(((struct _Ecore_Win32_Window *)window)->window, SW_SHOWNORMAL);
609    if (!UpdateWindow(((struct _Ecore_Win32_Window *)window)->window))
610      {
611         ERR("UpdateWindow() failed");
612      }
613 }
614
615 /* FIXME: seems to block the taskbar */
616 void
617 ecore_win32_window_hide(Ecore_Win32_Window *window)
618 {
619    if (!window) return;
620
621    INF("hiding window");
622
623    ShowWindow(((struct _Ecore_Win32_Window *)window)->window, SW_HIDE);
624 }
625
626 void
627 ecore_win32_window_raise(Ecore_Win32_Window *window)
628 {
629    if (!window) return;
630
631    INF("raising window");
632
633    if (!SetWindowPos(((struct _Ecore_Win32_Window *)window)->window,
634                      HWND_TOP, 0, 0, 0, 0,
635                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
636      {
637         ERR("SetWindowPos() failed");
638      }
639 }
640
641 void
642 ecore_win32_window_lower(Ecore_Win32_Window *window)
643 {
644    if (!window) return;
645
646    INF("lowering window");
647
648    if (!SetWindowPos(((struct _Ecore_Win32_Window *)window)->window,
649                      HWND_BOTTOM, 0, 0, 0, 0,
650                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
651      {
652         ERR("SetWindowPos() failed");
653      }
654 }
655
656 void
657 ecore_win32_window_title_set(Ecore_Win32_Window *window,
658                              const char         *title)
659 {
660    if (!window) return;
661
662    if (!title || !title[0]) return;
663
664    INF("setting window title");
665
666    if (!SetWindowText(((struct _Ecore_Win32_Window *)window)->window, title))
667      {
668         ERR("SetWindowText() failed");
669      }
670 }
671
672 void
673 ecore_win32_window_focus_set(Ecore_Win32_Window *window)
674 {
675    if (!window) return;
676
677    INF("focusing window");
678
679    if (!SetFocus(((struct _Ecore_Win32_Window *)window)->window))
680      {
681         ERR("SetFocus() failed");
682      }
683 }
684
685 void
686 ecore_win32_window_iconified_set(Ecore_Win32_Window *window,
687                                  int                 on)
688 {
689    struct _Ecore_Win32_Window *ew;
690
691    if (!window) return;
692
693    ew = (struct _Ecore_Win32_Window *)window;
694    if (((ew->iconified) && (on)) ||
695        ((!ew->iconified) && (!on)))
696      return;
697
698    INF("iconifying window: %s", on ? "yes" : "no");
699
700    ShowWindow(ew->window, on ? SW_MINIMIZE : SW_RESTORE);
701    ew->iconified = on;
702 }
703
704 void
705 ecore_win32_window_borderless_set(Ecore_Win32_Window *window,
706                                   int                 on)
707 {
708    RECT                        rect;
709    DWORD                       style;
710    struct _Ecore_Win32_Window *ew;
711    HWND                        w;
712
713    if (!window) return;
714
715    ew = (struct _Ecore_Win32_Window *)window;
716    if (((ew->borderless) && (on)) ||
717        ((!ew->borderless) && (!on)))
718      return;
719
720    INF("setting window without border: %s", on ? "yes" : "no");
721
722    w = ew->window;
723
724    style = GetWindowLong(w, GWL_STYLE);
725    if (on)
726      {
727         if (!GetClientRect(w, &rect))
728           {
729              ERR("GetClientRect() failed");
730              return;
731           }
732         SetLastError(0);
733         if (!SetWindowLongPtr(w, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME)) && (GetLastError() != 0))
734           {
735              ERR("SetWindowLongPtr() failed");
736              return;
737           }
738      }
739    else
740      {
741         if (!GetWindowRect(w, &rect))
742           {
743              ERR("GetWindowRect() failed");
744              return;
745           }
746         style |= WS_CAPTION | WS_THICKFRAME;
747         if (!AdjustWindowRect (&rect, style, FALSE))
748           {
749              ERR("AdjustWindowRect() failed");
750              return;
751           }
752         SetLastError(0);
753         if (!SetWindowLongPtr(w, GWL_STYLE, style) && (GetLastError() != 0))
754           {
755              ERR("SetWindowLongPtr() failed");
756              return;
757           }
758      }
759    if (!SetWindowPos(w, HWND_TOPMOST,
760                      rect.left, rect.top,
761                      rect.right - rect.left, rect.bottom - rect.top,
762                      SWP_NOMOVE | SWP_FRAMECHANGED))
763      {
764         ERR("SetWindowPos() failed");
765         return;
766      }
767    ew->borderless = on;
768 }
769
770 void
771 ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window,
772                                   int                 on)
773 {
774    struct _Ecore_Win32_Window *ew;
775    HWND                        w;
776
777    if (!window) return;
778
779    ew = (struct _Ecore_Win32_Window *)window;
780    if (((ew->fullscreen) && (on)) ||
781        ((!ew->fullscreen) && (!on)))
782      return;
783
784    INF("setting fullscreen: %s", on ? "yes" : "no");
785
786    ew->fullscreen = !!on;
787    w = ew->window;
788
789    if (on)
790      {
791         DWORD style;
792
793         if (!GetWindowRect(w, &ew->rect))
794           {
795              ERR("GetWindowRect() failed");
796              return;
797           }
798         if (!(ew->style = GetWindowLong(w, GWL_STYLE)))
799           {
800              ERR("GetWindowLong() failed");
801              return;
802           }
803         style = ew->style & ~WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX;
804         style |= WS_VISIBLE | WS_POPUP;
805         SetLastError(0);
806         if (!SetWindowLongPtr(w, GWL_STYLE, style) && (GetLastError() != 0))
807           {
808              ERR("SetWindowLongPtr() failed");
809              return;
810           }
811         SetLastError(0);
812         if (!SetWindowLongPtr(w, GWL_EXSTYLE, WS_EX_TOPMOST) && (GetLastError() != 0))
813           {
814              ERR("SetWindowLongPtr() failed");
815              return;
816           }
817         if (!SetWindowPos(w, HWND_TOPMOST, 0, 0,
818                           GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN),
819                           SWP_NOCOPYBITS | SWP_SHOWWINDOW))
820           {
821              ERR("SetWindowPos() failed");
822              return;
823           }
824      }
825    else
826      {
827         SetLastError(0);
828         if (!SetWindowLongPtr(w, GWL_STYLE, ew->style) && (GetLastError() != 0))
829           {
830              ERR("SetWindowLongPtr() failed");
831              return;
832           }
833         SetLastError(0);
834         if (!SetWindowLongPtr(w, GWL_EXSTYLE, 0) && (GetLastError() != 0))
835           {
836              ERR("SetWindowLongPtr() failed");
837              return;
838           }
839         if (!SetWindowPos(w, HWND_NOTOPMOST,
840                           ew->rect.left,
841                           ew->rect.top,
842                           ew->rect.right - ew->rect.left,
843                           ew->rect.bottom - ew->rect.top,
844                           SWP_NOCOPYBITS | SWP_SHOWWINDOW))
845           {
846              ERR("SetWindowPos() failed");
847              return;
848           }
849      }
850 }
851
852 void
853 ecore_win32_window_cursor_set(Ecore_Win32_Window *window,
854                               Ecore_Win32_Cursor *cursor)
855 {
856    INF("setting cursor");
857
858    if (!SetClassLong(((struct _Ecore_Win32_Window *)window)->window,
859                      GCL_HCURSOR, (LONG)cursor))
860      {
861         ERR("SetClassLong() failed");
862      }
863 }
864
865 void
866 ecore_win32_window_state_set(Ecore_Win32_Window       *window,
867                              Ecore_Win32_Window_State *state,
868                              unsigned int              num)
869 {
870    unsigned int i;
871
872    if (!window || !state || !num)
873      return;
874
875    INF("setting cursor state");
876
877    for (i = 0; i < num; i++)
878      {
879         switch (state[i])
880           {
881           case ECORE_WIN32_WINDOW_STATE_ICONIFIED:
882             ((struct _Ecore_Win32_Window *)window)->state.iconified = 1;
883             break;
884           case ECORE_WIN32_WINDOW_STATE_MODAL:
885             ((struct _Ecore_Win32_Window *)window)->state.modal = 1;
886             break;
887           case ECORE_WIN32_WINDOW_STATE_STICKY:
888             ((struct _Ecore_Win32_Window *)window)->state.sticky = 1;
889             break;
890           case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT:
891             ((struct _Ecore_Win32_Window *)window)->state.maximized_vert = 1;
892             break;
893           case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ:
894             ((struct _Ecore_Win32_Window *)window)->state.maximized_horz = 1;
895             break;
896           case ECORE_WIN32_WINDOW_STATE_MAXIMIZED:
897             ((struct _Ecore_Win32_Window *)window)->state.maximized_horz = 1;
898             ((struct _Ecore_Win32_Window *)window)->state.maximized_vert = 1;
899             break;
900           case ECORE_WIN32_WINDOW_STATE_SHADED:
901             ((struct _Ecore_Win32_Window *)window)->state.shaded = 1;
902             break;
903           case ECORE_WIN32_WINDOW_STATE_HIDDEN:
904             ((struct _Ecore_Win32_Window *)window)->state.hidden = 1;
905             break;
906           case ECORE_WIN32_WINDOW_STATE_FULLSCREEN:
907             ((struct _Ecore_Win32_Window *)window)->state.fullscreen = 1;
908             break;
909           case ECORE_WIN32_WINDOW_STATE_ABOVE:
910             ((struct _Ecore_Win32_Window *)window)->state.above = 1;
911             break;
912           case ECORE_WIN32_WINDOW_STATE_BELOW:
913             ((struct _Ecore_Win32_Window *)window)->state.below = 1;
914             break;
915           case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION:
916             ((struct _Ecore_Win32_Window *)window)->state.demands_attention = 1;
917             break;
918           case ECORE_WIN32_WINDOW_STATE_UNKNOWN:
919             /* nothing to be done */
920             break;
921           }
922      }
923 }
924
925 void
926 ecore_win32_window_state_request_send(Ecore_Win32_Window      *window,
927                                       Ecore_Win32_Window_State state,
928                                       unsigned int             set)
929 {
930    struct _Ecore_Win32_Window *ew;
931    HWND                        w;
932
933    if (!window) return;
934
935    ew = (struct _Ecore_Win32_Window *)window;
936    w = ew->window;
937
938    INF("sending cursor state");
939
940    switch (state)
941      {
942       case ECORE_WIN32_WINDOW_STATE_ICONIFIED:
943          if (ew->state.iconified)
944            ecore_win32_window_iconified_set(window, set);
945          break;
946       case ECORE_WIN32_WINDOW_STATE_MODAL:
947          ew->state.modal = 1;
948          break;
949       case ECORE_WIN32_WINDOW_STATE_STICKY:
950          ew->state.sticky = 1;
951          break;
952       case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT:
953          if (ew->state.maximized_vert)
954            {
955               RECT rect;
956               int  y;
957               int  height;
958
959               if (!SystemParametersInfo(SPI_GETWORKAREA, 0,
960                                         &rect, 0))
961                 {
962                    ERR("SystemParametersInfo() failed");
963                    break;
964                 }
965               y = rect.top;
966               height = rect.bottom - rect.top;
967
968               if (!GetClientRect(w, &rect))
969                 {
970                    ERR("GetClientRect() failed");
971                    break;
972                 }
973
974               if (!MoveWindow(w, rect.left, y,
975                               rect.right - rect.left,
976                               height,
977                               TRUE))
978                 {
979                    ERR("MoveWindow() failed");
980                 }
981            }
982          break;
983       case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ:
984          if (ew->state.maximized_horz)
985            {
986               RECT rect;
987
988               if (!GetClientRect(w, &rect))
989                 {
990                    ERR("GetClientRect() failed");
991                    break;
992                 }
993
994               if (!MoveWindow(w, 0, rect.top,
995                               GetSystemMetrics(SM_CXSCREEN),
996                               rect.bottom - rect.top,
997                               TRUE))
998                 {
999                    ERR("MoveWindow() failed");
1000                 }
1001            }
1002          break;
1003       case ECORE_WIN32_WINDOW_STATE_MAXIMIZED:
1004          if (ew->state.maximized_vert && ew->state.maximized_horz)
1005            {
1006               RECT rect;
1007
1008               if (!SystemParametersInfo(SPI_GETWORKAREA, 0,
1009                                         &rect, 0))
1010                 {
1011                    ERR("SystemParametersInfo() failed");
1012                    break;
1013                 }
1014
1015               if (!MoveWindow(w, 0, 0,
1016                               GetSystemMetrics(SM_CXSCREEN),
1017                               rect.bottom - rect.top,
1018                               TRUE))
1019                 {
1020                    ERR("MoveWindow() failed");
1021                 }
1022            }
1023          break;
1024       case ECORE_WIN32_WINDOW_STATE_SHADED:
1025          ew->state.shaded = 1;
1026          break;
1027       case ECORE_WIN32_WINDOW_STATE_HIDDEN:
1028          ew->state.hidden = 1;
1029          break;
1030       case ECORE_WIN32_WINDOW_STATE_FULLSCREEN:
1031          if (ew->state.fullscreen)
1032            ecore_win32_window_fullscreen_set(window, set);
1033          break;
1034       case ECORE_WIN32_WINDOW_STATE_ABOVE:
1035          if (ew->state.above)
1036            if (!SetWindowPos(w, HWND_TOP,
1037                              0, 0,
1038                              0, 0,
1039                              SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW))
1040              {
1041                 ERR("SetWindowPos() failed");
1042              }
1043          break;
1044       case ECORE_WIN32_WINDOW_STATE_BELOW:
1045          if (ew->state.below)
1046            if (!SetWindowPos(w, HWND_BOTTOM,
1047                              0, 0,
1048                              0, 0,
1049                              SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW))
1050              {
1051                 ERR("SetWindowPos() failed");
1052              }
1053          break;
1054       case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION:
1055          ew->state.demands_attention = 1;
1056          break;
1057       case ECORE_WIN32_WINDOW_STATE_UNKNOWN:
1058          /* nothing to be done */
1059          break;
1060      }
1061 }
1062
1063 void
1064 ecore_win32_window_type_set(Ecore_Win32_Window      *window,
1065                             Ecore_Win32_Window_Type  type)
1066 {
1067    if (!window)
1068      return;
1069
1070    INF("setting window type");
1071
1072    switch (type)
1073      {
1074      case ECORE_WIN32_WINDOW_TYPE_DESKTOP:
1075        ((struct _Ecore_Win32_Window *)window)->type.desktop = 1;
1076        break;
1077      case ECORE_WIN32_WINDOW_TYPE_DOCK:
1078        ((struct _Ecore_Win32_Window *)window)->type.dock = 1;
1079        break;
1080      case ECORE_WIN32_WINDOW_TYPE_TOOLBAR:
1081        ((struct _Ecore_Win32_Window *)window)->type.toolbar = 1;
1082        break;
1083      case ECORE_WIN32_WINDOW_TYPE_MENU:
1084        ((struct _Ecore_Win32_Window *)window)->type.menu = 1;
1085        break;
1086      case ECORE_WIN32_WINDOW_TYPE_UTILITY:
1087        ((struct _Ecore_Win32_Window *)window)->type.utility = 1;
1088        break;
1089      case ECORE_WIN32_WINDOW_TYPE_SPLASH:
1090        ((struct _Ecore_Win32_Window *)window)->type.splash = 1;
1091        break;
1092      case ECORE_WIN32_WINDOW_TYPE_DIALOG:
1093        ((struct _Ecore_Win32_Window *)window)->type.dialog = 1;
1094        break;
1095      case ECORE_WIN32_WINDOW_TYPE_NORMAL:
1096        ((struct _Ecore_Win32_Window *)window)->type.normal = 1;
1097        break;
1098      case ECORE_WIN32_WINDOW_TYPE_UNKNOWN:
1099        ((struct _Ecore_Win32_Window *)window)->type.normal = 1;
1100        break;
1101      }
1102 }
1103
1104
1105 /***** Private functions definitions *****/
1106
1107 static Ecore_Win32_Window *
1108 ecore_win32_window_internal_new(Ecore_Win32_Window *parent,
1109                                 int                 x,
1110                                 int                 y,
1111                                 int                 width,
1112                                 int                 height,
1113                                 DWORD               style)
1114 {
1115    RECT                        rect;
1116    struct _Ecore_Win32_Window *w;
1117    int                         minimal_width;
1118    int                         minimal_height;
1119
1120    w = (struct _Ecore_Win32_Window *)calloc(1, sizeof(struct _Ecore_Win32_Window));
1121    if (!w)
1122      {
1123         ERR("malloc() failed");
1124         return NULL;
1125      }
1126
1127    rect.left = 0;
1128    rect.top = 0;
1129    rect.right = width;
1130    rect.bottom = height;
1131    if (!AdjustWindowRect(&rect, style, FALSE))
1132      {
1133         ERR("AdjustWindowRect() failed");
1134         free(w);
1135         return NULL;
1136      }
1137
1138    minimal_width = GetSystemMetrics(SM_CXMIN);
1139    minimal_height = GetSystemMetrics(SM_CYMIN);
1140 /*    if (((rect.right - rect.left) < minimal_width) || */
1141 /*        ((rect.bottom - rect.top) < minimal_height)) */
1142 /*      { */
1143 /*         fprintf (stderr, "[Ecore] [Win32] ERROR !!\n"); */
1144 /*         fprintf (stderr, "                Wrong size %ld\n", rect.right - rect.left); */
1145 /*         free(w); */
1146 /*         return NULL; */
1147 /*      } */
1148    if ((rect.right - rect.left) < minimal_width)
1149      {
1150        rect.right = rect.left + minimal_width;
1151      }
1152
1153    w->window = CreateWindowEx(0,
1154                               ECORE_WIN32_WINDOW_CLASS, "",
1155                               style,
1156                               x, y,
1157                               rect.right - rect.left,
1158                               rect.bottom - rect.top,
1159                               parent ? ((struct _Ecore_Win32_Window *)parent)->window : NULL,
1160                               NULL, _ecore_win32_instance, NULL);
1161    if (!w->window)
1162      {
1163         ERR("CreateWindowEx() failed");
1164         free(w);
1165         return NULL;
1166      }
1167
1168    SetLastError(0);
1169    if (!SetWindowLongPtr(w->window, GWL_USERDATA, (LONG)w) && (GetLastError() != 0))
1170      {
1171         ERR("SetWindowLongPtr() failed");
1172         DestroyWindow(w->window);
1173         free(w);
1174         return NULL;
1175      }
1176
1177    w->min_width   = 0;
1178    w->min_height  = 0;
1179    w->max_width   = 32767;
1180    w->max_height  = 32767;
1181    w->base_width  = -1;
1182    w->base_height = -1;
1183    w->step_width  = -1;
1184    w->step_height = -1;
1185
1186    w->state.iconified         = 0;
1187    w->state.modal             = 0;
1188    w->state.sticky            = 0;
1189    w->state.maximized_vert    = 0;
1190    w->state.maximized_horz    = 0;
1191    w->state.shaded            = 0;
1192    w->state.hidden            = 0;
1193    w->state.fullscreen        = 0;
1194    w->state.above             = 0;
1195    w->state.below             = 0;
1196    w->state.demands_attention = 0;
1197
1198    w->type.desktop = 0;
1199    w->type.dock    = 0;
1200    w->type.toolbar = 0;
1201    w->type.menu    = 0;
1202    w->type.utility = 0;
1203    w->type.splash  = 0;
1204    w->type.dialog  = 0;
1205    w->type.normal  = 0;
1206
1207    w->pointer_is_in = 0;
1208    w->borderless    = 0;
1209    w->iconified     = 0;
1210    w->fullscreen    = 0;
1211
1212    return w;
1213 }