[ecore] merged svn latest code (svn54830)
[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  *                                  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           struct _Ecore_WinCE_Window *w = NULL;
86
87           w = (struct _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_PAINT:
145        {
146           PAINTSTRUCT paint;
147
148           if (BeginPaint(window, &paint))
149             {
150                data->update = paint.rcPaint;
151                _ecore_wince_event_handle_expose(data);
152                EndPaint(window, &paint);
153             }
154           break;
155        }
156      default:
157        return DefWindowProc(window, message, window_param, data_param);
158      }
159
160    return 0;
161 }
162
163 static void
164 _ecore_wince_error_print_cb(const Eina_Log_Domain *d __UNUSED__,
165                             Eina_Log_Level  level __UNUSED__,
166                             const char     *file __UNUSED__,
167                             const char     *fnc,
168                             int             line,
169                             const char     *fmt,
170                             void           *data __UNUSED__,
171                             va_list         args)
172 {
173    fprintf(stderr, "[%s:%d] ", fnc, line);
174    vfprintf(stderr, fmt, args);
175 }
176
177 /**
178  * @endcond
179  */
180
181
182 /*============================================================================*
183  *                                 Global                                     *
184  *============================================================================*/
185
186
187 double              _ecore_wince_double_click_time = 0.25;
188 long                _ecore_wince_event_last_time = 0;
189 Ecore_WinCE_Window *_ecore_wince_event_last_window = NULL;
190 HINSTANCE           _ecore_wince_instance = NULL;
191 int                 _ecore_wince_log_dom_global = -1;
192
193 int ECORE_WINCE_EVENT_MOUSE_IN              = 0;
194 int ECORE_WINCE_EVENT_MOUSE_OUT             = 0;
195 int ECORE_WINCE_EVENT_WINDOW_FOCUS_IN       = 0;
196 int ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT      = 0;
197 int ECORE_WINCE_EVENT_WINDOW_DAMAGE         = 0;
198 int ECORE_WINCE_EVENT_WINDOW_CREATE         = 0;
199 int ECORE_WINCE_EVENT_WINDOW_DESTROY        = 0;
200 int ECORE_WINCE_EVENT_WINDOW_SHOW           = 0;
201 int ECORE_WINCE_EVENT_WINDOW_HIDE           = 0;
202 int ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST = 0;
203
204 /*============================================================================*
205  *                                   API                                      *
206  *============================================================================*/
207
208 /**
209  * @addtogroup Ecore_WinCE_Group Ecore_WinCE library
210  *
211  * Ecore_WinCE is a library that wraps Windows CE graphic functions
212  * and integrate them nicely into the Ecore main loop.
213  *
214  * @{
215  */
216
217 /**
218  * @brief Initialize the Ecore_WinCE library.
219  *
220  * @return 1 or greater on success, 0 on error.
221  *
222  * This function sets up the Windows CE graphic system. It returns 0 on
223  * failure, otherwise it returns the number of times it has already been
224  * called.
225  *
226  * When Ecore_WinCE is not used anymore, call ecore_wince_shutdown()
227  * to shut down the Ecore_WinCE library.
228  */
229 EAPI int
230 ecore_wince_init()
231 {
232    WNDCLASS wc;
233
234    if (++_ecore_wince_init_count != 1)
235      return _ecore_wince_init_count;
236
237    if (!eina_init())
238      return --_ecore_wince_init_count;
239
240    eina_log_print_cb_set(_ecore_wince_error_print_cb, NULL);
241    _ecore_wince_log_dom_global = eina_log_domain_register
242      ("ecore_wince", ECORE_WINCE_DEFAULT_LOG_COLOR);
243    if (_ecore_wince_log_dom_global < 0)
244      {
245         EINA_LOG_ERR("Ecore_WinCE: Could not register log domain");
246         goto shutdown_eina;
247       }
248
249    if (!ecore_event_init())
250      {
251         ERR("Ecore_WinCE: Could not init ecore_event");
252         goto unregister_log_domain;
253      }
254
255    _ecore_wince_instance = GetModuleHandle(NULL);
256    if (!_ecore_wince_instance)
257      {
258         ERR("GetModuleHandle() failed");
259         goto shutdown_ecore_event;
260      }
261
262    memset (&wc, 0, sizeof (wc));
263    wc.style = CS_HREDRAW | CS_VREDRAW;
264    wc.lpfnWndProc = _ecore_wince_window_procedure;
265    wc.cbClsExtra = 0;
266    wc.cbWndExtra = 0;
267    wc.hInstance = _ecore_wince_instance;
268    wc.hIcon = NULL;
269    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
270    wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
271    wc.lpszMenuName =  NULL;
272    wc.lpszClassName = ECORE_WINCE_WINDOW_CLASS;
273
274    if(!RegisterClass(&wc))
275      {
276         ERR("RegisterClass() failed");
277         goto free_library;
278      }
279
280    if (!ECORE_WINCE_EVENT_MOUSE_IN)
281      {
282         ECORE_WINCE_EVENT_MOUSE_IN              = ecore_event_type_new();
283         ECORE_WINCE_EVENT_MOUSE_OUT             = ecore_event_type_new();
284         ECORE_WINCE_EVENT_WINDOW_FOCUS_IN       = ecore_event_type_new();
285         ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT      = ecore_event_type_new();
286         ECORE_WINCE_EVENT_WINDOW_DAMAGE         = ecore_event_type_new();
287         ECORE_WINCE_EVENT_WINDOW_CREATE         = ecore_event_type_new();
288         ECORE_WINCE_EVENT_WINDOW_DESTROY        = ecore_event_type_new();
289         ECORE_WINCE_EVENT_WINDOW_SHOW           = ecore_event_type_new();
290         ECORE_WINCE_EVENT_WINDOW_HIDE           = ecore_event_type_new();
291         ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
292      }
293
294    return _ecore_wince_init_count;
295
296  free_library:
297    FreeLibrary(_ecore_wince_instance);
298  shutdown_ecore_event:
299    ecore_event_shutdown();
300  unregister_log_domain:
301    eina_log_domain_unregister(_ecore_wince_log_dom_global);
302  shutdown_eina:
303    eina_shutdown();
304
305    return --_ecore_wince_init_count;
306 }
307
308 /**
309  * @brief Shut down the Ecore_WinCE library.
310  *
311  * @return 0 when the library is completely shut down, 1 or
312  * greater otherwise.
313  *
314  * This function shuts down the Ecore_WinCE library. It returns 0 when it has
315  * been called the same number of times than ecore_wince_init(). In that case
316  * it shuts down all the Windows CE graphic system.
317  */
318 EAPI int
319 ecore_wince_shutdown()
320 {
321    HWND task_bar;
322
323    if (--_ecore_wince_init_count != 0)
324      return _ecore_wince_init_count;
325
326    /* force task bar to be shown (in case the application exits */
327    /* while being fullscreen) */
328    task_bar = FindWindow(L"HHTaskBar", NULL);
329    if (task_bar)
330      {
331         ShowWindow(task_bar, SW_SHOW);
332         EnableWindow(task_bar, TRUE);
333      }
334
335    if (!UnregisterClass(ECORE_WINCE_WINDOW_CLASS, _ecore_wince_instance))
336      ERR("UnregisterClass() failed");
337
338    if (!FreeLibrary(_ecore_wince_instance))
339      ERR("FreeLibrary() failed");
340
341    _ecore_wince_instance = NULL;
342
343    ecore_event_shutdown();
344    eina_log_domain_unregister(_ecore_wince_log_dom_global);
345    _ecore_wince_log_dom_global = -1;
346    eina_shutdown();
347
348    return _ecore_wince_init_count;
349 }
350
351 /**
352  * @brief Set the timeout for a double and triple clicks to be flagged.
353  *
354  * @param t The time in seconds.
355  *
356  * This function sets the time @p t between clicks before the
357  * double_click flag is set in a button down event. If 3 clicks occur
358  * within double this time, the triple_click flag is also set.
359  */
360 EAPI void
361 ecore_wince_double_click_time_set(double t)
362 {
363    if (t < 0.0) t = 0.0;
364    _ecore_wince_double_click_time = t;
365 }
366
367 /**
368  * @brief Retrieve the double and triple click flag timeout.
369  *
370  * @return The timeout for double clicks in seconds.
371  *
372  * This function returns the double clicks in seconds. If
373  * ecore_wince_double_click_time_set() has not been called, the
374  * default value is returned. See ecore_wince_double_click_time_set()
375  * for more informations.
376  */
377 EAPI double
378 ecore_wince_double_click_time_get(void)
379 {
380    return _ecore_wince_double_click_time;
381 }
382
383 /**
384  * @brief Return the last event time.
385  *
386  * @return The last envent time.
387  *
388  * This function returns the last event time.
389  */
390 EAPI long
391 ecore_wince_current_time_get(void)
392 {
393    return _ecore_wince_event_last_time;
394 }
395
396 /**
397  * @}
398  */