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