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