2acc0056ceecb18a423cde3d29d4429952cc2330
[framework/uifw/ecore.git] / src / lib / ecore_win32 / ecore_win32.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 #include <windowsx.h>
16
17 #include "Ecore.h"
18 #include "Ecore_Win32.h"
19 #include "ecore_win32_private.h"
20
21
22 /***** Global declarations *****/
23
24 HINSTANCE           _ecore_win32_instance = NULL;
25 double              _ecore_win32_double_click_time = 0.25;
26 double              _ecore_win32_event_last_time = 0.0;
27 Ecore_Win32_Window *_ecore_win32_event_last_window = NULL;
28
29 int ECORE_WIN32_EVENT_KEY_DOWN              = 0;
30 int ECORE_WIN32_EVENT_KEY_UP                = 0;
31 int ECORE_WIN32_EVENT_MOUSE_BUTTON_DOWN     = 0;
32 int ECORE_WIN32_EVENT_MOUSE_BUTTON_UP       = 0;
33 int ECORE_WIN32_EVENT_MOUSE_MOVE            = 0;
34 int ECORE_WIN32_EVENT_MOUSE_IN              = 0;
35 int ECORE_WIN32_EVENT_MOUSE_OUT             = 0;
36 int ECORE_WIN32_EVENT_MOUSE_WHEEL           = 0;
37 int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN       = 0;
38 int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT      = 0;
39 int ECORE_WIN32_EVENT_WINDOW_DAMAGE         = 0;
40 int ECORE_WIN32_EVENT_WINDOW_CREATE         = 0;
41 int ECORE_WIN32_EVENT_WINDOW_DESTROY        = 0;
42 int ECORE_WIN32_EVENT_WINDOW_SHOW           = 0;
43 int ECORE_WIN32_EVENT_WINDOW_HIDE           = 0;
44 int ECORE_WIN32_EVENT_WINDOW_CONFIGURE      = 0;
45 int ECORE_WIN32_EVENT_WINDOW_RESIZE         = 0;
46 int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST = 0;
47
48
49 /***** Private declarations *****/
50
51 static int       _ecore_win32_init_count = 0;
52
53 LRESULT CALLBACK _ecore_win32_window_procedure(HWND   window,
54                                                UINT   message,
55                                                WPARAM window_param,
56                                                LPARAM data_param);
57
58
59 /***** API *****/
60
61
62 int
63 ecore_win32_init()
64 {
65    WNDCLASS wc;
66
67    if (_ecore_win32_init_count > 0)
68      {
69         _ecore_win32_init_count++;
70         return _ecore_win32_init_count;
71      }
72
73    printf (" *** ecore_win32_init\n");
74    _ecore_win32_instance = GetModuleHandle(NULL);
75    if (!_ecore_win32_instance)
76      return 0;
77
78    memset (&wc, 0, sizeof (WNDCLASS));
79    wc.style = CS_HREDRAW | CS_VREDRAW;
80    wc.lpfnWndProc = _ecore_win32_window_procedure;
81    wc.cbClsExtra = 0;
82    wc.cbWndExtra = 0;
83    wc.hInstance = _ecore_win32_instance;
84    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
85    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
86    wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
87    wc.lpszMenuName =  NULL;
88    wc.lpszClassName = ECORE_WIN32_WINDOW_CLASS;
89
90    if(!RegisterClass(&wc))
91      {
92         FreeLibrary(_ecore_win32_instance);
93         return 0;
94      }
95
96    if (!ECORE_WIN32_EVENT_KEY_DOWN)
97      {
98         ECORE_WIN32_EVENT_KEY_DOWN              = ecore_event_type_new();
99         ECORE_WIN32_EVENT_KEY_UP                = ecore_event_type_new();
100         ECORE_WIN32_EVENT_MOUSE_BUTTON_DOWN     = ecore_event_type_new();
101         ECORE_WIN32_EVENT_MOUSE_BUTTON_UP       = ecore_event_type_new();
102         ECORE_WIN32_EVENT_MOUSE_MOVE            = ecore_event_type_new();
103         ECORE_WIN32_EVENT_MOUSE_IN              = ecore_event_type_new();
104         ECORE_WIN32_EVENT_MOUSE_OUT             = ecore_event_type_new();
105         ECORE_WIN32_EVENT_MOUSE_WHEEL           = ecore_event_type_new();
106         ECORE_WIN32_EVENT_WINDOW_FOCUS_IN       = ecore_event_type_new();
107         ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT      = ecore_event_type_new();
108         ECORE_WIN32_EVENT_WINDOW_DAMAGE         = ecore_event_type_new();
109         ECORE_WIN32_EVENT_WINDOW_CREATE         = ecore_event_type_new();
110         ECORE_WIN32_EVENT_WINDOW_DESTROY        = ecore_event_type_new();
111         ECORE_WIN32_EVENT_WINDOW_SHOW           = ecore_event_type_new();
112         ECORE_WIN32_EVENT_WINDOW_HIDE           = ecore_event_type_new();
113         ECORE_WIN32_EVENT_WINDOW_CONFIGURE      = ecore_event_type_new();
114         ECORE_WIN32_EVENT_WINDOW_RESIZE         = ecore_event_type_new();
115         ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
116      }
117
118    _ecore_win32_init_count++;
119
120    return _ecore_win32_init_count;
121 }
122
123 int
124 ecore_win32_shutdown()
125 {
126    _ecore_win32_init_count++;
127    if (_ecore_win32_init_count > 0) return _ecore_win32_init_count;
128    if (!_ecore_win32_instance) return _ecore_win32_init_count;
129
130    UnregisterClass(ECORE_WIN32_WINDOW_CLASS, _ecore_win32_instance);
131    FreeLibrary(_ecore_win32_instance);
132    _ecore_win32_instance = NULL;
133
134    if (_ecore_win32_init_count < 0) _ecore_win32_init_count = 0;
135
136    return _ecore_win32_init_count;
137 }
138
139 int
140 ecore_win32_screen_depth_get()
141 {
142    HDC dc;
143    int depth;
144
145    dc = GetDC(NULL);
146    if (!dc)
147      return 0;
148
149    depth = GetDeviceCaps(dc, BITSPIXEL);
150    ReleaseDC(NULL, dc);
151
152    return depth;
153 }
154
155 /**
156  * Sets the timeout for a double and triple clicks to be flagged.
157  *
158  * This sets the time between clicks before the double_click flag is
159  * set in a button down event. If 3 clicks occur within double this
160  * time, the triple_click flag is also set.
161  *
162  * @param t The time in seconds
163  */
164 void
165 ecore_win32_double_click_time_set(double t)
166 {
167    if (t < 0.0) t = 0.0;
168    _ecore_win32_double_click_time = t;
169 }
170
171 /**
172  * Retrieves the double and triple click flag timeout.
173  *
174  * See @ref ecore_win32_double_click_time_set for more information.
175  *
176  * @return The timeout for double clicks in seconds.
177  */
178 double
179 ecore_win32_double_click_time_get(void)
180 {
181    return _ecore_win32_double_click_time;
182 }
183
184 /**
185  * Return the last event time
186  */
187 double
188 ecore_win32_current_time_get(void)
189 {
190    return _ecore_win32_event_last_time;
191 }
192
193
194 /***** Private functions definitions *****/
195
196
197 LRESULT CALLBACK
198 _ecore_win32_window_procedure(HWND   window,
199                               UINT   message,
200                               WPARAM window_param,
201                               LPARAM data_param)
202 {
203    Ecore_Win32_Callback_Data *data;
204    POINTS                     pt;
205    DWORD                      coord;
206
207    data = (Ecore_Win32_Callback_Data *)malloc(sizeof(Ecore_Win32_Callback_Data));
208    if (!data) return DefWindowProc(window, message, window_param, data_param);
209
210    data->window = window;
211    data->message = message;
212    data->window_param = window_param;
213    data->data_param = data_param;
214    data->time = GetMessageTime();
215    coord = GetMessagePos();
216    pt = MAKEPOINTS(coord);
217    data->x = pt.x;
218    data->y = pt.y;
219
220    switch (data->message)
221      {
222        /* Keyboard input notifications */
223      case WM_KEYDOWN:
224        printf (" * ecore message : keystroke down\n");
225        _ecore_win32_event_handle_key_press(data, 1);
226        return 0;
227      case WM_CHAR:
228        _ecore_win32_event_handle_key_press(data, 0);
229        return 0;
230      case WM_KEYUP:
231        printf (" * ecore message : keystroke up\n");
232        _ecore_win32_event_handle_key_release(data, 1);
233        return 0;
234      case WM_SETFOCUS:
235        printf (" * ecore message : focus in\n");
236        _ecore_win32_event_handle_focus_in(data);
237        return 0;
238      case WM_KILLFOCUS:
239        printf (" * ecore message : focus out\n");
240        _ecore_win32_event_handle_focus_out(data);
241        return 0;
242        /* Mouse input notifications */
243      case WM_LBUTTONDOWN:
244        printf (" * ecore message : lbuttondown\n");
245        _ecore_win32_event_handle_button_press(data, 1);
246        return 0;
247      case WM_MBUTTONDOWN:
248        printf (" * ecore message : mbuttondown\n");
249        _ecore_win32_event_handle_button_press(data, 2);
250        return 0;
251      case WM_RBUTTONDOWN:
252        printf (" * ecore message : rbuttondown\n");
253        _ecore_win32_event_handle_button_press(data, 3);
254        return 0;
255      case WM_LBUTTONUP:
256        printf (" * ecore message : lbuttonup\n");
257        _ecore_win32_event_handle_button_release(data, 1);
258        return 0;
259      case WM_MBUTTONUP:
260        printf (" * ecore message : mbuttonup\n");
261        _ecore_win32_event_handle_button_release(data, 2);
262        return 0;
263      case WM_RBUTTONUP:
264        printf (" * ecore message : rbuttonup\n");
265        _ecore_win32_event_handle_button_release(data, 3);
266        return 0;
267      case WM_MOUSEMOVE:
268        {
269           RECT                        rect;
270           struct _Ecore_Win32_Window *w = NULL;
271
272           w = (struct _Ecore_Win32_Window *)GetWindowLong(window, GWL_USERDATA);
273
274           if (GetClientRect(window, &rect))
275           {
276              POINT pt;
277
278              pt.x = GET_X_LPARAM(data_param);
279              pt.y = GET_Y_LPARAM(data_param);
280              if (!PtInRect(&rect, pt))
281                {
282                   if (w->pointer_is_in)
283                     {
284                        w->pointer_is_in = 0;
285                        _ecore_win32_event_handle_leave_notify(data);
286                     }
287                }
288              else
289                {
290                   if (!w->pointer_is_in)
291                     {
292                        w->pointer_is_in = 1;
293                        _ecore_win32_event_handle_enter_notify(data);
294                     }
295
296                }
297           }
298           _ecore_win32_event_handle_motion_notify(data);
299
300           return 0;
301        }
302      case WM_MOUSEWHEEL:
303        printf (" * ecore message : mouse wheel\n");
304        _ecore_win32_event_handle_button_press(data, 4);
305        return 0;
306        /* Window notifications */
307      case WM_CREATE:
308        {
309          RECT rect;
310          GetClientRect(window, &rect);
311          printf (" *** ecore message : create %ld %ld\n",
312                  rect.right - rect.left, rect.bottom - rect.top);
313        }
314        _ecore_win32_event_handle_create_notify(data);
315        return 0;
316      case WM_DESTROY:
317        printf (" * ecore message : destroy\n");
318        _ecore_win32_event_handle_destroy_notify(data);
319        return 0;
320      case WM_SHOWWINDOW:
321        {
322          RECT rect;
323          GetClientRect(window, &rect);
324          printf (" *** ecore message : show %ld %ld\n",
325                  rect.right - rect.left, rect.bottom - rect.top);
326        }
327        if ((data->data_param == SW_OTHERUNZOOM) ||
328            (data->data_param == SW_OTHERUNZOOM))
329          return 0;
330
331        if (data->window_param)
332          _ecore_win32_event_handle_map_notify(data);
333        else
334          _ecore_win32_event_handle_unmap_notify(data);
335
336        return 0;
337      case WM_CLOSE:
338        printf (" * ecore message : close\n");
339        _ecore_win32_event_handle_delete_request(data);
340        return 0;
341      case WM_MOVING:
342        printf (" * ecore message : moving\n");
343        return TRUE;
344      case WM_MOVE:
345        printf (" * ecore message : moved\n");
346        return 0;
347      case WM_SIZING:
348        printf (" * ecore message : sizing\n");
349        _ecore_win32_event_handle_resize(data);
350        _ecore_win32_event_handle_configure_notify(data);
351        return TRUE;
352      case WM_SIZE:
353        printf (" * ecore message : sized\n");
354        return 0;
355 /*      case WM_WINDOWPOSCHANGING: */
356 /*        { */
357 /*          RECT rect; */
358 /*          GetClientRect(window, &rect); */
359 /*          printf (" *** ecore message : WINDOWPOSCHANGING %ld %ld\n", */
360 /*                  rect.right - rect.left, rect.bottom - rect.top); */
361 /*        } */
362 /*        _ecore_win32_event_handle_configure_notify(data); */
363 /*        return 0; */
364      case WM_WINDOWPOSCHANGED:
365        {
366          RECT rect;
367          GetClientRect(window, &rect);
368          printf (" *** ecore message : WINDOWPOSCHANGED %ld %ld\n",
369                  rect.right - rect.left, rect.bottom - rect.top);
370        }
371        _ecore_win32_event_handle_configure_notify(data);
372        return 0;
373      case WM_ENTERSIZEMOVE :
374        printf (" * ecore message : WM_ENTERSIZEMOVE \n");
375        return 0;
376      case WM_EXITSIZEMOVE:
377        printf (" * ecore message : WM_EXITSIZEMOVE\n");
378        return 0;
379        /* GDI notifications */
380      case WM_PAINT:
381        {
382          RECT rect;
383
384          printf (" * ecore message : paint\n");
385          if (GetUpdateRect(window, &rect, FALSE))
386            {
387               PAINTSTRUCT ps;
388               HDC         hdc;
389
390               hdc = BeginPaint(window, &ps);
391               data->update = rect;
392               _ecore_win32_event_handle_expose(data);
393               EndPaint(window, &ps);
394               printf (" *    %ld %ld %ld %ld\n",
395                       rect.left,
396                       rect.top,
397                       rect.right - rect.left,
398                       rect.bottom - rect.top);
399            }
400          return 0;
401        }
402      case WM_SETREDRAW:
403        printf (" * ecore message : WM_SETREDRAW\n");
404        return 0;
405      case WM_SYNCPAINT:
406        printf (" * ecore message : WM_SYNCPAINT\n");
407        return 0;
408      default:
409        return DefWindowProc(window, message, window_param, data_param);
410      }
411
412 }