a66382393ed62925636746ceee3476206769329a
[profile/ivi/ecore.git] / src / lib / ecore_wince / ecore_wince.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_LEAN_AND_MEAN
9 #include <windows.h>
10 #undef WIN32_LEAN_AND_MEAN
11
12 #include <Eina.h>
13 #include <Ecore.h>
14 #include <Ecore_Input.h>
15
16 #include "Ecore_WinCE.h"
17 #include "ecore_wince_private.h"
18
19
20 /***** Global declarations *****/
21
22 double              _ecore_wince_double_click_time = 0.25;
23 long                _ecore_wince_event_last_time = 0;
24 Ecore_WinCE_Window *_ecore_wince_event_last_window = NULL;
25 HINSTANCE           _ecore_wince_instance = NULL;
26 int                 _ecore_wince_log_dom_global = -1;
27
28 int ECORE_WINCE_EVENT_MOUSE_IN              = 0;
29 int ECORE_WINCE_EVENT_MOUSE_OUT             = 0;
30 int ECORE_WINCE_EVENT_WINDOW_FOCUS_IN       = 0;
31 int ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT      = 0;
32 int ECORE_WINCE_EVENT_WINDOW_DAMAGE         = 0;
33 int ECORE_WINCE_EVENT_WINDOW_CREATE         = 0;
34 int ECORE_WINCE_EVENT_WINDOW_DESTROY        = 0;
35 int ECORE_WINCE_EVENT_WINDOW_SHOW           = 0;
36 int ECORE_WINCE_EVENT_WINDOW_HIDE           = 0;
37 int ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST = 0;
38
39
40 /***** Private declarations *****/
41
42 static int       _ecore_wince_init_count = 0;
43
44 LRESULT CALLBACK _ecore_wince_window_procedure(HWND   window,
45                                                UINT   message,
46                                                WPARAM window_param,
47                                                LPARAM data_param);
48
49 static void      _ecore_wince_error_print_cb(const Eina_Log_Domain *d,
50                                              Eina_Log_Level   level,
51                                              const char      *file,
52                                              const char      *fnc,
53                                              int              line,
54                                              const char      *fmt,
55                                              void            *data,
56                                              va_list          args);
57
58
59 /***** API *****/
60
61 int
62 ecore_wince_init()
63 {
64    WNDCLASS wc;
65
66    if (++_ecore_wince_init_count != 1)
67      return _ecore_wince_init_count;
68
69    if (!eina_init())
70      return --_ecore_wince_init_count;
71
72    eina_log_print_cb_set(_ecore_wince_error_print_cb, NULL);
73    _ecore_wince_log_dom_global = eina_log_domain_register("ecore_wince", ECORE_WINCE_DEFAULT_LOG_COLOR);
74    if (_ecore_wince_log_dom_global < 0)
75      {
76         EINA_LOG_ERR("Ecore_WinCE: Could not register log domain");
77         goto shutdown_eina;
78       }
79
80    if (!ecore_event_init())
81      {
82         ERR("Ecore_WinCE: Could not init ecore_event");
83         goto unregister_log_domain;
84      }
85
86    _ecore_wince_instance = GetModuleHandle(NULL);
87    if (!_ecore_wince_instance)
88      {
89         ERR("GetModuleHandle() failed");
90         goto shutdown_ecore_event;
91      }
92
93    memset (&wc, 0, sizeof (wc));
94    wc.style = CS_HREDRAW | CS_VREDRAW;
95    wc.lpfnWndProc = _ecore_wince_window_procedure;
96    wc.cbClsExtra = 0;
97    wc.cbWndExtra = 0;
98    wc.hInstance = _ecore_wince_instance;
99    wc.hIcon = NULL;
100    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
101    wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
102    wc.lpszMenuName =  NULL;
103    wc.lpszClassName = ECORE_WINCE_WINDOW_CLASS;
104
105    if(!RegisterClass(&wc))
106      {
107         ERR("RegisterClass() failed");
108         goto free_library;
109      }
110
111    if (!ECORE_WINCE_EVENT_MOUSE_IN)
112      {
113         ECORE_WINCE_EVENT_MOUSE_IN              = ecore_event_type_new();
114         ECORE_WINCE_EVENT_MOUSE_OUT             = ecore_event_type_new();
115         ECORE_WINCE_EVENT_WINDOW_FOCUS_IN       = ecore_event_type_new();
116         ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT      = ecore_event_type_new();
117         ECORE_WINCE_EVENT_WINDOW_DAMAGE         = ecore_event_type_new();
118         ECORE_WINCE_EVENT_WINDOW_CREATE         = ecore_event_type_new();
119         ECORE_WINCE_EVENT_WINDOW_DESTROY        = ecore_event_type_new();
120         ECORE_WINCE_EVENT_WINDOW_SHOW           = ecore_event_type_new();
121         ECORE_WINCE_EVENT_WINDOW_HIDE           = ecore_event_type_new();
122         ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
123      }
124
125    return _ecore_wince_init_count;
126
127  free_library:
128    FreeLibrary(_ecore_wince_instance);
129  shutdown_ecore_event:
130    ecore_event_shutdown();
131  unregister_log_domain:
132    eina_log_domain_unregister(_ecore_wince_log_dom_global);
133  shutdown_eina:
134    eina_shutdown();
135
136    return --_ecore_wince_init_count;
137 }
138
139 int
140 ecore_wince_shutdown()
141 {
142    HWND task_bar;
143
144    if (--_ecore_wince_init_count != 0)
145      return _ecore_wince_init_count;
146
147    /* force task bar to be shown (in case the application exits */
148    /* while being fullscreen) */
149    task_bar = FindWindow(L"HHTaskBar", NULL);
150    if (task_bar)
151      {
152         ShowWindow(task_bar, SW_SHOW);
153         EnableWindow(task_bar, TRUE);
154      }
155
156    if (!UnregisterClass(ECORE_WINCE_WINDOW_CLASS, _ecore_wince_instance))
157      ERR("UnregisterClass() failed");
158
159    if (!FreeLibrary(_ecore_wince_instance))
160      ERR("FreeLibrary() failed");
161
162    _ecore_wince_instance = NULL;
163
164    ecore_event_shutdown();
165    eina_log_domain_unregister(_ecore_wince_log_dom_global);
166    _ecore_wince_log_dom_global = -1;
167    eina_shutdown();
168
169    return _ecore_wince_init_count;
170 }
171
172 /**
173  * Sets the timeout for a double and triple clicks to be flagged.
174  *
175  * This sets the time between clicks before the double_click flag is
176  * set in a button down event. If 3 clicks occur within double this
177  * time, the triple_click flag is also set.
178  *
179  * @param t The time in seconds
180  */
181 EAPI void
182 ecore_wince_double_click_time_set(double t)
183 {
184    if (t < 0.0) t = 0.0;
185    _ecore_wince_double_click_time = t;
186 }
187
188 /**
189  * Retrieves the double and triple click flag timeout.
190  *
191  * See @ref ecore_wince_double_click_time_set for more information.
192  *
193  * @return The timeout for double clicks in seconds.
194  */
195 EAPI double
196 ecore_wince_double_click_time_get(void)
197 {
198    return _ecore_wince_double_click_time;
199 }
200
201 /**
202  * Return the last event time
203  */
204 EAPI long
205 ecore_wince_current_time_get(void)
206 {
207    return _ecore_wince_event_last_time;
208 }
209
210
211 /***** Private functions definitions *****/
212
213 LRESULT CALLBACK
214 _ecore_wince_window_procedure(HWND   window,
215                               UINT   message,
216                               WPARAM window_param,
217                               LPARAM data_param)
218 {
219    Ecore_WinCE_Callback_Data *data;
220    POINTS                     pt;
221    DWORD                      coord;
222
223    data = (Ecore_WinCE_Callback_Data *)malloc(sizeof(Ecore_WinCE_Callback_Data));
224    if (!data) return DefWindowProc(window, message, window_param, data_param);
225
226    data->window = window;
227    data->message = message;
228    data->window_param = window_param;
229    data->data_param = data_param;
230    data->time = GetTickCount();
231    coord = GetMessagePos();
232    pt = MAKEPOINTS(coord);
233    data->x = pt.x;
234    data->y = pt.y;
235
236    switch (data->message)
237      {
238        /* Keyboard input notifications */
239      case WM_CHAR:
240        _ecore_wince_event_handle_key_press(data, 0);
241        break;
242      case WM_HOTKEY:
243        _ecore_wince_event_handle_key_press(data, 1);
244        break;
245      case WM_KEYDOWN:
246      case WM_SYSKEYDOWN:
247        _ecore_wince_event_handle_key_press(data, 1);
248        break;
249      case WM_KEYUP:
250      case WM_SYSKEYUP:
251        _ecore_wince_event_handle_key_release(data, 1);
252        break;
253      case WM_SETFOCUS:
254        _ecore_wince_event_handle_focus_in(data);
255        break;
256      case WM_KILLFOCUS:
257        _ecore_wince_event_handle_focus_out(data);
258        break;
259        /* Mouse input notifications */
260      case WM_LBUTTONDOWN:
261        _ecore_wince_event_handle_button_press(data, 1);
262        break;
263      case WM_LBUTTONUP:
264        _ecore_wince_event_handle_button_release(data, 1);
265        break;
266      case WM_MOUSEMOVE:
267        {
268           RECT                        rect;
269           struct _Ecore_WinCE_Window *w = NULL;
270
271           w = (struct _Ecore_WinCE_Window *)GetWindowLong(window, GWL_USERDATA);
272
273           if (GetClientRect(window, &rect))
274             {
275                POINT pt;
276
277                INF("mouse in window");
278
279                pt.x = LOWORD(data_param);
280                pt.y = HIWORD(data_param);
281                if (!PtInRect(&rect, pt))
282                  {
283                     if (w->pointer_is_in)
284                       {
285                          w->pointer_is_in = 0;
286                          _ecore_wince_event_handle_leave_notify(data);
287                       }
288                  }
289                else
290                  {
291                     if (!w->pointer_is_in)
292                       {
293                          w->pointer_is_in = 1;
294                          _ecore_wince_event_handle_enter_notify(data);
295                       }
296                  }
297             }
298           else
299             {
300                ERR("GetClientRect() failed");
301             }
302           _ecore_wince_event_handle_motion_notify(data);
303
304           break;
305        }
306        /* Window notifications */
307      case WM_CREATE:
308        _ecore_wince_event_handle_create_notify(data);
309        break;
310      case WM_DESTROY:
311        _ecore_wince_event_handle_destroy_notify(data);
312        break;
313      case WM_SHOWWINDOW:
314        if ((data->data_param == SW_OTHERUNZOOM) ||
315            (data->data_param == SW_OTHERUNZOOM))
316          break;
317
318        if (data->window_param)
319          _ecore_wince_event_handle_map_notify(data);
320        else
321          _ecore_wince_event_handle_unmap_notify(data);
322
323        break;
324      case WM_CLOSE:
325        _ecore_wince_event_handle_delete_request(data);
326        break;
327        /* GDI notifications */
328      case WM_PAINT:
329        {
330           PAINTSTRUCT paint;
331
332           if (BeginPaint(window, &paint))
333             {
334                data->update = paint.rcPaint;
335                _ecore_wince_event_handle_expose(data);
336                EndPaint(window, &paint);
337             }
338           break;
339        }
340      default:
341        return DefWindowProc(window, message, window_param, data_param);
342      }
343
344    return 0;
345 }
346
347 static void
348 _ecore_wince_error_print_cb(const Eina_Log_Domain *d __UNUSED__,
349                             Eina_Log_Level  level __UNUSED__,
350                             const char     *file __UNUSED__,
351                             const char     *fnc,
352                             int             line,
353                             const char     *fmt,
354                             void           *data __UNUSED__,
355                             va_list         args)
356 {
357    fprintf(stderr, "[%s:%d] ", fnc, line);
358    vfprintf(stderr, fmt, args);
359 }