svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_wince / ecore_wince_window.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #define WIN32_LEAN_AND_MEAN
10 #include <windows.h>
11 #undef WIN32_LEAN_AND_MEAN
12
13 #include <Evil.h>
14 #include <Eina.h>
15
16 #include "Ecore_WinCE.h"
17 #include "ecore_wince_private.h"
18
19
20 /***** Private declarations *****/
21
22 typedef BOOL (__stdcall *UnregisterFunc1Proc)(UINT, UINT);
23
24 static int _ecore_wince_hardware_keys_register(HWND window);
25
26
27 /***** API *****/
28
29 Ecore_WinCE_Window *
30 ecore_wince_window_new(Ecore_WinCE_Window *parent,
31                        int                 x,
32                        int                 y,
33                        int                 width,
34                        int                 height)
35 {
36    struct _Ecore_WinCE_Window *w;
37    HWND                        window;
38    RECT                        rect;
39
40    INF("creating window");
41
42    w = (struct _Ecore_WinCE_Window *)calloc(1, sizeof(struct _Ecore_WinCE_Window));
43    if (!w)
44      {
45         ERR("malloc() failed");
46         return NULL;
47      }
48
49    rect.left = 0;
50    rect.top = 0;
51    rect.right = width;
52    rect.bottom = height;
53    if (!AdjustWindowRectEx(&rect, WS_CAPTION | WS_SYSMENU | WS_VISIBLE, FALSE, WS_EX_TOPMOST))
54      {
55         ERR("AdjustWindowRectEx() failed");
56         free(w);
57         return NULL;
58      }
59
60    window = CreateWindowEx(WS_EX_TOPMOST,
61                            ECORE_WINCE_WINDOW_CLASS,
62                            L"",
63                            WS_CAPTION | WS_SYSMENU | WS_VISIBLE,
64                            x, y,
65                            rect.right - rect.left, rect.bottom - rect.top,
66                            parent ? ((struct _Ecore_WinCE_Window *)parent)->window : NULL,
67                            NULL, _ecore_wince_instance, NULL);
68    if (!window)
69      {
70         ERR("CreateWindowEx() failed");
71         free(w);
72         return NULL;
73      }
74
75    if (!_ecore_wince_hardware_keys_register(window))
76      {
77         ERR("_ecore_wince_hardware_keys_register() failed");
78         DestroyWindow(window);
79         free(w);
80         return NULL;
81      }
82
83    w->window = window;
84
85    SetLastError(0);
86    if (!SetWindowLong(window, GWL_USERDATA, (LONG)w) && (GetLastError() != 0))
87      {
88         ERR("SetWindowLong() failed");
89         DestroyWindow(window);
90         free(w);
91         return NULL;
92      }
93
94    w->pointer_is_in = 0;
95
96    return w;
97 }
98
99 void
100 ecore_wince_window_free(Ecore_WinCE_Window *window)
101 {
102    if (!window) return;
103
104    INF("destroying window");
105
106    DestroyWindow(((struct _Ecore_WinCE_Window *)window)->window);
107    free(window);
108 }
109
110 void *
111 ecore_wince_window_hwnd_get(Ecore_WinCE_Window *window)
112 {
113    if (!window)
114      return NULL;
115
116    return ((struct _Ecore_WinCE_Window *)window)->window;
117 }
118
119 void
120 ecore_wince_window_move(Ecore_WinCE_Window *window,
121                         int                 x,
122                         int                 y)
123 {
124    RECT rect;
125    HWND w;
126
127    if (!window || ((struct _Ecore_WinCE_Window *)window)->fullscreen)
128      return;
129
130    INF("moving window (%dx%d)", x, y);
131
132    w = ((struct _Ecore_WinCE_Window *)window)->window;
133    if (!GetWindowRect(w, &rect))
134      {
135         ERR("GetWindowRect() failed");
136         return;
137      }
138
139    if (!MoveWindow(w, x, y,
140                    rect.right - rect.left,
141                    rect.bottom - rect.top,
142                    TRUE))
143      {
144         ERR("MoveWindow() failed");
145      }
146 }
147
148 void
149 ecore_wince_window_resize(Ecore_WinCE_Window *window,
150                           int                 width,
151                           int                 height)
152 {
153    RECT                        rect;
154    struct _Ecore_WinCE_Window *w;
155    DWORD                       style;
156    DWORD                       exstyle;
157    int                         x;
158    int                         y;
159
160    if (!window || ((struct _Ecore_WinCE_Window *)window)->fullscreen)
161      return;
162
163    INF("resizing window (%dx%d)", width, height);
164
165    w = (struct _Ecore_WinCE_Window *)window;
166    if (!GetWindowRect(w->window, &rect))
167      {
168         ERR("GetWindowRect() failed");
169         return;
170      }
171
172    x = rect.left;
173    y = rect.top;
174    rect.left = 0;
175    rect.top = 0;
176    rect.right = width;
177    rect.bottom = height;
178    if (!(style = GetWindowLong(w->window, GWL_STYLE)))
179      {
180         ERR("GetWindowLong() failed");
181         return;
182      }
183    if (!(exstyle = GetWindowLong(w->window, GWL_EXSTYLE)))
184      {
185         ERR("GetWindowLong() failed");
186         return;
187      }
188    if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle))
189      {
190         ERR("AdjustWindowRectEx() failed");
191         return;
192      }
193
194    if (!MoveWindow(w->window, x, y,
195                    rect.right - rect.left,
196                    rect.bottom - rect.top,
197                    FALSE))
198      {
199         ERR("MoveWindow() failed");
200      }
201 }
202
203 void
204 ecore_wince_window_move_resize(Ecore_WinCE_Window *window,
205                                int                 x,
206                                int                 y,
207                                int                 width,
208                                int                 height)
209 {
210    RECT                        rect;
211    struct _Ecore_WinCE_Window *w;
212    DWORD                       style;
213    DWORD                       exstyle;
214
215    if (!window || ((struct _Ecore_WinCE_Window *)window)->fullscreen)
216      return;
217
218    INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height);
219
220    w = ((struct _Ecore_WinCE_Window *)window);
221    rect.left = 0;
222    rect.top = 0;
223    rect.right = width;
224    rect.bottom = height;
225    if (!(style = GetWindowLong(w->window, GWL_STYLE)))
226      {
227         ERR("GetWindowLong() failed");
228         return;
229      }
230    if (!(exstyle = GetWindowLong(w->window, GWL_EXSTYLE)))
231      {
232         ERR("GetWindowLong() failed");
233         return;
234      }
235    if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle))
236      {
237         ERR("AdjustWindowRectEx() failed");
238         return;
239      }
240
241    if (!MoveWindow(w->window, x, y,
242               rect.right - rect.left,
243               rect.bottom - rect.top,
244               TRUE))
245      {
246         ERR("MoveWindow() failed");
247      }
248 }
249
250 void
251 ecore_wince_window_show(Ecore_WinCE_Window *window)
252 {
253    if (!window) return;
254
255    INF("showing window");
256
257    if (!ShowWindow(((struct _Ecore_WinCE_Window *)window)->window, SW_SHOWNORMAL))
258      {
259         ERR("ShowWindow() failed");
260         return;
261      }
262    if (!UpdateWindow(((struct _Ecore_WinCE_Window *)window)->window))
263      {
264         ERR("UpdateWindow() failed");
265      }
266    if (!SendMessage(((struct _Ecore_WinCE_Window *)window)->window, WM_SHOWWINDOW, 1, 0))
267      {
268         ERR("SendMessage() failed");
269      }
270 }
271
272 void
273 ecore_wince_window_hide(Ecore_WinCE_Window *window)
274 {
275    if (!window) return;
276
277    INF("hiding window");
278
279    if (!ShowWindow(((struct _Ecore_WinCE_Window *)window)->window, SW_HIDE))
280      {
281         ERR("ShowWindow() failed");
282         return;
283      }
284    if (!SendMessage(((struct _Ecore_WinCE_Window *)window)->window, WM_SHOWWINDOW, 0, 0))
285      {
286         ERR("SendMessage() failed");
287      }
288 }
289
290 void
291 ecore_wince_window_title_set(Ecore_WinCE_Window *window,
292                              const char         *title)
293 {
294    wchar_t *wtitle;
295
296    if (!window) return;
297
298    if (!title || !title[0]) return;
299
300    INF("setting window title");
301
302    wtitle = evil_char_to_wchar(title);
303    if (!wtitle) return;
304
305    if (!SetWindowText(((struct _Ecore_WinCE_Window *)window)->window, wtitle))
306      {
307         ERR("SetWindowText() failed");
308      }
309    free(wtitle);
310 }
311
312 void
313 ecore_wince_window_backend_set(Ecore_WinCE_Window *window, int backend)
314 {
315    struct _Ecore_WinCE_Window *w;
316
317    if (!window)
318      return;
319
320    INF("setting backend");
321
322    w = (struct _Ecore_WinCE_Window *)window;
323    w->backend = backend;
324 }
325
326 void
327 ecore_wince_window_suspend_set(Ecore_WinCE_Window *window, int (*suspend)(int))
328 {
329    struct _Ecore_WinCE_Window *w;
330
331    if (!window)
332      return;
333
334    INF("setting suspend callback");
335
336    w = (struct _Ecore_WinCE_Window *)window;
337    w->suspend = suspend;
338 }
339
340 void
341 ecore_wince_window_resume_set(Ecore_WinCE_Window *window, int (*resume)(int))
342 {
343    struct _Ecore_WinCE_Window *w;
344
345    if (!window)
346      return;
347
348    INF("setting resume callback");
349
350    w = (struct _Ecore_WinCE_Window *)window;
351    w->resume = resume;
352 }
353
354 void
355 ecore_wince_window_geometry_get(Ecore_WinCE_Window *window,
356                                 int                *x,
357                                 int                *y,
358                                 int                *width,
359                                 int                *height)
360 {
361    RECT rect;
362    int  w;
363    int  h;
364
365    INF("getting window geometry");
366
367    if (!window)
368      {
369         if (x) *x = 0;
370         if (y) *y = 0;
371         if (width) *width = GetSystemMetrics(SM_CXSCREEN);
372         if (height) *height = GetSystemMetrics(SM_CYSCREEN);
373
374         return;
375      }
376
377    if (!GetClientRect(((struct _Ecore_WinCE_Window *)window)->window,
378                       &rect))
379      {
380         ERR("GetClientRect() failed");
381
382         if (x) *x = 0;
383         if (y) *y = 0;
384         if (width) *width = 0;
385         if (height) *height = 0;
386
387         return;
388      }
389
390    w = rect.right - rect.left;
391    h = rect.bottom - rect.top;
392
393    if (!GetWindowRect(((struct _Ecore_WinCE_Window *)window)->window,
394                       &rect))
395      {
396         ERR("GetWindowRect() failed");
397
398         if (x) *x = 0;
399         if (y) *y = 0;
400         if (width) *width = 0;
401         if (height) *height = 0;
402
403         return;
404      }
405
406    if (x) *x = rect.left;
407    if (y) *y = rect.top;
408    if (width) *width = w;
409    if (height) *height = h;
410 }
411
412 void
413 ecore_wince_window_size_get(Ecore_WinCE_Window *window,
414                             int                *width,
415                             int                *height)
416 {
417    RECT rect;
418
419    INF("getting window size");
420
421    if (!window)
422      {
423         if (width) *width = GetSystemMetrics(SM_CXSCREEN);
424         if (height) *height = GetSystemMetrics(SM_CYSCREEN);
425
426         return;
427      }
428
429    if (!GetClientRect(((struct _Ecore_WinCE_Window *)window)->window,
430                       &rect))
431      {
432         ERR("GetClientRect() failed");
433
434         if (width) *width = 0;
435         if (height) *height = 0;
436      }
437
438    if (width) *width = rect.right - rect.left;
439    if (height) *height = rect.bottom - rect.top;
440 }
441
442 void
443 ecore_wince_window_fullscreen_set(Ecore_WinCE_Window *window,
444                                   int                 on)
445 {
446    struct _Ecore_WinCE_Window *ew;
447    HWND                        w;
448    HWND                        task_bar;
449
450    if (!window) return;
451
452    ew = (struct _Ecore_WinCE_Window *)window;
453    if (((ew->fullscreen) && (on)) ||
454        ((!ew->fullscreen) && (!on)))
455      return;
456
457    INF("setting fullscreen: %s", on ? "yes" : "no");
458
459    ew->fullscreen = !!on;
460    w = ew->window;
461
462    if (on)
463      {
464         /* save the position and size of the window */
465         if (!GetWindowRect(w, &ew->rect))
466           {
467              ERR("GetWindowRect() failed");
468              return;
469           }
470
471         /* hide task bar */
472         task_bar = FindWindow(L"HHTaskBar", NULL);
473         if (!task_bar)
474           {
475              INF("FindWindow(): can not find task bar");
476           }
477         if (!ShowWindow(task_bar, SW_HIDE))
478           {
479              INF("ShowWindow(): task bar already hidden");
480           }
481         if (!EnableWindow(task_bar, FALSE))
482           {
483              INF("EnableWindow(): input already disabled");
484           }
485
486         /* style: visible + popup */
487         if (!SetWindowLong(w, GWL_STYLE, WS_POPUP | WS_VISIBLE))
488           {
489              INF("SetWindowLong() failed");
490           }
491
492         /* resize window to fit the entire screen */
493         if (!SetWindowPos(w, HWND_TOPMOST,
494                           0, 0,
495                           GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
496                           SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED))
497           {
498              INF("SetWindowPos() failed");
499           }
500         /*
501          * It seems that SetWindowPos is not sufficient.
502          * Call MoveWindow with the correct size and force painting.
503          * Note that UpdateWindow (forcing repainting) is not sufficient
504          */
505         if (!MoveWindow(w,
506                         0, 0,
507                         GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
508                         TRUE))
509           {
510              INF("MoveWindow() failed");
511           }
512      }
513    else
514      {
515         /* show task bar */
516         task_bar = FindWindow(L"HHTaskBar", NULL);
517         if (!task_bar)
518           {
519              INF("FindWindow(): can not find task bar");
520           }
521         if (!ShowWindow(task_bar, SW_SHOW))
522           {
523              INF("ShowWindow(): task bar already visible");
524           }
525         if (!EnableWindow(task_bar, TRUE))
526           {
527              INF("EnableWindow():  input already enabled");
528           }
529
530         /* style: visible + caption + sysmenu */
531         if (!SetWindowLong(w, GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_VISIBLE))
532           {
533              INF("SetWindowLong() failed");
534           }
535         /* restaure the position and size of the window */
536         if (!SetWindowPos(w, HWND_TOPMOST,
537                           ew->rect.left,
538                           ew->rect.top,
539                           ew->rect.right - ew->rect.left,
540                           ew->rect.bottom - ew->rect.top,
541                           SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED))
542           {
543              INF("SetWindowLong() failed");
544           }
545         /*
546          * It seems that SetWindowPos is not sufficient.
547          * Call MoveWindow with the correct size and force painting.
548          * Note that UpdateWindow (forcing repainting) is not sufficient
549          */
550         if (!MoveWindow(w,
551                         ew->rect.left,
552                         ew->rect.top,
553                         ew->rect.right - ew->rect.left,
554                         ew->rect.bottom - ew->rect.top,
555                         TRUE))
556           {
557              INF("MoveWindow() failed");
558           }
559      }
560 }
561
562
563 /***** Private functions definitions *****/
564
565 static int
566 _ecore_wince_hardware_keys_register(HWND window)
567 {
568    HINSTANCE           core_dll;
569    UnregisterFunc1Proc unregister_fct;
570    int                 i;
571
572    core_dll = LoadLibrary(L"coredll.dll");
573    if (!core_dll)
574      {
575         ERR("LoadLibrary() failed");
576         return 0;
577      }
578
579    unregister_fct = (UnregisterFunc1Proc)GetProcAddress(core_dll, L"UnregisterFunc1");
580    if (!unregister_fct)
581      {
582         ERR("GetProcAddress() failed");
583         FreeLibrary(core_dll);
584         return 0;
585      }
586
587    for (i = 0xc1; i <= 0xcf; i++)
588      {
589         unregister_fct(MOD_WIN, i);
590         RegisterHotKey(window, i, MOD_WIN, i);
591      }
592
593    FreeLibrary(core_dll);
594
595    return 1;
596 }