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