summaryrefslogtreecommitdiff
path: root/src/lib/ecore_win32
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-12-02 22:35:45 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-12-02 22:35:45 +0000
commit7d6010b12c47a20e492da808e3192c3f87dab619 (patch)
tree26c6fd189e046a76560c0bc740b85f4d767ae399 /src/lib/ecore_win32
parent53fc441d5475155965d92da89502fe4634a561b2 (diff)
merge: add escape ecore, fix several bugs
SVN revision: 79995
Diffstat (limited to 'src/lib/ecore_win32')
-rw-r--r--src/lib/ecore_win32/Ecore_Win32.h526
-rw-r--r--src/lib/ecore_win32/ecore_win32.c841
-rw-r--r--src/lib/ecore_win32/ecore_win32_cursor.c305
-rwxr-xr-xsrc/lib/ecore_win32/ecore_win32_dnd.c221
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp209
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_data_object.h49
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp92
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_drop_source.h36
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp232
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_drop_target.h47
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp157
-rw-r--r--src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h50
-rw-r--r--src/lib/ecore_win32/ecore_win32_event.c1307
-rw-r--r--src/lib/ecore_win32/ecore_win32_private.h170
-rw-r--r--src/lib/ecore_win32/ecore_win32_window.c1418
15 files changed, 5660 insertions, 0 deletions
diff --git a/src/lib/ecore_win32/Ecore_Win32.h b/src/lib/ecore_win32/Ecore_Win32.h
new file mode 100644
index 0000000000..ae1bd4ec8c
--- /dev/null
+++ b/src/lib/ecore_win32/Ecore_Win32.h
@@ -0,0 +1,526 @@
1#ifndef __ECORE_WIN32_H__
2#define __ECORE_WIN32_H__
3
4/*
5 * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND
6 * THE API MAY CHANGE.
7 */
8
9#ifndef ECORE_WIN32_WIP_POZEFLKSD
10# ifdef _MSC_VER
11# pragma message ("You are using a work in progress API. This API is not stable")
12# pragma message ("and is subject to change. You use this at your own risk.")
13# else
14# warning "You are using a work in progress API. This API is not stable"
15# warning "and is subject to change. You use this at your own risk."
16# endif
17#endif
18
19#include <Eina.h>
20
21#ifdef EAPI
22# undef EAPI
23#endif
24
25#ifdef _WIN32
26# ifdef EFL_ECORE_WIN32_BUILD
27# ifdef DLL_EXPORT
28# define EAPI __declspec(dllexport)
29# else
30# define EAPI
31# endif /* ! DLL_EXPORT */
32# else
33# define EAPI __declspec(dllimport)
34# endif /* ! EFL_ECORE_WIN32_BUILD */
35#else
36# ifdef __GNUC__
37# if __GNUC__ >= 4
38# define EAPI __attribute__ ((visibility("default")))
39# else
40# define EAPI
41# endif
42# else
43# define EAPI
44# endif
45#endif /* ! _WIN32 */
46
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/**
53 * @defgroup Ecore_Win32_Group Ecore_Win32 library
54 *
55 * @{
56 */
57
58/**
59 * @typedef Ecore_Win32_Window_State
60 * State of a window.
61 */
62typedef enum
63{
64 ECORE_WIN32_WINDOW_STATE_ICONIFIED, /**< iconified window */
65 ECORE_WIN32_WINDOW_STATE_MODAL, /**< modal dialog box */
66 ECORE_WIN32_WINDOW_STATE_STICKY, /**< sticky window */
67 ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT, /**< maximum vertical sized window */
68 ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ, /**< maximum horizontal sized window */
69 ECORE_WIN32_WINDOW_STATE_MAXIMIZED, /**< maximum sized window */
70 ECORE_WIN32_WINDOW_STATE_SHADED, /**< shaded window */
71 ECORE_WIN32_WINDOW_STATE_HIDDEN, /**< hidden (minimized or iconified) window */
72 ECORE_WIN32_WINDOW_STATE_FULLSCREEN, /**< fullscreen window */
73 ECORE_WIN32_WINDOW_STATE_ABOVE, /**< above window */
74 ECORE_WIN32_WINDOW_STATE_BELOW, /**< below window */
75 ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION, /**< To document */
76 ECORE_WIN32_WINDOW_STATE_UNKNOWN /**< Unknown state */
77} Ecore_Win32_Window_State;
78
79/**
80 * @typedef Ecore_Win32_Window_Type
81 * Type of a window.
82 */
83typedef enum
84{
85 ECORE_WIN32_WINDOW_TYPE_DESKTOP, /**< Desktop feature */
86 ECORE_WIN32_WINDOW_TYPE_DOCK, /**< Dock window (should be on top of other windows) */
87 ECORE_WIN32_WINDOW_TYPE_TOOLBAR, /**< Toolbar window */
88 ECORE_WIN32_WINDOW_TYPE_MENU, /**< Menu window */
89 ECORE_WIN32_WINDOW_TYPE_UTILITY, /**< Small persistent utility window, such as a palette or toolbox */
90 ECORE_WIN32_WINDOW_TYPE_SPLASH, /**< Splash screen window displayed as an application is starting up */
91 ECORE_WIN32_WINDOW_TYPE_DIALOG, /**< Dialog window */
92 ECORE_WIN32_WINDOW_TYPE_NORMAL, /**< Normal top-level window */
93 ECORE_WIN32_WINDOW_TYPE_UNKNOWN /**< Unknown type */
94} Ecore_Win32_Window_Type;
95
96/**
97 * @typedef Ecore_Win32_Cursor_Shape
98 * Shape of a cursor.
99 */
100typedef enum
101{
102 ECORE_WIN32_CURSOR_SHAPE_APP_STARTING, /**< Standard arrow and small hourglass */
103 ECORE_WIN32_CURSOR_SHAPE_ARROW, /**< Standard arrow */
104 ECORE_WIN32_CURSOR_SHAPE_CROSS, /**< Crosshair */
105 ECORE_WIN32_CURSOR_SHAPE_HAND, /**< Hand */
106 ECORE_WIN32_CURSOR_SHAPE_HELP, /**< Arrow and question mark */
107 ECORE_WIN32_CURSOR_SHAPE_I_BEAM, /**< I-beam */
108 ECORE_WIN32_CURSOR_SHAPE_NO, /**< Slashed circle */
109 ECORE_WIN32_CURSOR_SHAPE_SIZE_ALL, /**< Four-pointed arrow pointing north, south, east, and west */
110 ECORE_WIN32_CURSOR_SHAPE_SIZE_NESW, /**< Double-pointed arrow pointing northeast and southwest */
111 ECORE_WIN32_CURSOR_SHAPE_SIZE_NS, /**< Double-pointed arrow pointing north and south */
112 ECORE_WIN32_CURSOR_SHAPE_SIZE_NWSE, /**< Double-pointed arrow pointing northwest and southeast */
113 ECORE_WIN32_CURSOR_SHAPE_SIZE_WE, /**< Double-pointed arrow pointing west and east */
114 ECORE_WIN32_CURSOR_SHAPE_UP_ARROW, /**< Vertical arrow */
115 ECORE_WIN32_CURSOR_SHAPE_WAIT /**< Hourglass */
116} Ecore_Win32_Cursor_Shape;
117
118/**
119 * @typedef Ecore_Win32_DnD_State
120 * State of a DnD operation.
121 */
122typedef enum
123{
124 ECORE_WIN32_DND_EVENT_DRAG_ENTER = 1, /**< Drag enter */
125 ECORE_WIN32_DND_EVENT_DRAG_OVER = 2, /**< Drag over */
126 ECORE_WIN32_DND_EVENT_DRAG_LEAVE = 3, /**< Drag leave */
127 ECORE_WIN32_DND_EVENT_DROP = 4 /**< Drop */
128} Ecore_Win32_DnD_State;
129
130/**
131 * @typedef Ecore_Win32_Window
132 * Abstract type for a window.
133 */
134typedef struct _Ecore_Win32_Window Ecore_Win32_Window;
135
136/**
137 * @typedef Ecore_Win32_Cursor
138 * Abstract type for a cursor.
139 */
140typedef void Ecore_Win32_Cursor;
141
142
143/**
144 * @typedef Ecore_Win32_Event_Mouse_In
145 * Event sent when the mouse enters the window.
146 */
147typedef struct _Ecore_Win32_Event_Mouse_In Ecore_Win32_Event_Mouse_In;
148
149/**
150 * @typedef Ecore_Win32_Event_Mouse_Out
151 * Event sent when the mouse leaves the window.
152 */
153typedef struct _Ecore_Win32_Event_Mouse_Out Ecore_Win32_Event_Mouse_Out;
154
155/**
156 * @typedef Ecore_Win32_Event_Window_Focus_In
157 * Event sent when the window gets the focus.
158 */
159typedef struct _Ecore_Win32_Event_Window_Focus_In Ecore_Win32_Event_Window_Focus_In;
160
161/**
162 * @typedef Ecore_Win32_Event_Window_Focus_Out
163 * Event sent when the window looses the focus.
164 */
165typedef struct _Ecore_Win32_Event_Window_Focus_Out Ecore_Win32_Event_Window_Focus_Out;
166
167/**
168 * @typedef Ecore_Win32_Event_Window_Damage
169 * Event sent when the window is damaged.
170 */
171typedef struct _Ecore_Win32_Event_Window_Damage Ecore_Win32_Event_Window_Damage;
172
173/**
174 * @typedef Ecore_Win32_Event_Window_Create
175 * Event sent when the window is created.
176 */
177typedef struct _Ecore_Win32_Event_Window_Create Ecore_Win32_Event_Window_Create;
178
179/**
180 * @typedef Ecore_Win32_Event_Window_Destroy
181 * Event sent when the window is destroyed.
182 */
183typedef struct _Ecore_Win32_Event_Window_Destroy Ecore_Win32_Event_Window_Destroy;
184
185/**
186 * @typedef Ecore_Win32_Event_Window_Hide
187 * Event sent when the window is hidden.
188 */
189typedef struct _Ecore_Win32_Event_Window_Hide Ecore_Win32_Event_Window_Hide;
190
191/**
192 * @typedef Ecore_Win32_Event_Window_Show
193 * Event sent when the window is shown.
194 */
195typedef struct _Ecore_Win32_Event_Window_Show Ecore_Win32_Event_Window_Show;
196
197/**
198 * @typedef Ecore_Win32_Event_Window_Configure
199 * Event sent when the window is configured.
200 */
201typedef struct _Ecore_Win32_Event_Window_Configure Ecore_Win32_Event_Window_Configure;
202
203/**
204 * @typedef Ecore_Win32_Event_Window_Resize
205 * Event sent when the window is resized.
206 */
207typedef struct _Ecore_Win32_Event_Window_Resize Ecore_Win32_Event_Window_Resize;
208
209/**
210 * @typedef Ecore_Win32_Event_Window_Delete_Request
211 * Event sent when the window is deleted.
212 */
213typedef struct _Ecore_Win32_Event_Window_Delete_Request Ecore_Win32_Event_Window_Delete_Request;
214
215/**
216 * @struct _Ecore_Win32_Event_Mouse_In
217 * Event sent when the mouse enters the window.
218 */
219struct _Ecore_Win32_Event_Mouse_In
220{
221 Ecore_Win32_Window *window; /**< The window that received the event */
222 int x; /**< The x coordinate where the mouse leaved */
223 int y; /**< The y coordinate where the mouse entered */
224 unsigned long timestamp; /**< The time the event occurred */
225};
226
227/**
228 * @struct _Ecore_Win32_Event_Mouse_Out
229 * Event sent when the mouse leaves the window.
230 */
231struct _Ecore_Win32_Event_Mouse_Out
232{
233 Ecore_Win32_Window *window; /**< The window that received the event */
234 int x; /**< The x coordinate where the mouse leaved */
235 int y; /**< The y coordinate where the mouse leaved */
236 unsigned long timestamp; /**< The time the event occurred */
237};
238
239/**
240 * @struct _Ecore_Win32_Event_Window_Focus_In
241 * Event sent when the window gets the focus.
242 */
243struct _Ecore_Win32_Event_Window_Focus_In
244{
245 Ecore_Win32_Window *window; /**< The window that received the event */
246 unsigned long timestamp; /**< The time the event occurred */
247};
248
249/**
250 * @struct _Ecore_Win32_Event_Window_Focus_Out
251 * Event sent when the window looses the focus.
252 */
253struct _Ecore_Win32_Event_Window_Focus_Out
254{
255 Ecore_Win32_Window *window; /**< The window that received the event */
256 unsigned long timestamp; /**< The time the event occurred */
257};
258
259/**
260 * @struct _Ecore_Win32_Event_Window_Damage
261 * Event sent when the window is damaged.
262 */
263struct _Ecore_Win32_Event_Window_Damage
264{
265 Ecore_Win32_Window *window; /**< The window that received the event */
266 int x; /**< The x coordinate of the top left corner of the damaged region */
267 int y; /**< The y coordinate of the top left corner of the damaged region */
268 int width; /**< The width of the damaged region */
269 int height; /**< The time the event occurred */
270 unsigned long timestamp; /**< The time the event occurred */
271};
272
273/**
274 * @struct _Ecore_Win32_Event_Window_Create
275 * Event sent when the window is created.
276 */
277struct _Ecore_Win32_Event_Window_Create
278{
279 Ecore_Win32_Window *window; /**< The window that received the event */
280 unsigned long timestamp; /**< The time the event occurred */
281};
282
283/**
284 * @struct _Ecore_Win32_Event_Window_Destroy
285 * Event sent when the window is destroyed.
286 */
287struct _Ecore_Win32_Event_Window_Destroy
288{
289 Ecore_Win32_Window *window; /**< The window that received the event */
290 unsigned long timestamp; /**< The time the event occurred */
291};
292
293/**
294 * @struct _Ecore_Win32_Event_Window_Hide
295 * Event sent when the window is hidden.
296 */
297struct _Ecore_Win32_Event_Window_Hide
298{
299 Ecore_Win32_Window *window; /**< The window that received the event */
300 unsigned long timestamp; /**< The time the event occurred */
301};
302
303/**
304 * @struct _Ecore_Win32_Event_Window_Show
305 * Event sent when the window is shown.
306 */
307struct _Ecore_Win32_Event_Window_Show
308{
309 Ecore_Win32_Window *window; /**< The window that received the event */
310 unsigned long timestamp; /**< The time the event occurred */
311};
312
313/**
314 * @struct _Ecore_Win32_Event_Window_Configure
315 * Event sent when the window is configured.
316 */
317struct _Ecore_Win32_Event_Window_Configure
318{
319 Ecore_Win32_Window *window; /**< The window that received the event */
320 Ecore_Win32_Window *abovewin;
321 int x; /**< The new x coordinate of the top left corner */
322 int y; /**< The new y coordinate of the top left corner */
323 int width; /**< The new width */
324 int height; /**< The new height */
325 unsigned long timestamp; /**< The time the event occurred */
326};
327
328/**
329 * @struct _Ecore_Win32_Event_Window_Resize
330 * Event sent when the window is resized.
331 */
332struct _Ecore_Win32_Event_Window_Resize
333{
334 Ecore_Win32_Window *window; /**< The window that received the event */
335 int width; /**< The new width */
336 int height; /**< The new height */
337 unsigned long timestamp; /**< The time the event occurred */
338};
339
340/**
341 * @struct _Ecore_Win32_Event_Window_Delete_Request
342 * Event sent when the window is deleted.
343 */
344struct _Ecore_Win32_Event_Window_Delete_Request
345{
346 Ecore_Win32_Window *window; /**< The window that received the event */
347 unsigned long timestamp; /**< The time the event occurred */
348};
349
350/**
351 * @typedef Ecore_Win32_Dnd_DropTarget_Callback
352 * Callback type for Drop operations. See ecore_win32_dnd_register_drop_target().
353 */
354typedef int (*Ecore_Win32_Dnd_DropTarget_Callback)(void *window, int event, int pt_x, int pt_y, void *data, int size);
355
356EAPI extern int ECORE_WIN32_EVENT_MOUSE_IN; /**< Ecore_Event for the #Ecore_Win32_Event_Mouse_In event */
357EAPI extern int ECORE_WIN32_EVENT_MOUSE_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Mouse_Out event */
358EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_In event */
359EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_Out event */
360EAPI extern int ECORE_WIN32_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the Ecore_Win32_Event_Damage event */
361EAPI extern int ECORE_WIN32_EVENT_WINDOW_CREATE; /**< Ecore_Event for the Ecore_Win32_Event_Create event */
362EAPI extern int ECORE_WIN32_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the Ecore_Win32_Event_Destroy event */
363EAPI extern int ECORE_WIN32_EVENT_WINDOW_HIDE; /**< Ecore_Event for the Ecore_Win32_Event_Hide event */
364EAPI extern int ECORE_WIN32_EVENT_WINDOW_SHOW; /**< Ecore_Event for the Ecore_Win32_Event_Show event */
365EAPI extern int ECORE_WIN32_EVENT_WINDOW_CONFIGURE; /**< Ecore_Event for the Ecore_Win32_Event_Configure event */
366EAPI extern int ECORE_WIN32_EVENT_WINDOW_RESIZE; /**< Ecore_Event for the Ecore_Win32_Event_Resize event */
367EAPI extern int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Delete_Request event */
368
369
370/* Core */
371
372EAPI int ecore_win32_init();
373EAPI int ecore_win32_shutdown();
374EAPI int ecore_win32_screen_depth_get();
375EAPI void ecore_win32_double_click_time_set(double t);
376EAPI double ecore_win32_double_click_time_get(void);
377EAPI unsigned long ecore_win32_current_time_get(void);
378
379/* Window */
380
381EAPI Ecore_Win32_Window *ecore_win32_window_new(Ecore_Win32_Window *parent,
382 int x,
383 int y,
384 int width,
385 int height);
386EAPI Ecore_Win32_Window *ecore_win32_window_override_new(Ecore_Win32_Window *parent,
387 int x,
388 int y,
389 int width,
390 int height);
391
392EAPI void ecore_win32_window_free(Ecore_Win32_Window *window);
393
394EAPI void *ecore_win32_window_hwnd_get(Ecore_Win32_Window *window);
395
396EAPI void ecore_win32_window_move(Ecore_Win32_Window *window,
397 int x,
398 int y);
399
400EAPI void ecore_win32_window_resize(Ecore_Win32_Window *window,
401 int width,
402 int height);
403
404EAPI void ecore_win32_window_move_resize(Ecore_Win32_Window *window,
405 int x,
406 int y,
407 int width,
408 int height);
409
410EAPI void ecore_win32_window_geometry_get(Ecore_Win32_Window *window,
411 int *x,
412 int *y,
413 int *width,
414 int *height);
415
416EAPI void ecore_win32_window_size_get(Ecore_Win32_Window *window,
417 int *width,
418 int *height);
419
420EAPI void ecore_win32_window_size_min_set(Ecore_Win32_Window *window,
421 unsigned int min_width,
422 unsigned int min_height);
423
424EAPI void ecore_win32_window_size_min_get(Ecore_Win32_Window *window,
425 unsigned int *min_width,
426 unsigned int *min_height);
427
428EAPI void ecore_win32_window_size_max_set(Ecore_Win32_Window *window,
429 unsigned int max_width,
430 unsigned int max_height);
431
432EAPI void ecore_win32_window_size_max_get(Ecore_Win32_Window *window,
433 unsigned int *max_width,
434 unsigned int *max_height);
435
436EAPI void ecore_win32_window_size_base_set(Ecore_Win32_Window *window,
437 unsigned int base_width,
438 unsigned int base_height);
439
440EAPI void ecore_win32_window_size_base_get(Ecore_Win32_Window *window,
441 unsigned int *base_width,
442 unsigned int *base_height);
443
444EAPI void ecore_win32_window_size_step_set(Ecore_Win32_Window *window,
445 unsigned int step_width,
446 unsigned int step_height);
447
448EAPI void ecore_win32_window_size_step_get(Ecore_Win32_Window *window,
449 unsigned int *step_width,
450 unsigned int *step_height);
451
452EAPI void ecore_win32_window_show(Ecore_Win32_Window *window);
453
454EAPI void ecore_win32_window_hide(Ecore_Win32_Window *window);
455
456EAPI void ecore_win32_window_raise(Ecore_Win32_Window *window);
457
458EAPI void ecore_win32_window_lower(Ecore_Win32_Window *window);
459
460EAPI void ecore_win32_window_title_set(Ecore_Win32_Window *window,
461 const char *title);
462
463EAPI void ecore_win32_window_focus(Ecore_Win32_Window *window);
464
465EAPI void *ecore_win32_window_focus_get(void);
466
467EAPI void ecore_win32_window_iconified_set(Ecore_Win32_Window *window,
468 Eina_Bool on);
469
470EAPI void ecore_win32_window_borderless_set(Ecore_Win32_Window *window,
471 Eina_Bool on);
472
473EAPI void ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window,
474 Eina_Bool on);
475
476EAPI void ecore_win32_window_cursor_set(Ecore_Win32_Window *window,
477 Ecore_Win32_Cursor *cursor);
478
479EAPI void ecore_win32_window_state_set(Ecore_Win32_Window *window,
480 Ecore_Win32_Window_State *state,
481 unsigned int num);
482
483EAPI void ecore_win32_window_state_request_send(Ecore_Win32_Window *window,
484 Ecore_Win32_Window_State state,
485 unsigned int set);
486
487EAPI void ecore_win32_window_type_set(Ecore_Win32_Window *window,
488 Ecore_Win32_Window_Type type);
489
490/* Cursor */
491
492EAPI Ecore_Win32_Cursor *ecore_win32_cursor_new(const void *pixels_and,
493 const void *pixels_xor,
494 int width,
495 int height,
496 int hot_x,
497 int hot_y);
498
499EAPI void ecore_win32_cursor_free(Ecore_Win32_Cursor *cursor);
500
501EAPI Ecore_Win32_Cursor *ecore_win32_cursor_shaped_new(Ecore_Win32_Cursor_Shape shape);
502
503EAPI void ecore_win32_cursor_size_get(int *width, int *height);
504
505
506
507/* Drag and drop */
508EAPI int ecore_win32_dnd_init();
509EAPI int ecore_win32_dnd_shutdown();
510EAPI Eina_Bool ecore_win32_dnd_begin(const char *data,
511 int size);
512EAPI Eina_Bool ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window,
513 Ecore_Win32_Dnd_DropTarget_Callback callback);
514EAPI void ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window);
515
516/**
517 * @}
518 */
519
520
521#ifdef __cplusplus
522}
523#endif
524
525
526#endif /* __ECORE_WIN32_H__ */
diff --git a/src/lib/ecore_win32/ecore_win32.c b/src/lib/ecore_win32/ecore_win32.c
new file mode 100644
index 0000000000..b571d74d1b
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32.c
@@ -0,0 +1,841 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdlib.h>
6
7#define WIN32_LEAN_AND_MEAN
8#include <windows.h>
9#undef WIN32_LEAN_AND_MEAN
10#include <windowsx.h>
11
12#include <Eina.h>
13#include <Ecore.h>
14#include <Ecore_Input.h>
15
16#include "Ecore_Win32.h"
17#include "ecore_win32_private.h"
18
19/*============================================================================*
20 * Local *
21 *============================================================================*/
22
23/**
24 * @cond LOCAL
25 */
26
27/* OLE IID for Drag'n Drop */
28
29# define INITGUID
30# include <basetyps.h>
31DEFINE_OLEGUID(IID_IEnumFORMATETC, 0x00000103L, 0, 0);
32DEFINE_OLEGUID(IID_IDataObject, 0x0000010EL, 0, 0);
33DEFINE_OLEGUID(IID_IDropSource, 0x00000121L, 0, 0);
34DEFINE_OLEGUID(IID_IDropTarget, 0x00000122L, 0, 0);
35DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0);
36
37#define IDI_ICON 101
38
39static int _ecore_win32_init_count = 0;
40
41static void
42_ecore_win32_size_check(Ecore_Win32_Window *win, int w, int h, int *dx, int *dy)
43{
44 int minimal_width;
45 int minimal_height;
46
47 minimal_width = GetSystemMetrics(SM_CXMIN);
48 minimal_height = GetSystemMetrics(SM_CYMIN);
49 if ((w) < MAX(minimal_width, (int)win->min_width))
50 *dx = 0;
51 if ((w) > (int)win->max_width)
52 *dx = 0;
53 if ((h) < MAX(minimal_height, (int)win->min_height))
54 *dy = 0;
55 if ((h) > (int)win->max_height)
56 *dy = 0;
57}
58
59LRESULT CALLBACK
60_ecore_win32_window_procedure(HWND window,
61 UINT message,
62 WPARAM window_param,
63 LPARAM data_param)
64{
65 Ecore_Win32_Callback_Data *data;
66 POINTS point;
67 DWORD coord;
68
69 data = (Ecore_Win32_Callback_Data *)malloc(sizeof(Ecore_Win32_Callback_Data));
70 if (!data) return DefWindowProc(window, message, window_param, data_param);
71
72 data->window = window;
73 data->message = message;
74 data->window_param = window_param;
75 data->data_param = data_param;
76 data->timestamp = GetMessageTime();
77 coord = GetMessagePos();
78 point = MAKEPOINTS(coord);
79 data->x = point.x;
80 data->y = point.y;
81 data->discard_ctrl = EINA_FALSE;
82
83 switch (data->message)
84 {
85 /* Keyboard input notifications */
86 case WM_KEYDOWN:
87 case WM_SYSKEYDOWN:
88 if ((data->message == WM_KEYDOWN) &&
89 (data->window_param == VK_CONTROL) &&
90 ((HIWORD(data->data_param) & KF_EXTENDED) == 0))
91 {
92 /* Ctrl left key is pressed */
93 BOOL res;
94 MSG next_msg;
95
96 /*
97 * we check if the next message
98 * - is a WM_KEYDOWN
99 * - has the same timestamp than the Ctrl one
100 * - is the key press of the right Alt key
101 */
102 res = PeekMessage(&next_msg, data->window,
103 WM_KEYDOWN, WM_KEYDOWN,
104 PM_NOREMOVE);
105 if (res &&
106 (next_msg.wParam == VK_MENU) &&
107 (next_msg.time == data->timestamp) &&
108 (HIWORD(next_msg.lParam) & KF_EXTENDED))
109 {
110 INF("discard left Ctrl key press (sent by AltGr key press)");
111 data->discard_ctrl = EINA_TRUE;
112 }
113 }
114 _ecore_win32_event_handle_key_press(data, 1);
115 return 0;
116 case WM_CHAR:
117 case WM_SYSCHAR:
118 INF("char message");
119 _ecore_win32_event_handle_key_press(data, 0);
120 return 0;
121 case WM_KEYUP:
122 case WM_SYSKEYUP:
123 INF("keyup message");
124 if ((data->window_param == VK_CONTROL) &&
125 ((HIWORD(data->data_param) & KF_EXTENDED) == 0))
126 {
127 /* Ctrl left key is pressed */
128 BOOL res;
129 MSG next_msg;
130
131 /*
132 * we check if the next message
133 * - is a WM_KEYUP or WM_SYSKEYUP
134 * - has the same timestamp than the Ctrl one
135 * - is the key release of the right Alt key
136 */
137 res = PeekMessage(&next_msg, data->window,
138 WM_KEYUP, WM_SYSKEYUP,
139 PM_NOREMOVE);
140 if (res &&
141 ((next_msg.message == WM_KEYUP) ||
142 (next_msg.message == WM_SYSKEYUP)) &&
143 (next_msg.wParam == VK_MENU) &&
144 (next_msg.time == data->timestamp) &&
145 (HIWORD(next_msg.lParam) & KF_EXTENDED))
146 {
147 INF("discard left Ctrl key release (sent by AltGr key release)");
148 data->discard_ctrl = EINA_TRUE;
149 }
150 }
151 _ecore_win32_event_handle_key_release(data);
152 return 0;
153 case WM_SETFOCUS:
154 INF("setfocus message");
155 _ecore_win32_event_handle_focus_in(data);
156 return 0;
157 case WM_KILLFOCUS:
158 INF("kill focus message");
159 _ecore_win32_event_handle_focus_out(data);
160 return 0;
161 /* Mouse input notifications */
162 case WM_LBUTTONDOWN:
163 INF("left button down message");
164 SetCapture(window);
165 _ecore_win32_event_handle_button_press(data, 1);
166 return 0;
167 case WM_MBUTTONDOWN:
168 INF("middle button down message");
169 _ecore_win32_event_handle_button_press(data, 2);
170 return 0;
171 case WM_RBUTTONDOWN:
172 INF("right button down message");
173 _ecore_win32_event_handle_button_press(data, 3);
174 return 0;
175 case WM_LBUTTONUP:
176 {
177 Ecore_Win32_Window *w = NULL;
178
179 INF("left button up message");
180
181 ReleaseCapture();
182 w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA);
183 if (w->drag.dragging)
184 {
185 w->drag.dragging = 0;
186 return 0;
187 }
188
189 _ecore_win32_event_handle_button_release(data, 1);
190 return 0;
191 }
192 case WM_MBUTTONUP:
193 INF("middle button up message");
194 _ecore_win32_event_handle_button_release(data, 2);
195 return 0;
196 case WM_RBUTTONUP:
197 INF("right button up message");
198 _ecore_win32_event_handle_button_release(data, 3);
199 return 0;
200 case WM_MOUSEMOVE:
201 {
202 RECT rect;
203 Ecore_Win32_Window *w = NULL;
204
205 INF("moue move message");
206
207 w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA);
208
209 if (w->drag.dragging)
210 {
211 POINT pt;
212
213 pt.x = GET_X_LPARAM(data_param);
214 pt.y = GET_Y_LPARAM(data_param);
215 if (ClientToScreen(window, &pt))
216 {
217 if (w->drag.type == HTCAPTION)
218 {
219 int dx;
220 int dy;
221
222 dx = pt.x - w->drag.px;
223 dy = pt.y - w->drag.py;
224 ecore_win32_window_move(w, w->drag.x + dx, w->drag.y + dy);
225 w->drag.x += dx;
226 w->drag.y += dy;
227 w->drag.px = pt.x;
228 w->drag.py = pt.y;
229 return 0;
230 }
231 if (w->drag.type == HTLEFT)
232 {
233 int dw;
234
235 dw = pt.x - w->drag.px;
236 ecore_win32_window_move_resize(w, w->drag.x + dw, w->drag.y, w->drag.w - dw, w->drag.h);
237 w->drag.x += dw;
238 w->drag.w -= dw;
239 w->drag.px = pt.x;
240 w->drag.py = pt.y;
241 return 0;
242 }
243 if (w->drag.type == HTRIGHT)
244 {
245 int dw;
246
247 dw = pt.x - w->drag.px;
248 ecore_win32_window_resize(w, w->drag.w + dw, w->drag.h);
249 w->drag.w += dw;
250 w->drag.px = pt.x;
251 w->drag.py = pt.y;
252 return 0;
253 }
254 if (w->drag.type == HTTOP)
255 {
256 int dh;
257
258 dh = pt.y - w->drag.py;
259 ecore_win32_window_move_resize(w, w->drag.x, w->drag.y + dh, w->drag.w, w->drag.h - dh);
260 w->drag.y += dh;
261 w->drag.h -= dh;
262 w->drag.px = pt.x;
263 w->drag.py = pt.y;
264 return 0;
265 }
266 if (w->drag.type == HTBOTTOM)
267 {
268 int dh;
269
270 dh = pt.y - w->drag.py;
271 ecore_win32_window_resize(w, w->drag.w, w->drag.h + dh);
272 w->drag.h += dh;
273 w->drag.px = pt.x;
274 w->drag.py = pt.y;
275 return 0;
276 }
277 if (w->drag.type == HTTOPLEFT)
278 {
279 int dx;
280 int dy;
281 int dh;
282 int dw;
283
284 dw = pt.x - w->drag.px;
285 dh = pt.y - w->drag.py;
286 dx = dw;
287 dy = dh;
288 _ecore_win32_size_check(w,
289 w->drag.w - dw, w->drag.h - dh,
290 &dx, &dy);
291
292 ecore_win32_window_move_resize(w, w->drag.x + dx, w->drag.y + dy, w->drag.w - dw, w->drag.h - dh);
293 w->drag.x += dx;
294 w->drag.y += dy;
295 w->drag.w -= dw;
296 w->drag.h -= dh;
297 w->drag.px = pt.x;
298 w->drag.py = pt.y;
299 return 0;
300 }
301 if (w->drag.type == HTTOPRIGHT)
302 {
303 int dx;
304 int dy;
305 int dh;
306 int dw;
307
308 dw = pt.x - w->drag.px;
309 dh = pt.y - w->drag.py;
310 dx = dw;
311 dy = dh;
312 _ecore_win32_size_check(w,
313 w->drag.w, w->drag.h - dh,
314 &dx, &dy);
315 ecore_win32_window_move_resize(w, w->drag.x, w->drag.y + dy, w->drag.w, w->drag.h - dh);
316 w->drag.y += dy;
317 w->drag.w += dw;
318 w->drag.h -= dh;
319 w->drag.px = pt.x;
320 w->drag.py = pt.y;
321 return 0;
322 }
323 if (w->drag.type == HTBOTTOMLEFT)
324 {
325 int dx;
326 int dy;
327 int dh;
328 int dw;
329
330 dw = pt.x - w->drag.px;
331 dh = pt.y - w->drag.py;
332 dx = dw;
333 dy = dh;
334 _ecore_win32_size_check(w,
335 w->drag.w - dw, w->drag.h + dh,
336 &dx, &dy);
337 ecore_win32_window_move_resize(w, w->drag.x + dx, w->drag.y, w->drag.w - dw, w->drag.h + dh);
338 w->drag.x += dx;
339 w->drag.w -= dw;
340 w->drag.h += dh;
341 w->drag.px = pt.x;
342 w->drag.py = pt.y;
343 return 0;
344 }
345 if (w->drag.type == HTBOTTOMRIGHT)
346 {
347 int dh;
348 int dw;
349
350 dw = pt.x - w->drag.px;
351 dh = pt.y - w->drag.py;
352 ecore_win32_window_resize(w, w->drag.w + dw, w->drag.h + dh);
353 w->drag.w += dw;
354 w->drag.h += dh;
355 w->drag.px = pt.x;
356 w->drag.py = pt.y;
357 return 0;
358 }
359 }
360 }
361
362 if (GetClientRect(window, &rect))
363 {
364 POINT pt;
365
366 INF("mouse in window");
367
368 pt.x = GET_X_LPARAM(data_param);
369 pt.y = GET_Y_LPARAM(data_param);
370 if (!PtInRect(&rect, pt))
371 {
372 if (w->pointer_is_in)
373 {
374 w->pointer_is_in = 0;
375 _ecore_win32_event_handle_leave_notify(data);
376 }
377 }
378 else
379 {
380 if (!w->pointer_is_in)
381 {
382 w->pointer_is_in = 1;
383 _ecore_win32_event_handle_enter_notify(data);
384 }
385 }
386 }
387 else
388 {
389 ERR("GetClientRect() failed");
390 }
391 _ecore_win32_event_handle_motion_notify(data);
392
393 return 0;
394 }
395 case WM_MOUSEWHEEL:
396 INF("mouse wheel message");
397 _ecore_win32_event_handle_button_press(data, 4);
398 return 0;
399 /* Window notifications */
400 case WM_CREATE:
401 INF("create window message");
402 _ecore_win32_event_handle_create_notify(data);
403 return 0;
404 case WM_DESTROY:
405 INF("destroy window message");
406 _ecore_win32_event_handle_destroy_notify(data);
407 return 0;
408 case WM_SHOWWINDOW:
409 INF("show window message");
410 if ((data->data_param == SW_OTHERUNZOOM) ||
411 (data->data_param == SW_OTHERZOOM))
412 return 0;
413
414 if (data->window_param)
415 _ecore_win32_event_handle_map_notify(data);
416 else
417 _ecore_win32_event_handle_unmap_notify(data);
418
419 return 0;
420 case WM_CLOSE:
421 INF("close window message");
422 _ecore_win32_event_handle_delete_request(data);
423 return 0;
424 case WM_GETMINMAXINFO:
425 INF("get min max info window message");
426 return TRUE;
427 case WM_MOVING:
428 INF("moving window message");
429 _ecore_win32_event_handle_configure_notify(data);
430 return TRUE;
431 case WM_MOVE:
432 INF("move window message");
433 return 0;
434 case WM_SIZING:
435 INF("sizing window message");
436 _ecore_win32_event_handle_resize(data);
437 _ecore_win32_event_handle_configure_notify(data);
438 return TRUE;
439 case WM_SIZE:
440 INF("size window message");
441 return 0;
442/* case WM_WINDOWPOSCHANGING: */
443/* { */
444/* RECT rect; */
445/* GetClientRect(window, &rect); */
446/* printf (" *** ecore message : WINDOWPOSCHANGING %ld %ld\n", */
447/* rect.right - rect.left, rect.bottom - rect.top); */
448/* } */
449/* _ecore_win32_event_handle_configure_notify(data); */
450/* return 0; */
451 case WM_WINDOWPOSCHANGED:
452 INF("position changed window message");
453 _ecore_win32_event_handle_configure_notify(data);
454 _ecore_win32_event_handle_expose(data);
455 return 0;
456 case WM_ENTERSIZEMOVE:
457 INF("enter size move window message");
458 return 0;
459 case WM_EXITSIZEMOVE:
460 INF("exit size move window message");
461 return 0;
462 case WM_NCLBUTTONDOWN:
463 INF("non client left button down window message");
464
465 if (((DWORD)window_param == HTCAPTION) ||
466 ((DWORD)window_param == HTBOTTOM) ||
467 ((DWORD)window_param == HTBOTTOMLEFT) ||
468 ((DWORD)window_param == HTBOTTOMRIGHT) ||
469 ((DWORD)window_param == HTLEFT) ||
470 ((DWORD)window_param == HTRIGHT) ||
471 ((DWORD)window_param == HTTOP) ||
472 ((DWORD)window_param == HTTOPLEFT) ||
473 ((DWORD)window_param == HTTOPRIGHT))
474 {
475 Ecore_Win32_Window *w;
476
477 w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA);
478 ecore_win32_window_geometry_get(w,
479 NULL, NULL,
480 &w->drag.w, &w->drag.h);
481 SetCapture(window);
482 w->drag.type = (DWORD)window_param;
483 w->drag.px = GET_X_LPARAM(data_param);
484 w->drag.py = GET_Y_LPARAM(data_param);
485 w->drag.dragging = 1;
486 return 0;
487 }
488 return DefWindowProc(window, message, window_param, data_param);
489 case WM_SYSCOMMAND:
490 INF("sys command window message %d", (int)window_param);
491
492 if ((((DWORD)window_param & 0xfff0) == SC_MOVE) ||
493 (((DWORD)window_param & 0xfff0) == SC_SIZE))
494 {
495 Ecore_Win32_Window *w;
496
497 INF("sys command MOVE or SIZE window message : %dx%d", GET_X_LPARAM(data_param), GET_Y_LPARAM(data_param));
498
499 w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA);
500 w->drag.dragging = 1;
501 return 0;
502 }
503 return DefWindowProc(window, message, window_param, data_param);
504 /* GDI notifications */
505 case WM_ERASEBKGND:
506 return 1;
507 case WM_PAINT:
508 {
509 RECT rect;
510
511 INF("paint message");
512
513 if (GetUpdateRect(window, &rect, FALSE))
514 {
515 PAINTSTRUCT ps;
516 HDC hdc;
517
518 hdc = BeginPaint(window, &ps);
519 data->update = rect;
520 _ecore_win32_event_handle_expose(data);
521 EndPaint(window, &ps);
522 }
523 return 0;
524 }
525 case WM_SETREDRAW:
526 INF("set redraw message");
527 return 0;
528 case WM_SYNCPAINT:
529 INF("sync paint message");
530 return 0;
531 default:
532 return DefWindowProc(window, message, window_param, data_param);
533 }
534}
535
536/**
537 * @endcond
538 */
539
540
541/*============================================================================*
542 * Global *
543 *============================================================================*/
544
545
546HINSTANCE _ecore_win32_instance = NULL;
547double _ecore_win32_double_click_time = 0.25;
548unsigned long _ecore_win32_event_last_time = 0;
549Ecore_Win32_Window *_ecore_win32_event_last_window = NULL;
550int _ecore_win32_log_dom_global = -1;
551
552int ECORE_WIN32_EVENT_MOUSE_IN = 0;
553int ECORE_WIN32_EVENT_MOUSE_OUT = 0;
554int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN = 0;
555int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT = 0;
556int ECORE_WIN32_EVENT_WINDOW_DAMAGE = 0;
557int ECORE_WIN32_EVENT_WINDOW_CREATE = 0;
558int ECORE_WIN32_EVENT_WINDOW_DESTROY = 0;
559int ECORE_WIN32_EVENT_WINDOW_SHOW = 0;
560int ECORE_WIN32_EVENT_WINDOW_HIDE = 0;
561int ECORE_WIN32_EVENT_WINDOW_CONFIGURE = 0;
562int ECORE_WIN32_EVENT_WINDOW_RESIZE = 0;
563int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST = 0;
564
565/*============================================================================*
566 * API *
567 *============================================================================*/
568
569/**
570 * @addtogroup Ecore_Win32_Group Ecore_Win32 library
571 *
572 * Ecore_Win32 is a library that wraps Windows graphic functions
573 * and integrate them nicely into the Ecore main loop.
574 *
575 * @section Ecore_Win32_Sec_Init Initialisation / Shutdown
576 *
577 * To fill...
578 *
579 * @section Ecore_Win32_Sec_Icons How to set icons to an application
580 *
581 * It is possible to also sets the icon of the application easily:
582 *
583 * @li Create an icon with your favorite image creator. The Gimp is a
584 * good choice. Create several images of size 16, 32 and 48. You can
585 * also create images of size 24, 64, 128 and 256. Paste all of them
586 * in the image of size 16 as a layer. Save the image of size 16 with
587 * the name my_icon.ico. Put it where the source code of the
588 * application is located.
589 * @li Create my_icon_rc.rc file with your code editor and add in it:
590 * @code
591 * 101 ICON DISCARDABLE "my_icon.ico"
592 * @endcode
593 * @li With Visual Studio, put that file in the 'Resource file' part
594 * of the project.
595 * @li With MinGW, you have to compile it with windres:
596 * @code
597 * windres my_icon_rc.rc my_icon_rc.o
598 * @endcode
599 * and add my_icon_rc.o to the object files of the application.
600 *
601 * @note The value 101 must not be changed, it's the ID used
602 * internally by Ecore_Win32 to get the icons.
603 *
604 * @{
605 */
606
607/**
608 * @brief Initialize the Ecore_Win32 library.
609 *
610 * @return 1 or greater on success, 0 on error.
611 *
612 * This function sets up the Windows graphic system. It returns 0 on
613 * failure, otherwise it returns the number of times it has already been
614 * called.
615 *
616 * When Ecore_Win32 is not used anymore, call ecore_win32_shutdown()
617 * to shut down the Ecore_Win32 library.
618 */
619EAPI int
620ecore_win32_init()
621{
622 WNDCLASSEX wc;
623 HICON icon;
624 HICON icon_sm;
625
626 if (++_ecore_win32_init_count != 1)
627 return _ecore_win32_init_count;
628
629 if (!eina_init())
630 return --_ecore_win32_init_count;
631
632 _ecore_win32_log_dom_global = eina_log_domain_register
633 ("ecore_win32", ECORE_WIN32_DEFAULT_LOG_COLOR);
634 if (_ecore_win32_log_dom_global < 0)
635 {
636 EINA_LOG_ERR("Ecore_Win32: Could not register log domain");
637 goto shutdown_eina;
638 }
639
640 if (!ecore_event_init())
641 {
642 ERR("Ecore_Win32: Could not init ecore_event");
643 goto unregister_log_domain;
644 }
645
646 _ecore_win32_instance = GetModuleHandle(NULL);
647 if (!_ecore_win32_instance)
648 {
649 ERR("GetModuleHandle() failed");
650 goto shutdown_ecore_event;
651 }
652
653 icon = LoadImage(_ecore_win32_instance,
654 MAKEINTRESOURCE(IDI_ICON),
655 IMAGE_ICON,
656 GetSystemMetrics(SM_CXICON),
657 GetSystemMetrics(SM_CYICON),
658 LR_DEFAULTCOLOR);
659 icon_sm = LoadImage(_ecore_win32_instance,
660 MAKEINTRESOURCE(IDI_ICON),
661 IMAGE_ICON,
662 GetSystemMetrics(SM_CXSMICON),
663 GetSystemMetrics(SM_CYSMICON),
664 LR_DEFAULTCOLOR);
665 if (!icon)
666 icon = LoadIcon (NULL, IDI_APPLICATION);
667 if (!icon_sm)
668 icon_sm = LoadIcon (NULL, IDI_APPLICATION);
669
670 memset (&wc, 0, sizeof (WNDCLASSEX));
671 wc.cbSize = sizeof (WNDCLASSEX);
672 wc.style = CS_HREDRAW | CS_VREDRAW;
673 wc.lpfnWndProc = _ecore_win32_window_procedure;
674 wc.cbClsExtra = 0;
675 wc.cbWndExtra = 0;
676 wc.hInstance = _ecore_win32_instance;
677 wc.hIcon = icon;
678 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
679 wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
680 wc.lpszMenuName = NULL;
681 wc.lpszClassName = ECORE_WIN32_WINDOW_CLASS;
682 wc.hIconSm = icon_sm;
683
684 if(!RegisterClassEx(&wc))
685 {
686 ERR("RegisterClass() failed");
687 goto free_library;
688 }
689
690 if (!ecore_win32_dnd_init())
691 {
692 ERR("ecore_win32_dnd_init() failed");
693 goto unregister_class;
694 }
695
696 if (!ECORE_WIN32_EVENT_MOUSE_IN)
697 {
698 ECORE_WIN32_EVENT_MOUSE_IN = ecore_event_type_new();
699 ECORE_WIN32_EVENT_MOUSE_OUT = ecore_event_type_new();
700 ECORE_WIN32_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
701 ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
702 ECORE_WIN32_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
703 ECORE_WIN32_EVENT_WINDOW_CREATE = ecore_event_type_new();
704 ECORE_WIN32_EVENT_WINDOW_DESTROY = ecore_event_type_new();
705 ECORE_WIN32_EVENT_WINDOW_SHOW = ecore_event_type_new();
706 ECORE_WIN32_EVENT_WINDOW_HIDE = ecore_event_type_new();
707 ECORE_WIN32_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
708 ECORE_WIN32_EVENT_WINDOW_RESIZE = ecore_event_type_new();
709 ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
710 }
711
712 return _ecore_win32_init_count;
713
714 unregister_class:
715 UnregisterClass(ECORE_WIN32_WINDOW_CLASS, _ecore_win32_instance);
716 free_library:
717 FreeLibrary(_ecore_win32_instance);
718 shutdown_ecore_event:
719 ecore_event_shutdown();
720 unregister_log_domain:
721 eina_log_domain_unregister(_ecore_win32_log_dom_global);
722 shutdown_eina:
723 eina_shutdown();
724
725 return --_ecore_win32_init_count;
726}
727
728/**
729 * @brief Shut down the Ecore_Win32 library.
730 *
731 * @return 0 when the library is completely shut down, 1 or
732 * greater otherwise.
733 *
734 * This function shuts down the Ecore_Win32 library. It returns 0 when it has
735 * been called the same number of times than ecore_win32_init(). In that case
736 * it shuts down all the Windows graphic system.
737 */
738EAPI int
739ecore_win32_shutdown()
740{
741 if (--_ecore_win32_init_count != 0)
742 return _ecore_win32_init_count;
743
744 ecore_win32_dnd_shutdown();
745
746 if (!UnregisterClass(ECORE_WIN32_WINDOW_CLASS, _ecore_win32_instance))
747 INF("UnregisterClass() failed");
748
749 if (!FreeLibrary(_ecore_win32_instance))
750 INF("FreeLibrary() failed");
751
752 _ecore_win32_instance = NULL;
753
754 ecore_event_shutdown();
755 eina_log_domain_unregister(_ecore_win32_log_dom_global);
756 _ecore_win32_log_dom_global = -1;
757 eina_shutdown();
758
759 return _ecore_win32_init_count;
760}
761
762/**
763 * @brief Retrieve the depth of the screen.
764 *
765 * @return The depth of the screen.
766 *
767 * This function returns the depth of the screen. If an error occurs,
768 * it returns 0.
769 */
770EAPI int
771ecore_win32_screen_depth_get()
772{
773 HDC dc;
774 int depth;
775
776 INF("getting screen depth");
777
778 dc = GetDC(NULL);
779 if (!dc)
780 {
781 ERR("GetDC() failed");
782 return 0;
783 }
784
785 depth = GetDeviceCaps(dc, BITSPIXEL);
786 if (!ReleaseDC(NULL, dc))
787 {
788 ERR("ReleaseDC() failed (device context not released)");
789 }
790
791 return depth;
792}
793
794/**
795 * @brief Sets the timeout for a double and triple clicks to be flagged.
796 *
797 * @param t The time in seconds.
798 *
799 * This function sets the time @p t between clicks before the
800 * double_click flag is set in a button down event. If 3 clicks occur
801 * within double this time, the triple_click flag is also set.
802 */
803EAPI void
804ecore_win32_double_click_time_set(double t)
805{
806 if (t < 0.0) t = 0.0;
807 _ecore_win32_double_click_time = t;
808}
809
810/**
811 * @brief Retrieve the double and triple click flag timeout.
812 *
813 * @return The timeout for double clicks in seconds.
814 *
815 * This function returns the double clicks in seconds. If
816 * ecore_win32_double_click_time_set() has not been called, the
817 * default value is returned. See ecore_win32_double_click_time_set()
818 * for more informations.
819 */
820EAPI double
821ecore_win32_double_click_time_get(void)
822{
823 return _ecore_win32_double_click_time;
824}
825
826/**
827 * @brief Return the last event time.
828 *
829 * @return The last envent time.
830 *
831 * This function returns the last event time.
832 */
833EAPI unsigned long
834ecore_win32_current_time_get(void)
835{
836 return _ecore_win32_event_last_time;
837}
838
839/**
840 * @}
841 */
diff --git a/src/lib/ecore_win32/ecore_win32_cursor.c b/src/lib/ecore_win32/ecore_win32_cursor.c
new file mode 100644
index 0000000000..9b58c95160
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_cursor.c
@@ -0,0 +1,305 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#define WIN32_LEAN_AND_MEAN
6#include <windows.h>
7#undef WIN32_LEAN_AND_MEAN
8
9#include <Eina.h>
10
11#include "Ecore_Win32.h"
12#include "ecore_win32_private.h"
13
14/*============================================================================*
15 * Local *
16 *============================================================================*/
17
18
19/*============================================================================*
20 * Global *
21 *============================================================================*/
22
23
24/*============================================================================*
25 * API *
26 *============================================================================*/
27
28/**
29 * @addtogroup Ecore_Win32_Group Ecore_Win32 library
30 *
31 * @{
32 */
33
34/**
35 * @brief Create a new cursor.
36 *
37 * @param pixels_and The array of bytes containing the bit values for
38 * the AND mask of the cursor.
39 * @param pixels_xor The array of bytes containing the bit values for
40 * the XOR mask of the cursor.
41 * @param width The width of the cursor.
42 * @param height The height of the cursor.
43 * @param hot_x The horizontal position of the cursor's hot spot.
44 * @param hot_y The vertical position of the cursor's hot spot.
45 * @return A newly user-defined cursor.
46 *
47 * This function creates a new cursor of size @p width and @p
48 * height. They must be valid size. To determine the valid size of a
49 * cursor, use ecore_win32_cursor_size_get(). @p pixels_and is an array
50 * of bytes (unsigned char) containing the bits of the cursor that
51 * will be visible. @p pixels_xor is similar but will allow the cursor
52 * to have a shape. Here is the truth table for the masks:
53 *
54 * <table border=1>
55 * <tr><td>AND mask</td><td>XOR mask</td><td>Display</td></tr>
56 * <tr><td>0</td> <td>0</td> <td>Black</td></tr>
57 * <tr><td>0</td> <td>1</td> <td>White</td></tr>
58 * <tr><td>1</td> <td>0</td> <td>Screen</td></tr>
59 * <tr><td>1</td> <td>1</td> <td>Reverse screen</td></tr>
60 * </table>
61 *
62 * @p hot_x and @p hot_y are the position of the hot spot of the
63 * cursor. If @p pixels_and or @p pixels_xor are @c NULL, the function
64 * returns NULL. If @p width or @p height does not match the valid
65 * size of a cursor, the function returns @c NULL. On success, the
66 * function creates a user-defined cursor, otherwise it returns
67 * @c NULL.
68 *
69 * Once the cursor is not used anymore, use ecore_win32_cursor_free()
70 * to free the ressources.
71 *
72 * Example of use:
73 *
74 * @code
75 * unsigned char pixels_and[] ={
76 * 0xFF, 0xFC, 0x3F, 0xFF, // line 1
77 * 0xFF, 0xC0, 0x1F, 0xFF, // line 2
78 * 0xFF, 0x00, 0x3F, 0xFF, // line 3
79 * 0xFE, 0x00, 0xFF, 0xFF, // line 4
80 *
81 * 0xF7, 0x01, 0xFF, 0xFF, // line 5
82 * 0xF0, 0x03, 0xFF, 0xFF, // line 6
83 * 0xF0, 0x03, 0xFF, 0xFF, // line 7
84 * 0xE0, 0x07, 0xFF, 0xFF, // line 8
85 *
86 * 0xC0, 0x07, 0xFF, 0xFF, // line 9
87 * 0xC0, 0x0F, 0xFF, 0xFF, // line 10
88 * 0x80, 0x0F, 0xFF, 0xFF, // line 11
89 * 0x80, 0x0F, 0xFF, 0xFF, // line 12
90 *
91 * 0x80, 0x07, 0xFF, 0xFF, // line 13
92 * 0x00, 0x07, 0xFF, 0xFF, // line 14
93 * 0x00, 0x03, 0xFF, 0xFF, // line 15
94 * 0x00, 0x00, 0xFF, 0xFF, // line 16
95 *
96 * 0x00, 0x00, 0x7F, 0xFF, // line 17
97 * 0x00, 0x00, 0x1F, 0xFF, // line 18
98 * 0x00, 0x00, 0x0F, 0xFF, // line 19
99 * 0x80, 0x00, 0x0F, 0xFF, // line 20
100 *
101 * 0x80, 0x00, 0x07, 0xFF, // line 21
102 * 0x80, 0x00, 0x07, 0xFF, // line 22
103 * 0xC0, 0x00, 0x07, 0xFF, // line 23
104 * 0xC0, 0x00, 0x0F, 0xFF, // line 24
105 *
106 * 0xE0, 0x00, 0x0F, 0xFF, // line 25
107 * 0xF0, 0x00, 0x1F, 0xFF, // line 26
108 * 0xF0, 0x00, 0x1F, 0xFF, // line 27
109 * 0xF8, 0x00, 0x3F, 0xFF, // line 28
110 *
111 * 0xFE, 0x00, 0x7F, 0xFF, // line 29
112 * 0xFF, 0x00, 0xFF, 0xFF, // line 30
113 * 0xFF, 0xC3, 0xFF, 0xFF, // line 31
114 * 0xFF, 0xFF, 0xFF, 0xFF // line 32
115 * };
116 *
117 * unsigned char pixels_xor[] = {
118 * 0x00, 0x00, 0x00, 0x00, // line 1
119 * 0x00, 0x03, 0xC0, 0x00, // line 2
120 * 0x00, 0x3F, 0x00, 0x00, // line 3
121 * 0x00, 0xFE, 0x00, 0x00, // line 4
122 *
123 * 0x0E, 0xFC, 0x00, 0x00, // line 5
124 * 0x07, 0xF8, 0x00, 0x00, // line 6
125 * 0x07, 0xF8, 0x00, 0x00, // line 7
126 * 0x0F, 0xF0, 0x00, 0x00, // line 8
127 *
128 * 0x1F, 0xF0, 0x00, 0x00, // line 9
129 * 0x1F, 0xE0, 0x00, 0x00, // line 10
130 * 0x3F, 0xE0, 0x00, 0x00, // line 11
131 * 0x3F, 0xE0, 0x00, 0x00, // line 12
132 *
133 * 0x3F, 0xF0, 0x00, 0x00, // line 13
134 * 0x7F, 0xF0, 0x00, 0x00, // line 14
135 * 0x7F, 0xF8, 0x00, 0x00, // line 15
136 * 0x7F, 0xFC, 0x00, 0x00, // line 16
137 *
138 * 0x7F, 0xFF, 0x00, 0x00, // line 17
139 * 0x7F, 0xFF, 0x80, 0x00, // line 18
140 * 0x7F, 0xFF, 0xE0, 0x00, // line 19
141 * 0x3F, 0xFF, 0xE0, 0x00, // line 20
142 *
143 * 0x3F, 0xC7, 0xF0, 0x00, // line 21
144 * 0x3F, 0x83, 0xF0, 0x00, // line 22
145 * 0x1F, 0x83, 0xF0, 0x00, // line 23
146 * 0x1F, 0x83, 0xE0, 0x00, // line 24
147 *
148 * 0x0F, 0xC7, 0xE0, 0x00, // line 25
149 * 0x07, 0xFF, 0xC0, 0x00, // line 26
150 * 0x07, 0xFF, 0xC0, 0x00, // line 27
151 * 0x01, 0xFF, 0x80, 0x00, // line 28
152 *
153 * 0x00, 0xFF, 0x00, 0x00, // line 29
154 * 0x00, 0x3C, 0x00, 0x00, // line 30
155 * 0x00, 0x00, 0x00, 0x00, // line 31
156 * 0x00, 0x00, 0x00, 0x00 // line 32
157 * };
158 *
159 * Ecore_Win32_Cursor *cursor = ecore_win32_cursor_new(pixels_and, pixels_xor, 32, 32, 19, 2);
160 * @endcode
161 */
162EAPI Ecore_Win32_Cursor *
163ecore_win32_cursor_new(const void *pixels_and,
164 const void *pixels_xor,
165 int width,
166 int height,
167 int hot_x,
168 int hot_y)
169{
170 Ecore_Win32_Cursor *cursor = NULL;
171 int cursor_width;
172 int cursor_height;
173
174 INF("creating cursor");
175
176 if (!pixels_and || !pixels_xor)
177 return NULL;
178
179 cursor_width = GetSystemMetrics(SM_CXCURSOR);
180 cursor_height = GetSystemMetrics(SM_CYCURSOR);
181
182 if ((cursor_width != width) ||
183 (cursor_height != height))
184 return NULL;
185
186 if (!(cursor = CreateCursor(_ecore_win32_instance,
187 hot_x, hot_y,
188 width, height,
189 pixels_and,
190 pixels_xor)))
191 return NULL;
192
193 return cursor;
194}
195
196/**
197 * @brief Free the given cursor.
198 *
199 * @param cursor The cursor to free.
200 *
201 * This function free @p cursor. @p cursor must have been obtained
202 * with ecore_win32_cursor_new().
203 */
204EAPI void
205ecore_win32_cursor_free(Ecore_Win32_Cursor *cursor)
206{
207 INF("destroying cursor");
208
209 DestroyCursor(cursor);
210}
211
212/**
213 * @brief Create a cursor from a Windows ressource.
214 *
215 * @param shape The pre-defined shape of the cursor.
216 * @return The new cursor.
217 *
218 * This function returns a pre-defined cursor with a specified
219 * @p shape. This cursor does not need to be freed, as it is loaded
220 * from an existing resource.
221 */
222EAPI Ecore_Win32_Cursor *
223ecore_win32_cursor_shaped_new(Ecore_Win32_Cursor_Shape shape)
224{
225 Ecore_Win32_Cursor *cursor = NULL;
226 const char *cursor_name;
227
228 INF("geting shape cursor");
229
230 switch (shape)
231 {
232 case ECORE_WIN32_CURSOR_SHAPE_APP_STARTING:
233 cursor_name = IDC_APPSTARTING;
234 break;
235 case ECORE_WIN32_CURSOR_SHAPE_ARROW:
236 cursor_name = IDC_ARROW;
237 break;
238 case ECORE_WIN32_CURSOR_SHAPE_CROSS:
239 cursor_name = IDC_CROSS;
240 break;
241 case ECORE_WIN32_CURSOR_SHAPE_HAND:
242 cursor_name = IDC_HAND;
243 break;
244 case ECORE_WIN32_CURSOR_SHAPE_HELP:
245 cursor_name = IDC_HELP;
246 break;
247 case ECORE_WIN32_CURSOR_SHAPE_I_BEAM:
248 cursor_name = IDC_IBEAM;
249 break;
250 case ECORE_WIN32_CURSOR_SHAPE_NO:
251 cursor_name = IDC_NO;
252 break;
253 case ECORE_WIN32_CURSOR_SHAPE_SIZE_ALL:
254 cursor_name = IDC_SIZEALL;
255 break;
256 case ECORE_WIN32_CURSOR_SHAPE_SIZE_NESW:
257 cursor_name = IDC_SIZENESW;
258 break;
259 case ECORE_WIN32_CURSOR_SHAPE_SIZE_NS:
260 cursor_name = IDC_SIZENS;
261 break;
262 case ECORE_WIN32_CURSOR_SHAPE_SIZE_NWSE:
263 cursor_name = IDC_SIZENWSE;
264 break;
265 case ECORE_WIN32_CURSOR_SHAPE_SIZE_WE:
266 cursor_name = IDC_SIZEWE;
267 break;
268 case ECORE_WIN32_CURSOR_SHAPE_UP_ARROW:
269 cursor_name = IDC_UPARROW;
270 break;
271 case ECORE_WIN32_CURSOR_SHAPE_WAIT:
272 cursor_name = IDC_WAIT;
273 break;
274 default:
275 return NULL;
276 }
277
278 if (!(cursor = LoadCursor(NULL, cursor_name)))
279 return NULL;
280
281 return cursor;
282}
283
284/**
285 * @brief Retrieve the size of a valid cursor.
286 *
287 * @param width The width of a valid cursor.
288 * @param height The height of a valid cursor.
289 *
290 * This function returns the size of a cursor that must be passed to
291 * ecore_win32_cursor_new(). @p width and @p height are buffers that
292 * will be filled with the correct size. They can be @c NULL.
293 */
294EAPI void
295ecore_win32_cursor_size_get(int *width, int *height)
296{
297 INF("geting size cursor");
298
299 if (*width) *width = GetSystemMetrics(SM_CXCURSOR);
300 if (*height) *height = GetSystemMetrics(SM_CYCURSOR);
301}
302
303/**
304 * @}
305 */
diff --git a/src/lib/ecore_win32/ecore_win32_dnd.c b/src/lib/ecore_win32/ecore_win32_dnd.c
new file mode 100755
index 0000000000..6c5253ae20
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd.c
@@ -0,0 +1,221 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <windows.h>
6
7#include "Ecore_Win32.h"
8#include "ecore_win32_private.h"
9
10/*============================================================================*
11 * Local *
12 *============================================================================*/
13
14/**
15 * @cond LOCAL
16 */
17
18
19static int _ecore_win32_dnd_init_count = 0;
20
21static HANDLE DataToHandle(const char *data, int size)
22{
23 char *ptr;
24 ptr = (char *)GlobalAlloc(GMEM_FIXED, size);
25 memcpy(ptr, data, size);
26 return ptr;
27}
28
29/**
30 * @endcond
31 */
32
33
34/*============================================================================*
35 * Global *
36 *============================================================================*/
37
38
39/*============================================================================*
40 * API *
41 *============================================================================*/
42
43/**
44 * @addtogroup Ecore_Win32_Group Ecore_Win32 library
45 *
46 * @{
47 */
48
49/**
50 * @brief Initialize the Ecore_Win32 Drag and Drop module.
51 *
52 * @return 1 or greater on success, 0 on error.
53 *
54 * This function initialize the Drag and Drop module. It returns 0 on
55 * failure, otherwise it returns the number of times it has already
56 * been called.
57 *
58 * When the Drag and Drop module is not used anymore, call
59 * ecore_win32_dnd_shutdown() to shut down the module.
60 */
61EAPI int
62ecore_win32_dnd_init()
63{
64 if (_ecore_win32_dnd_init_count > 0)
65 {
66 _ecore_win32_dnd_init_count++;
67 return _ecore_win32_dnd_init_count;
68 }
69
70 if (OleInitialize(NULL) != S_OK)
71 return 0;
72
73 _ecore_win32_dnd_init_count++;
74
75 return _ecore_win32_dnd_init_count;
76}
77
78/**
79 * @brief Shut down the Ecore_Win32 Drag and Drop module.
80 *
81 * @return 0 when the module is completely shut down, 1 or
82 * greater otherwise.
83 *
84 * This function shuts down the Drag and Drop module. It returns 0 when it has
85 * been called the same number of times than ecore_win32_dnd_init(). In that case
86 * it shut down the module.
87 */
88EAPI int
89ecore_win32_dnd_shutdown()
90{
91 _ecore_win32_dnd_init_count--;
92 if (_ecore_win32_dnd_init_count > 0) return _ecore_win32_dnd_init_count;
93
94 OleUninitialize();
95
96 if (_ecore_win32_dnd_init_count < 0) _ecore_win32_dnd_init_count = 0;
97
98 return _ecore_win32_dnd_init_count;
99}
100
101/**
102 * @brief Begin a DnD operation.
103 *
104 * @param data The name pf the Drag operation.
105 * @param size The size of the name.
106 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
107 *
108 * This function start a Drag operation with the name @p data. If
109 * @p data is @c NULL, @c EINA_FALSE is returned. if @p size is less than
110 * @c 0, it is set to the length (as strlen()) of @p data. On success the
111 * function returns @c EINA_TRUE, otherwise it returns @c EINA_FALSE.
112 */
113EAPI Eina_Bool
114ecore_win32_dnd_begin(const char *data,
115 int size)
116{
117 IDataObject *pDataObject = NULL;
118 IDropSource *pDropSource = NULL;
119 FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
120 STGMEDIUM stgmed = { TYMED_HGLOBAL, { 0 }, 0 };
121 Eina_Bool res = EINA_FALSE;
122
123 if (!data)
124 return EINA_FALSE;
125
126 if (size < 0)
127 size = strlen(data) + 1;
128
129 stgmed.hGlobal = DataToHandle(data, size);
130
131 // create the data object
132 pDataObject = (IDataObject *)_ecore_win32_dnd_data_object_new((void *)&fmtetc,
133 (void *)&stgmed,
134 1);
135 pDropSource = (IDropSource *)_ecore_win32_dnd_drop_source_new();
136
137 if (pDataObject && pDropSource)
138 {
139 DWORD dwResult;
140 DWORD dwEffect = DROPEFFECT_COPY;
141
142 // do the drag-drop!
143 dwResult = DoDragDrop(pDataObject, pDropSource, DROPEFFECT_COPY, &dwEffect);
144
145 // finished. Check the return values to see if we need to do anything else
146 if (dwResult == DRAGDROP_S_DROP)
147 {
148 //printf(">>> \"%s\" Dropped <<<\n", str);
149 if(dwEffect == DROPEFFECT_MOVE)
150 {
151 // remove the data we just dropped from active document
152 }
153 }
154 //else if (dwResult == DRAGDROP_S_CANCEL)
155 // printf("DND cancelled\n");
156 //else
157 // printf("DND error\n");
158
159 res = EINA_TRUE;
160 }
161
162 _ecore_win32_dnd_data_object_free(pDataObject);
163 _ecore_win32_dnd_drop_source_free(pDropSource);
164
165 // cleanup
166 ReleaseStgMedium(&stgmed);
167
168 return res;
169}
170
171/**
172 * @brief Register a Drop operation.
173 *
174 * @param window The destination of the Drop operation.
175 * @param callback The callback called when the Drop operation
176 * finishes.
177 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
178 *
179 * This function register a Drop operation on @p window. Once the Drop
180 * operation finishes, @p callback is called. If @p window is @c NULL,
181 * the function returns @c EINA_FALSE. On success, it returns @c EINA_TRUE,
182 * otherwise it returns @c EINA_FALSE.
183 */
184EAPI Eina_Bool
185ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window,
186 Ecore_Win32_Dnd_DropTarget_Callback callback)
187{
188 Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window;
189
190 if (!window)
191 return EINA_FALSE;
192
193 wnd->dnd_drop_target = _ecore_win32_dnd_register_drop_window(wnd->window,
194 callback,
195 (void *)wnd);
196 return wnd->dnd_drop_target ? EINA_TRUE : EINA_FALSE;
197}
198
199/**
200 * @brief Unregister a Drop operation.
201 *
202 * @param window The destination of the Drop operation.
203 *
204 * This function unregister a Drop operation on @p window. If
205 * @p window is @c NULL, the function does nothing.
206 */
207EAPI void
208ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window)
209{
210 Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window;
211
212 if (!window)
213 return;
214
215 if (wnd->dnd_drop_target)
216 _ecore_win32_dnd_unregister_drop_window(wnd->window, wnd->dnd_drop_target);
217}
218
219/**
220 * @}
221 */
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp b/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp
new file mode 100644
index 0000000000..213197780b
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp
@@ -0,0 +1,209 @@
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 <assert.h>
10
11#define WIN32_LEAN_AND_MEAN
12#include <windows.h>
13#undef WIN32_LEAN_AND_MEAN
14#include <ole2.h>
15
16#include "Ecore_Win32.h"
17#include "ecore_win32_private.h"
18
19#include "ecore_win32_dnd_enumformatetc.h"
20#include "ecore_win32_dnd_data_object.h"
21
22
23static HGLOBAL DupGlobalMem(HGLOBAL hMem)
24{
25 DWORD len = (DWORD)GlobalSize(hMem);
26 PVOID source = GlobalLock(hMem);
27 PVOID dest = GlobalAlloc(GMEM_FIXED, len);
28 memcpy(dest, source, len);
29 GlobalUnlock(hMem);
30 return dest;
31}
32
33// structors
34
35DataObject::DataObject(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count)
36{
37 assert(fmtetc != NULL);
38 assert(stgmed != NULL);
39 assert(count > 0);
40
41 // reference count must ALWAYS start at 1
42 ref_count_ = 1;
43 formats_num_ = count;
44
45 format_etc_ = new FORMATETC[count];
46 stg_medium_ = new STGMEDIUM[count];
47
48 for(int i = 0; i < count; i++)
49 {
50 format_etc_[i] = fmtetc[i];
51 stg_medium_[i] = stgmed[i];
52 }
53}
54
55DataObject::~DataObject()
56{
57 delete[] format_etc_;
58 delete[] stg_medium_;
59}
60
61
62// IUnknown
63
64HRESULT DataObject::QueryInterface(REFIID iid, void **ppvObject)
65{
66 // check to see what interface has been requested
67 if ((iid == IID_IDataObject) || (iid == IID_IUnknown))
68 {
69 AddRef();
70 *ppvObject = this;
71 return S_OK;
72 }
73 *ppvObject = 0;
74 return E_NOINTERFACE;
75}
76
77ULONG DataObject::AddRef()
78{
79 return InterlockedIncrement(&ref_count_);
80}
81
82ULONG DataObject::Release()
83{
84 LONG count = InterlockedDecrement(&ref_count_);
85 if(count == 0)
86 {
87 delete this;
88 return 0;
89 }
90 return count;
91}
92
93// IDataObject
94
95HRESULT DataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
96{
97 assert(pMedium != NULL);
98 int idx;
99
100 // try to match the specified FORMATETC with one of our supported formats
101 if((idx = lookup_format_etc(pFormatEtc)) == -1)
102 return DV_E_FORMATETC;
103
104 // found a match - transfer data into supplied storage medium
105 pMedium->tymed = format_etc_[idx].tymed;
106 pMedium->pUnkForRelease = 0;
107
108 // copy the data into the caller's storage medium
109 switch(format_etc_[idx].tymed)
110 {
111 case TYMED_HGLOBAL:
112 pMedium->hGlobal = DupGlobalMem(stg_medium_[idx].hGlobal);
113 break;
114
115 default:
116 return DV_E_FORMATETC;
117 }
118
119 return S_OK;
120}
121
122HRESULT DataObject::GetDataHere(FORMATETC *pFormatEtc EINA_UNUSED, STGMEDIUM *pmedium EINA_UNUSED)
123{
124 return DATA_E_FORMATETC;
125}
126
127HRESULT DataObject::QueryGetData(FORMATETC *pFormatEtc)
128{
129 return (lookup_format_etc(pFormatEtc) == -1) ? DV_E_FORMATETC : S_OK;
130}
131
132HRESULT DataObject::GetCanonicalFormatEtc(FORMATETC *pFormatEct EINA_UNUSED, FORMATETC *pFormatEtcOut)
133{
134 // Apparently we have to set this field to NULL even though we don't do anything else
135 pFormatEtcOut->ptd = NULL;
136 return E_NOTIMPL;
137}
138
139HRESULT DataObject::SetData(FORMATETC *pFormatEtc EINA_UNUSED, STGMEDIUM *pMedium EINA_UNUSED, BOOL fRelease EINA_UNUSED)
140{
141 return E_NOTIMPL;
142}
143
144HRESULT DataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc)
145{
146 // only the get direction is supported for OLE
147 if(dwDirection == DATADIR_GET)
148 {
149 // for Win2k+ you can use the SHCreateStdEnumFmtEtc API call, however
150 // to support all Windows platforms we need to implement IEnumFormatEtc ourselves.
151 return CreateEnumFormatEtc(formats_num_, format_etc_, ppEnumFormatEtc);
152 }
153 else
154 {
155 // the direction specified is not supported for drag+drop
156 return E_NOTIMPL;
157 }
158}
159
160HRESULT DataObject::DAdvise(FORMATETC *pFormatEtc EINA_UNUSED, DWORD advf EINA_UNUSED, IAdviseSink *, DWORD *)
161{
162 return OLE_E_ADVISENOTSUPPORTED;
163}
164
165HRESULT DataObject::DUnadvise(DWORD dwConnection EINA_UNUSED)
166{
167 return OLE_E_ADVISENOTSUPPORTED;
168}
169
170HRESULT DataObject::EnumDAdvise(IEnumSTATDATA **ppEnumAdvise EINA_UNUSED)
171{
172 return OLE_E_ADVISENOTSUPPORTED;
173}
174
175// internal helper function
176
177int DataObject::lookup_format_etc(FORMATETC *pFormatEtc)
178{
179 // check each of our formats in turn to see if one matches
180 for(int i = 0; i < formats_num_; i++)
181 {
182 if((format_etc_[i].tymed & pFormatEtc->tymed) &&
183 (format_etc_[i].cfFormat == pFormatEtc->cfFormat) &&
184 (format_etc_[i].dwAspect == pFormatEtc->dwAspect))
185 {
186 // return index of stored format
187 return i;
188 }
189 }
190
191 // error, format not found
192 return -1;
193}
194
195void *_ecore_win32_dnd_data_object_new(void *fmtetc, void *stgmeds, int count)
196{
197 IDataObject *object = new DataObject((FORMATETC *)fmtetc, (STGMEDIUM *)stgmeds, (UINT)count);
198 assert(object != NULL);
199 return object;
200}
201
202void _ecore_win32_dnd_data_object_free(void *data_object)
203{
204 if (!data_object)
205 return;
206
207 IDataObject *object = (IDataObject *)data_object;
208 object->Release();
209}
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_data_object.h b/src/lib/ecore_win32/ecore_win32_dnd_data_object.h
new file mode 100644
index 0000000000..3d289cf7f5
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_data_object.h
@@ -0,0 +1,49 @@
1#ifndef __ECORE_WIN32_DND_DATA_OBJECT_H__
2#define __ECORE_WIN32_DND_DATA_OBJECT_H__
3
4
5#define WIN32_LEAN_AND_MEAN
6#include <windows.h>
7#undef WIN32_LEAN_AND_MEAN
8#include <objbase.h>
9
10
11class DataObject : public IDataObject
12{
13 private:
14
15 LONG ref_count_;
16 int formats_num_;
17 FORMATETC *format_etc_;
18 STGMEDIUM *stg_medium_;
19
20 private: // internal helper function
21
22 int lookup_format_etc(FORMATETC *format_etc);
23
24 public: // structors
25
26 DataObject(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count);
27 ~DataObject();
28
29 public: // IUnknown
30
31 HRESULT __stdcall QueryInterface(REFIID iid, void **ppvObject);
32 ULONG __stdcall AddRef();
33 ULONG __stdcall Release();
34
35 public: // IDataObject
36
37 HRESULT __stdcall GetData(FORMATETC *pFormatEtc, STGMEDIUM *pmedium);
38 HRESULT __stdcall GetDataHere(FORMATETC *pFormatEtc, STGMEDIUM *pmedium);
39 HRESULT __stdcall QueryGetData(FORMATETC *pFormatEtc);
40 HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC *pFormatEct, FORMATETC *pFormatEtcOut);
41 HRESULT __stdcall SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease);
42 HRESULT __stdcall EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
43 HRESULT __stdcall DAdvise(FORMATETC *pFormatEtc, DWORD advf, IAdviseSink *, DWORD *);
44 HRESULT __stdcall DUnadvise(DWORD dwConnection);
45 HRESULT __stdcall EnumDAdvise(IEnumSTATDATA **ppEnumAdvise);
46};
47
48
49#endif /* __ECORE_WIN32_DND_DATA_OBJECT_H__ */
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp
new file mode 100644
index 0000000000..a3a8bb1865
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp
@@ -0,0 +1,92 @@
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 <assert.h>
10
11#include "ecore_win32_dnd_drop_source.h"
12
13#include "ecore_win32_private.h"
14
15// structors
16
17// reference count must ALWAYS start at 1
18DropSource::DropSource() : ref_count_(1)
19{ }
20
21
22// IUnknown
23
24HRESULT DropSource::QueryInterface(REFIID iid, void **ppvObject)
25{
26 // check to see what interface has been requested
27 if (iid == IID_IDropSource || iid == IID_IUnknown)
28 {
29 AddRef();
30 *ppvObject = this;
31 return S_OK;
32 }
33 *ppvObject = 0;
34 return E_NOINTERFACE;
35}
36
37ULONG DropSource::AddRef()
38{
39 return InterlockedIncrement(&ref_count_);
40}
41
42ULONG DropSource::Release()
43{
44 LONG count = InterlockedDecrement(&ref_count_);
45 if(count == 0)
46 {
47 delete this;
48 return 0;
49 }
50 return count;
51}
52
53
54// IDropSource
55
56HRESULT DropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
57{
58 // if the Escape key has been pressed since the last call, cancel the drop
59 if(fEscapePressed == TRUE)
60 return DRAGDROP_S_CANCEL;
61
62 // if the LeftMouse button has been released, then do the drop!
63 if((grfKeyState & MK_LBUTTON) == 0)
64 return DRAGDROP_S_DROP;
65
66 // continue with the drag-drop
67 return S_OK;
68}
69
70HRESULT DropSource::GiveFeedback(DWORD dwEffect EINA_UNUSED)
71{
72 return DRAGDROP_S_USEDEFAULTCURSORS;
73}
74
75
76// ecore_win32 private functions
77
78void *_ecore_win32_dnd_drop_source_new()
79{
80 IDropSource *object = new DropSource();
81 assert(object != NULL);
82 return object;
83}
84
85void _ecore_win32_dnd_drop_source_free(void *drop_source)
86{
87 if (!drop_source)
88 return;
89
90 IDropSource *object = (IDropSource *)drop_source;
91 object->Release();
92}
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h
new file mode 100644
index 0000000000..9081f46a15
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h
@@ -0,0 +1,36 @@
1#ifndef __ECORE_WIN32_DND_DROP_SOURCE_H__
2#define __ECORE_WIN32_DND_DROP_SOURCE_H__
3
4
5#define WIN32_LEAN_AND_MEAN
6#include <windows.h>
7#undef WIN32_LEAN_AND_MEAN
8#include <ole2.h>
9
10#include "Ecore_Win32.h"
11
12
13class DropSource : public IDropSource
14{
15 private:
16
17 LONG ref_count_;
18
19 public: // structors
20
21 DropSource();
22
23 public: // IUnknown
24
25 HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject);
26 ULONG __stdcall AddRef();
27 ULONG __stdcall Release();
28
29 public: // IDropSource
30
31 HRESULT __stdcall QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
32 HRESULT __stdcall GiveFeedback(DWORD dwEffect);
33};
34
35
36#endif /* __ECORE_WIN32_DND_DROP_SOURCE_H__ */
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp
new file mode 100644
index 0000000000..2f2da1af65
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp
@@ -0,0 +1,232 @@
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 "ecore_win32_dnd_drop_target.h"
10
11#include "ecore_win32_private.h"
12
13
14// structors
15
16DropTarget::DropTarget(HWND window, Ecore_Win32_Dnd_DropTarget_Callback callback, void *window_obj_ptr)
17 : ref_count_(1)
18 , window_(window)
19 , allow_drop_(false)
20 , drop_callback_(callback)
21 ,drop_callback_ptr_(window_obj_ptr)
22{ }
23
24
25// IUnknown
26
27HRESULT DropTarget::QueryInterface(REFIID iid, void **ppvObject)
28{
29 // check to see what interface has been requested
30 if (iid == IID_IDropTarget || iid == IID_IUnknown)
31 {
32 AddRef();
33 *ppvObject = this;
34 return S_OK;
35 }
36 *ppvObject = 0;
37
38 return E_NOINTERFACE;
39}
40
41ULONG DropTarget::AddRef()
42{
43 return InterlockedIncrement(&ref_count_);
44}
45
46ULONG DropTarget::Release()
47{
48 LONG count = InterlockedDecrement(&ref_count_);
49 if (count == 0)
50 {
51 delete this;
52 return 0;
53 }
54
55 return count;
56}
57
58
59// IDropTarget
60
61HRESULT DropTarget::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
62{
63 // does the dataobject contain data we want?
64 allow_drop_ = QueryDataObject(pDataObject) &&
65 (drop_callback_ == NULL ||
66 (drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_ENTER, pt.x, pt.y, NULL, 0) != 0));
67
68 if (allow_drop_)
69 {
70 // get the dropeffect based on keyboard state
71 *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
72 SetFocus(window_);
73 //PositionCursor(_hwnd, pt);
74 }
75 else
76 *pdwEffect = DROPEFFECT_NONE;
77 return S_OK;
78}
79
80HRESULT DropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
81{
82 allow_drop_ =
83 (drop_callback_ == NULL) ||
84 (drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_OVER, pt.x, pt.y, NULL, 0) != 0);
85
86 if (allow_drop_)
87 {
88 *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
89 //PositionCursor(m_hWnd, pt);
90 }
91 else
92 {
93 *pdwEffect = DROPEFFECT_NONE;
94 }
95
96 return S_OK;
97}
98
99HRESULT DropTarget::DragLeave()
100{
101 POINT pt;
102
103 GetCursorPos(&pt);
104 if (drop_callback_ != NULL)
105 drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_LEAVE, pt.x, pt.y, NULL, 0);
106
107 return S_OK;
108}
109
110HRESULT DropTarget::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
111{
112 if (allow_drop_)
113 {
114 // construct a FORMATETC object
115 FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
116 STGMEDIUM stgmed;
117
118 // See if the dataobject contains any TEXT stored as a HGLOBAL
119 if (pDataObject->QueryGetData(&fmtetc) == S_OK)
120 {
121 // Yippie! the data is there, so go get it!
122 if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK)
123 {
124 // we asked for the data as a HGLOBAL, so access it appropriately
125 PVOID data = GlobalLock(stgmed.hGlobal);
126 UINT size = GlobalSize(stgmed.hGlobal);
127
128 if (drop_callback_ != NULL)
129 {
130 drop_callback_(drop_callback_ptr_,
131 ECORE_WIN32_DND_EVENT_DROP,
132 pt.x, pt.y,
133 data, size);
134 }
135
136 GlobalUnlock(stgmed.hGlobal);
137
138 // release the data using the COM API
139 ReleaseStgMedium(&stgmed);
140 }
141 }
142 *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
143 }
144 else
145 {
146 *pdwEffect = DROPEFFECT_NONE;
147 }
148
149 return S_OK;
150}
151
152
153// internal helper function
154
155DWORD DropTarget::DropEffect(DWORD grfKeyState, POINTL pt EINA_UNUSED, DWORD dwAllowed)
156{
157 DWORD dwEffect = 0;
158
159 // 1. check "pt" -> do we allow a drop at the specified coordinates?
160
161 // 2. work out that the drop-effect should be based on grfKeyState
162 if (grfKeyState & MK_CONTROL)
163 {
164 dwEffect = dwAllowed & DROPEFFECT_COPY;
165 }
166 else if (grfKeyState & MK_SHIFT)
167 {
168 dwEffect = dwAllowed & DROPEFFECT_MOVE;
169 }
170
171 // 3. no key-modifiers were specified (or drop effect not allowed), so
172 // base the effect on those allowed by the dropsource
173 if (dwEffect == 0)
174 {
175 if (dwAllowed & DROPEFFECT_COPY) dwEffect = DROPEFFECT_COPY;
176 if (dwAllowed & DROPEFFECT_MOVE) dwEffect = DROPEFFECT_MOVE;
177 }
178
179 return dwEffect;
180}
181
182bool DropTarget::QueryDataObject(IDataObject *pDataObject)
183{
184 FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
185
186 // does the data object support CF_TEXT using a HGLOBAL?
187 return pDataObject->QueryGetData(&fmtetc) == S_OK;
188}
189
190
191// ecore_win32 private functions
192
193void *_ecore_win32_dnd_register_drop_window(HWND hwnd, Ecore_Win32_Dnd_DropTarget_Callback callback, void *ptr)
194{
195 DropTarget *pDropTarget = new DropTarget(hwnd, callback, ptr);
196
197 if (pDropTarget == NULL)
198 return NULL;
199
200 // acquire a strong lock
201 if (FAILED(CoLockObjectExternal(pDropTarget, TRUE, FALSE)))
202 {
203 delete pDropTarget;
204 return NULL;
205 }
206
207 // tell OLE that the window is a drop target
208 if (FAILED(RegisterDragDrop(hwnd, pDropTarget)))
209 {
210 delete pDropTarget;
211 return NULL;
212 }
213
214 return pDropTarget;
215}
216
217void _ecore_win32_dnd_unregister_drop_window(HWND hwnd, void *drop_target)
218{
219 IDropTarget *pDropTarget = (IDropTarget *)drop_target;
220
221 if (drop_target == NULL)
222 return;
223
224 // remove drag+drop
225 RevokeDragDrop(hwnd);
226
227 // remove the strong lock
228 CoLockObjectExternal(pDropTarget, FALSE, TRUE);
229
230 // release our own reference
231 pDropTarget->Release();
232}
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h
new file mode 100644
index 0000000000..24c3de3e1a
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h
@@ -0,0 +1,47 @@
1#ifndef __ECORE_WIN32_DND_DROP_TARGET_H__
2#define __ECORE_WIN32_DND_DROP_TARGET_H__
3
4
5#define WIN32_LEAN_AND_MEAN
6#include <windows.h>
7#undef WIN32_LEAN_AND_MEAN
8#include <ole2.h>
9
10#include "Ecore_Win32.h"
11
12
13class DropTarget : public IDropTarget
14{
15 private:
16
17 LONG ref_count_;
18 HWND window_;
19 bool allow_drop_;
20 Ecore_Win32_Dnd_DropTarget_Callback drop_callback_;
21 void *drop_callback_ptr_;
22
23 private: // internal helper function
24
25 DWORD DropEffect(DWORD grfKeyState, POINTL pt, DWORD dwAllowed);
26 bool QueryDataObject(IDataObject *pDataObject);
27
28 public: // structors
29
30 DropTarget(HWND hwnd, Ecore_Win32_Dnd_DropTarget_Callback callback, void *window_obj_ptr);
31
32public: // IUnknown
33
34 HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject);
35 ULONG __stdcall AddRef();
36 ULONG __stdcall Release();
37
38 public: // IDropTarget
39
40 HRESULT __stdcall DragEnter(IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
41 HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
42 HRESULT __stdcall DragLeave();
43 HRESULT __stdcall Drop(IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
44};
45
46
47#endif /* __ECORE_WIN32_DND_DROP_TARGET_H__ */
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp
new file mode 100644
index 0000000000..a3858bcdd8
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp
@@ -0,0 +1,157 @@
1
2#include <ole2.h>
3
4#include "ecore_win32_dnd_enumformatetc.h"
5
6
7// structors
8
9CEnumFormatEtc::CEnumFormatEtc(FORMATETC *format_etc, int formats_num)
10 : ref_count_(1)
11 , index_(0)
12 , formats_num_(formats_num)
13 , format_etc_(new FORMATETC[formats_num])
14{
15 // make a new copy of each FORMATETC structure
16 for (unsigned int i = 0; i < formats_num_; i++)
17 {
18 DeepCopyFormatEtc(&format_etc_[i], &format_etc[i]);
19 }
20}
21
22CEnumFormatEtc::~CEnumFormatEtc()
23{
24 if (format_etc_)
25 {
26 // first free any DVTARGETDEVICE structures
27 for (ULONG i = 0; i < formats_num_; i++)
28 {
29 if (format_etc_[i].ptd)
30 CoTaskMemFree(format_etc_[i].ptd);
31 }
32
33 // now free the main array
34 delete[] format_etc_;
35 }
36}
37
38// IUnknown
39
40ULONG __stdcall CEnumFormatEtc::AddRef(void)
41{
42 // increment object reference count
43 return InterlockedIncrement(&ref_count_);
44}
45
46ULONG __stdcall CEnumFormatEtc::Release(void)
47{
48 // decrement object reference count
49 LONG count = InterlockedDecrement(&ref_count_);
50
51 if (count == 0)
52 {
53 delete this;
54 return 0;
55 }
56 else
57 {
58 return count;
59 }
60}
61
62HRESULT __stdcall CEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject)
63{
64 // check to see what interface has been requested
65 if ((iid == IID_IEnumFORMATETC) || (iid == IID_IUnknown))
66 {
67 AddRef();
68 *ppvObject = this;
69 return S_OK;
70 }
71 else
72 {
73 *ppvObject = 0;
74 return E_NOINTERFACE;
75 }
76}
77
78// IEnumFormatEtc
79
80HRESULT CEnumFormatEtc::Reset(void)
81{
82 index_ = 0;
83 return S_OK;
84}
85
86HRESULT CEnumFormatEtc::Skip(ULONG celt)
87{
88 index_ += celt;
89 return (index_ <= formats_num_) ? S_OK : S_FALSE;
90}
91
92HRESULT CEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc)
93{
94 HRESULT hResult;
95
96 // make a duplicate enumerator
97 hResult = CreateEnumFormatEtc(formats_num_, format_etc_, ppEnumFormatEtc);
98
99 if (hResult == S_OK)
100 {
101 // manually set the index state
102 ((CEnumFormatEtc *)*ppEnumFormatEtc)->index_ = index_;
103 }
104
105 return hResult;
106}
107
108HRESULT CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
109{
110 ULONG copied = 0;
111
112 // validate arguments
113 if ((celt == 0) || (pFormatEtc == 0))
114 return E_INVALIDARG;
115
116 // copy the FORMATETC structures into the caller's buffer
117 while (index_ < formats_num_ && copied < celt)
118 {
119 DeepCopyFormatEtc(&pFormatEtc[copied], &format_etc_[index_]);
120 copied++;
121 index_++;
122 }
123
124 // store result
125 if (pceltFetched != 0)
126 *pceltFetched = copied;
127
128 // did we copy all that was requested?
129 return (copied == celt) ? S_OK : S_FALSE;
130}
131
132// external functions
133
134void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source)
135{
136 // copy the source FORMATETC into dest
137 *dest = *source;
138
139 if (source->ptd)
140 {
141 // allocate memory for the DVTARGETDEVICE if necessary
142 dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
143
144 // copy the contents of the source DVTARGETDEVICE into dest->ptd
145 *(dest->ptd) = *(source->ptd);
146 }
147}
148
149HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc)
150{
151 if((cfmt == 0) || (afmt == 0) || (ppEnumFormatEtc == 0))
152 return E_INVALIDARG;
153
154 *ppEnumFormatEtc = new CEnumFormatEtc(afmt, cfmt);
155
156 return (*ppEnumFormatEtc) ? S_OK : E_OUTOFMEMORY;
157}
diff --git a/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h
new file mode 100644
index 0000000000..9f17f5684e
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h
@@ -0,0 +1,50 @@
1#ifndef __ECORE_WIN32_DND_ENUMFORMATETC_H__
2#define __ECORE_WIN32_DND_ENUMFORMATETC_H__
3
4
5#define WIN32_LEAN_AND_MEAN
6#include <windows.h>
7#undef WIN32_LEAN_AND_MEAN
8#include <objbase.h>
9
10
11class CEnumFormatEtc : public IEnumFORMATETC
12{
13 private:
14
15 LONG ref_count_; // Reference count for this COM interface
16 ULONG index_; // current enumerator index
17 ULONG formats_num_; // number of FORMATETC members
18 FORMATETC *format_etc_; // array of FORMATETC objects
19
20 public: // structors
21
22 CEnumFormatEtc(FORMATETC *pFormatEtc, int nNumFormats);
23
24 ~CEnumFormatEtc();
25
26 public: // IUnknown
27
28 HRESULT __stdcall QueryInterface (REFIID iid, void ** ppvObject);
29
30 ULONG __stdcall AddRef (void);
31
32 ULONG __stdcall Release (void);
33
34 public: // IEnumFormatEtc
35
36 HRESULT __stdcall Next (ULONG celt, FORMATETC * rgelt, ULONG * pceltFetched);
37
38 HRESULT __stdcall Skip (ULONG celt);
39
40 HRESULT __stdcall Reset (void);
41
42 HRESULT __stdcall Clone (IEnumFORMATETC ** ppEnumFormatEtc);
43};
44
45void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source);
46
47HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc);
48
49
50#endif /* __ECORE_WIN32_DND_ENUMFORMATETC_H__ */
diff --git a/src/lib/ecore_win32/ecore_win32_event.c b/src/lib/ecore_win32/ecore_win32_event.c
new file mode 100644
index 0000000000..fc285995fc
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_event.c
@@ -0,0 +1,1307 @@
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#include <windowsx.h>
12
13#include <Eina.h>
14#include <Ecore.h>
15#include <Ecore_Input.h>
16
17#include "Ecore_Win32.h"
18#include "ecore_win32_private.h"
19
20
21typedef enum
22{
23 ECORE_WIN32_KEY_MASK_LSHIFT = 1 << 0,
24 ECORE_WIN32_KEY_MASK_RSHIFT = 1 << 1,
25 ECORE_WIN32_KEY_MASK_LCONTROL = 1 << 2,
26 ECORE_WIN32_KEY_MASK_RCONTROL = 1 << 3,
27 ECORE_WIN32_KEY_MASK_LMENU = 1 << 4,
28 ECORE_WIN32_KEY_MASK_RMENU = 1 << 5
29} Ecore_Win32_Key_Mask;
30
31/***** Private declarations *****/
32
33
34static Ecore_Win32_Window *_ecore_win32_mouse_down_last_window = NULL;
35static Ecore_Win32_Window *_ecore_win32_mouse_down_last_last_window = NULL;
36static long _ecore_win32_mouse_down_last_time = 0 ;
37static long _ecore_win32_mouse_down_last_last_time = 0 ;
38static int _ecore_win32_mouse_down_did_triple = 0;
39static int _ecore_win32_mouse_up_count = 0;
40static Ecore_Win32_Key_Mask _ecore_win32_key_mask = 0;
41
42static void _ecore_win32_event_free_key_down(void *data,
43 void *ev);
44
45static void _ecore_win32_event_free_key_up(void *data,
46 void *ev);
47
48static int _ecore_win32_event_keystroke_get(Ecore_Win32_Callback_Data *msg,
49 Eina_Bool is_down,
50 char **keyname,
51 char **keysymbol,
52 char **keycompose,
53 unsigned int *modifiers);
54
55static int _ecore_win32_event_char_get(int key,
56 char **keyname,
57 char **keysymbol,
58 char **keycompose,
59 unsigned int *modifiers);
60
61
62/***** Global functions definitions *****/
63
64void
65_ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg,
66 int is_keystroke)
67{
68 Ecore_Event_Key *e;
69
70 INF("key pressed");
71
72 e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key));
73 if (!e) return;
74
75 if (is_keystroke)
76 {
77 if (!_ecore_win32_event_keystroke_get(msg,
78 EINA_TRUE,
79 (char **)&e->keyname,
80 (char **)&e->key,
81 (char **)&e->string,
82 &e->modifiers))
83 {
84 free(e);
85 return;
86 }
87 }
88 else
89 {
90 if (!_ecore_win32_event_char_get(LOWORD(msg->window_param),
91 (char **)&e->keyname,
92 (char **)&e->key,
93 (char **)&e->string,
94 &e->modifiers))
95 {
96 free(e);
97 return;
98 }
99 }
100
101 e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
102 if (!e->window)
103 {
104 free(e);
105 return;
106 }
107 e->event_window = e->window;
108 e->timestamp = msg->timestamp;
109
110 _ecore_win32_event_last_time = e->timestamp;
111
112 ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _ecore_win32_event_free_key_down, NULL);
113}
114
115void
116_ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg)
117{
118 Ecore_Event_Key *e;
119
120 INF("key released");
121
122 e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key));
123 if (!e) return;
124
125 if (!_ecore_win32_event_keystroke_get(msg,
126 EINA_FALSE,
127 (char **)&e->keyname,
128 (char **)&e->key,
129 (char **)&e->string,
130 &e->modifiers))
131 {
132 if (msg->discard_ctrl ||
133 !_ecore_win32_event_char_get(LOWORD(msg->window_param),
134 (char **)&e->keyname,
135 (char **)&e->key,
136 (char **)&e->string,
137 &e->modifiers))
138 {
139 free(e);
140 return;
141 }
142 }
143
144 e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
145 if (!e->window)
146 {
147 free(e);
148 return;
149 }
150 e->event_window = e->window;
151 e->timestamp = msg->timestamp;
152
153 _ecore_win32_event_last_time = e->timestamp;
154
155 ecore_event_add(ECORE_EVENT_KEY_UP, e, _ecore_win32_event_free_key_up, NULL);
156}
157
158void
159_ecore_win32_event_handle_button_press(Ecore_Win32_Callback_Data *msg,
160 int button)
161{
162 Ecore_Win32_Window *window;
163
164 INF("mouse button pressed");
165
166 window = (Ecore_Win32_Window *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
167
168 if (button > 3)
169 {
170 Ecore_Event_Mouse_Wheel *e;
171
172 e = (Ecore_Event_Mouse_Wheel *)calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
173 if (!e) return;
174
175 e->window = (Ecore_Window)window;
176 e->event_window = e->window;
177 e->direction = 0;
178 /* wheel delta is positive or negative, never 0 */
179 e->z = GET_WHEEL_DELTA_WPARAM(msg->window_param) > 0 ? -1 : 1;
180 e->x = GET_X_LPARAM(msg->data_param);
181 e->y = GET_Y_LPARAM(msg->data_param);
182 e->timestamp = msg->timestamp;
183
184 _ecore_win32_event_last_time = e->timestamp;
185 _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
186
187 ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
188 }
189 else
190 {
191 {
192 Ecore_Event_Mouse_Move *e;
193
194 e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
195 if (!e) return;
196
197 e->window = (Ecore_Window)window;
198 e->event_window = e->window;
199 e->x = GET_X_LPARAM(msg->data_param);
200 e->y = GET_Y_LPARAM(msg->data_param);
201 e->timestamp = msg->timestamp;
202
203 _ecore_win32_event_last_time = e->timestamp;
204 _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
205
206 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
207 }
208
209 {
210 Ecore_Event_Mouse_Button *e;
211
212 if (_ecore_win32_mouse_down_did_triple)
213 {
214 _ecore_win32_mouse_down_last_window = NULL;
215 _ecore_win32_mouse_down_last_last_window = NULL;
216 _ecore_win32_mouse_down_last_time = 0;
217 _ecore_win32_mouse_down_last_last_time = 0;
218 }
219
220 e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
221 if (!e) return;
222
223 e->window = (Ecore_Window)window;
224 e->event_window = e->window;
225 e->buttons = button;
226 e->x = GET_X_LPARAM(msg->data_param);
227 e->y = GET_Y_LPARAM(msg->data_param);
228 e->timestamp = msg->timestamp;
229
230 if (((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned long)(1000 * _ecore_win32_double_click_time)) &&
231 (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window))
232 e->double_click = 1;
233
234 if (((e->timestamp - _ecore_win32_mouse_down_last_last_time) <= (unsigned long)(2 * 1000 * _ecore_win32_double_click_time)) &&
235 (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window) &&
236 (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_last_window))
237 {
238 e->triple_click = 1;
239 _ecore_win32_mouse_down_did_triple = 1;
240 }
241 else
242 _ecore_win32_mouse_down_did_triple = 0;
243
244 if (!e->double_click && !e->triple_click)
245 _ecore_win32_mouse_up_count = 0;
246
247 _ecore_win32_event_last_time = e->timestamp;
248 _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
249
250 if (!_ecore_win32_mouse_down_did_triple)
251 {
252 _ecore_win32_mouse_down_last_last_window = _ecore_win32_mouse_down_last_window;
253 _ecore_win32_mouse_down_last_window = (Ecore_Win32_Window *)e->window;
254 _ecore_win32_mouse_down_last_last_time = _ecore_win32_mouse_down_last_time;
255 _ecore_win32_mouse_down_last_time = e->timestamp;
256 }
257
258 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
259 }
260 }
261}
262
263void
264_ecore_win32_event_handle_button_release(Ecore_Win32_Callback_Data *msg,
265 int button)
266{
267 Ecore_Win32_Window *window;
268
269 INF("mouse button released");
270
271 window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
272
273 {
274 Ecore_Event_Mouse_Move *e;
275
276 e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
277 if (!e) return;
278
279 e->window = (Ecore_Window)window;
280 e->event_window = e->window;
281 e->x = GET_X_LPARAM(msg->data_param);
282 e->y = GET_Y_LPARAM(msg->data_param);
283 e->timestamp = msg->timestamp;
284
285 _ecore_win32_event_last_time = e->timestamp;
286 _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
287
288 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
289 }
290
291 {
292 Ecore_Event_Mouse_Button *e;
293
294 e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
295 if (!e) return;
296
297 e->window = (Ecore_Window)window;
298 e->event_window = e->window;
299 e->buttons = button;
300 e->x = GET_X_LPARAM(msg->data_param);
301 e->y = GET_Y_LPARAM(msg->data_param);
302 e->timestamp = msg->timestamp;
303
304 _ecore_win32_mouse_up_count++;
305
306 if ((_ecore_win32_mouse_up_count >= 2) &&
307 ((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned long)(1000 * _ecore_win32_double_click_time)) &&
308 (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window))
309 e->double_click = 1;
310
311 if ((_ecore_win32_mouse_up_count >= 3) &&
312 ((e->timestamp - _ecore_win32_mouse_down_last_last_time) <= (unsigned long)(2 * 1000 * _ecore_win32_double_click_time)) &&
313 (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window) &&
314 (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_last_window))
315 e->triple_click = 1;
316
317 _ecore_win32_event_last_time = e->timestamp;
318 _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
319
320 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
321 }
322}
323
324void
325_ecore_win32_event_handle_motion_notify(Ecore_Win32_Callback_Data *msg)
326{
327 Ecore_Event_Mouse_Move *e;
328
329 INF("mouse moved");
330
331 e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
332 if (!e) return;
333
334 e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
335 e->event_window = e->window;
336 e->x = GET_X_LPARAM(msg->data_param);
337 e->y = GET_Y_LPARAM(msg->data_param);
338 e->timestamp = msg->timestamp;
339
340 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
341}
342
343void
344_ecore_win32_event_handle_enter_notify(Ecore_Win32_Callback_Data *msg)
345{
346 {
347 Ecore_Event_Mouse_Move *e;
348
349 INF("mouse in");
350
351 e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
352 if (!e) return;
353
354 e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
355 e->event_window = e->window;
356 e->x = msg->x;
357 e->y = msg->y;
358 e->timestamp = msg->timestamp;
359
360 _ecore_win32_event_last_time = e->timestamp;
361 _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
362
363 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
364 }
365
366 {
367 Ecore_Win32_Event_Mouse_In *e;
368
369 e = (Ecore_Win32_Event_Mouse_In *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_In));
370 if (!e) return;
371
372 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
373 e->x = msg->x;
374 e->y = msg->y;
375 e->timestamp = msg->timestamp ;
376
377 _ecore_win32_event_last_time = e->timestamp;
378
379 ecore_event_add(ECORE_WIN32_EVENT_MOUSE_IN, e, NULL, NULL);
380 }
381}
382
383void
384_ecore_win32_event_handle_leave_notify(Ecore_Win32_Callback_Data *msg)
385{
386 {
387 Ecore_Event_Mouse_Move *e;
388
389 INF("mouse out");
390
391 e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
392 if (!e) return;
393
394 e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
395 e->event_window = e->window;
396 e->x = msg->x;
397 e->y = msg->y;
398 e->timestamp = msg->timestamp;
399
400 _ecore_win32_event_last_time = e->timestamp;
401 _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
402
403 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
404 }
405
406 {
407 Ecore_Win32_Event_Mouse_Out *e;
408
409 e = (Ecore_Win32_Event_Mouse_Out *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Out));
410 if (!e) return;
411
412 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
413 e->x = msg->x;
414 e->y = msg->y;
415 e->timestamp = msg->timestamp;
416
417 _ecore_win32_event_last_time = e->timestamp;
418
419 ecore_event_add(ECORE_WIN32_EVENT_MOUSE_OUT, e, NULL, NULL);
420 }
421}
422
423void
424_ecore_win32_event_handle_focus_in(Ecore_Win32_Callback_Data *msg)
425{
426 Ecore_Win32_Event_Window_Focus_In *e;
427
428 INF("focus in");
429
430 e = (Ecore_Win32_Event_Window_Focus_In *)calloc(1, sizeof(Ecore_Win32_Event_Window_Focus_In));
431 if (!e) return;
432
433 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
434
435 e->timestamp = _ecore_win32_event_last_time;
436 _ecore_win32_event_last_time = e->timestamp;
437
438 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
439}
440
441void
442_ecore_win32_event_handle_focus_out(Ecore_Win32_Callback_Data *msg)
443{
444 Ecore_Win32_Event_Window_Focus_Out *e;
445
446 INF("focus out");
447
448 e = (Ecore_Win32_Event_Window_Focus_Out *)calloc(1, sizeof(Ecore_Win32_Event_Window_Focus_Out));
449 if (!e) return;
450
451 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
452
453 e->timestamp = _ecore_win32_event_last_time;
454 _ecore_win32_event_last_time = e->timestamp;
455
456 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
457}
458
459void
460_ecore_win32_event_handle_expose(Ecore_Win32_Callback_Data *msg)
461{
462 Ecore_Win32_Event_Window_Damage *e;
463
464 INF("window expose");
465
466 e = (Ecore_Win32_Event_Window_Damage *)calloc(1, sizeof(Ecore_Win32_Event_Window_Damage));
467 if (!e) return;
468
469 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
470
471 e->x = msg->update.left;
472 e->y = msg->update.top;
473 e->width = msg->update.right - msg->update.left;
474 e->height = msg->update.bottom - msg->update.top;
475
476 e->timestamp = _ecore_win32_event_last_time;
477
478 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
479}
480
481void
482_ecore_win32_event_handle_create_notify(Ecore_Win32_Callback_Data *msg)
483{
484 Ecore_Win32_Event_Window_Create *e;
485
486 INF("window create notify");
487
488 e = calloc(1, sizeof(Ecore_Win32_Event_Window_Create));
489 if (!e) return;
490
491 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
492
493 e->timestamp = _ecore_win32_event_last_time;
494
495 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CREATE, e, NULL, NULL);
496}
497
498void
499_ecore_win32_event_handle_destroy_notify(Ecore_Win32_Callback_Data *msg)
500{
501 Ecore_Win32_Event_Window_Destroy *e;
502
503 INF("window destroy notify");
504
505 e = calloc(1, sizeof(Ecore_Win32_Event_Window_Destroy));
506 if (!e) return;
507
508 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
509
510 e->timestamp = _ecore_win32_event_last_time;
511 if (e->window == _ecore_win32_event_last_window) _ecore_win32_event_last_window = NULL;
512
513 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DESTROY, e, NULL, NULL);
514}
515
516void
517_ecore_win32_event_handle_map_notify(Ecore_Win32_Callback_Data *msg)
518{
519 Ecore_Win32_Event_Window_Show *e;
520
521 INF("window map notify");
522
523 e = calloc(1, sizeof(Ecore_Win32_Event_Window_Show));
524 if (!e) return;
525
526 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
527
528 e->timestamp = _ecore_win32_event_last_time;
529
530 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_SHOW, e, NULL, NULL);
531}
532
533void
534_ecore_win32_event_handle_unmap_notify(Ecore_Win32_Callback_Data *msg)
535{
536 Ecore_Win32_Event_Window_Hide *e;
537
538 INF("window unmap notify");
539
540 e = calloc(1, sizeof(Ecore_Win32_Event_Window_Hide));
541 if (!e) return;
542
543 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
544
545 e->timestamp = _ecore_win32_event_last_time;
546
547 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_HIDE, e, NULL, NULL);
548}
549
550void
551_ecore_win32_event_handle_configure_notify(Ecore_Win32_Callback_Data *msg)
552{
553 WINDOWINFO wi;
554 Ecore_Win32_Event_Window_Configure *e;
555 WINDOWPOS *window_pos;
556
557 INF("window configure notify");
558
559 e = calloc(1, sizeof(Ecore_Win32_Event_Window_Configure));
560 if (!e) return;
561
562 window_pos = (WINDOWPOS *)msg->data_param;
563 wi.cbSize = sizeof(WINDOWINFO);
564 if (!GetWindowInfo(window_pos->hwnd, &wi))
565 {
566 free(e);
567 return;
568 }
569
570 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
571 e->abovewin = (void *)GetWindowLongPtr(window_pos->hwndInsertAfter, GWLP_USERDATA);
572 e->x = wi.rcClient.left;
573 e->y = wi.rcClient.top;
574 e->width = wi.rcClient.right - wi.rcClient.left;
575 e->height = wi.rcClient.bottom - wi.rcClient.top;
576 e->timestamp = _ecore_win32_event_last_time;
577
578 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
579}
580
581void
582_ecore_win32_event_handle_resize(Ecore_Win32_Callback_Data *msg)
583{
584 RECT rect;
585 Ecore_Win32_Event_Window_Resize *e;
586
587 INF("window resize");
588
589 if (!GetClientRect(msg->window, &rect))
590 return;
591
592 e = calloc(1, sizeof(Ecore_Win32_Event_Window_Resize));
593 if (!e) return;
594
595 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
596 e->width = rect.right - rect.left;
597 e->height = rect.bottom - rect.top;
598 e->timestamp = _ecore_win32_event_last_time;
599
600 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_RESIZE, e, NULL, NULL);
601}
602
603void
604_ecore_win32_event_handle_delete_request(Ecore_Win32_Callback_Data *msg)
605{
606 Ecore_Win32_Event_Window_Delete_Request *e;
607
608 INF("window delete request");
609
610 e = calloc(1, sizeof(Ecore_Win32_Event_Window_Delete_Request));
611 if (!e) return;
612
613 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
614 e->timestamp = _ecore_win32_event_last_time;
615
616 ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
617}
618
619
620/***** Private functions definitions *****/
621
622static void
623_ecore_win32_event_free_key_down(void *data EINA_UNUSED,
624 void *ev)
625{
626 Ecore_Event_Key *e;
627
628 e = ev;
629 if (e->keyname) free((char *)e->keyname);
630 if (e->key) free((char *)e->key);
631 if (e->string) free((char *)e->string);
632 free(e);
633}
634
635static void
636_ecore_win32_event_free_key_up(void *data EINA_UNUSED,
637 void *ev)
638{
639 Ecore_Event_Key *e;
640
641 e = ev;
642 if (e->keyname) free((char *)e->keyname);
643 if (e->key) free((char *)e->key);
644 if (e->string) free((char *)e->string);
645 free(e);
646}
647
648static int
649_ecore_win32_event_keystroke_get(Ecore_Win32_Callback_Data *msg,
650 Eina_Bool is_down,
651 char **keyname,
652 char **keysymbol,
653 char **keycompose,
654 unsigned int *modifiers)
655{
656 WCHAR buf[3];
657 char delete_string[2] = { 0x7f, 0 };
658 char *kn = NULL;
659 char *ks = NULL;
660 char *kc = NULL;
661 int key;
662 int is_extended;
663 int previous_key_state;
664
665 key = msg->window_param;
666 is_extended = msg->data_param & 0x01000000;
667 previous_key_state = msg->data_param & 0x40000000;
668
669 *keyname = NULL;
670 *keysymbol = NULL;
671 *keycompose = NULL;
672
673 switch (key)
674 {
675 /* Keystroke */
676 case VK_PRIOR:
677 if (is_extended)
678 {
679 kn = "Prior";
680 ks = "Prior";
681 kc = NULL;
682 }
683 else
684 {
685 kn = "KP_Prior";
686 ks = "KP_9";
687 kc = "KP_Prior";
688 }
689 break;
690 case VK_NEXT:
691 if (is_extended)
692 {
693 kn = "Next";
694 ks = "Next";
695 kc = NULL;
696 }
697 else
698 {
699 kn = "KP_Next";
700 ks = "KP_3";
701 kc = "KP_Next";
702 }
703 break;
704 case VK_END:
705 if (is_extended)
706 {
707 kn = "End";
708 ks = "End";
709 kc = NULL;
710 }
711 else
712 {
713 kn = "KP_End";
714 ks = "KP_1";
715 kc = "KP_End";
716 }
717 break;
718 case VK_HOME:
719 if (is_extended)
720 {
721 kn = "Home";
722 ks = "Home";
723 kc = NULL;
724 }
725 else
726 {
727 kn = "KP_Home";
728 ks = "KP_7";
729 kc = "KP_Home";
730 }
731 break;
732 case VK_LEFT:
733 if (is_extended)
734 {
735 kn = "Left";
736 ks = "Left";
737 kc = NULL;
738 }
739 else
740 {
741 kn = "KP_Left";
742 ks = "KP_4";
743 kc = "KP_Left";
744 }
745 break;
746 case VK_UP:
747 if (is_extended)
748 {
749 kn = "Up";
750 ks = "Up";
751 kc = NULL;
752 }
753 else
754 {
755 kn = "KP_Up";
756 ks = "KP_8";
757 kc = "KP_Up";
758 }
759 break;
760 case VK_RIGHT:
761 if (is_extended)
762 {
763 kn = "Right";
764 ks = "Right";
765 kc = NULL;
766 }
767 else
768 {
769 kn = "KP_Right";
770 ks = "KP_6";
771 kc = "KP_Right";
772 }
773 break;
774 case VK_DOWN:
775 if (is_extended)
776 {
777 kn = "Down";
778 ks = "Down";
779 kc = NULL;
780 }
781 else
782 {
783 kn = "KP_Down";
784 ks = "KP_2";
785 kc = "KP_Down";
786 }
787 break;
788 case VK_INSERT:
789 if (is_extended)
790 {
791 kn = "Insert";
792 ks = "Insert";
793 kc = NULL;
794 }
795 else
796 {
797 kn = "KP_Insert";
798 ks = "KP_0";
799 kc = "KP_Insert";
800 }
801 break;
802 case VK_DELETE:
803 if (is_extended)
804 {
805 kn = "Delete";
806 ks = "Delete";
807 kc = delete_string;
808 }
809 else
810 {
811 kn = "KP_Delete";
812 ks = "KP_Decimal";
813 kc = "KP_Delete";
814 }
815 break;
816 case VK_SHIFT:
817 {
818 SHORT res;
819
820 if (is_down)
821 {
822 if (previous_key_state) return 0;
823 res = GetKeyState(VK_LSHIFT);
824 if (res & 0x8000)
825 {
826 _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LSHIFT;
827 kn = "Shift_L";
828 ks = "Shift_L";
829 kc = "";
830 }
831 res = GetKeyState(VK_RSHIFT);
832 if (res & 0x8000)
833 {
834 _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RSHIFT;
835 kn = "Shift_R";
836 ks = "Shift_R";
837 kc = "";
838 }
839 *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT;
840 }
841 else /* is_up */
842 {
843 res = GetKeyState(VK_LSHIFT);
844 if (!(res & 0x8000) &&
845 (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LSHIFT))
846 {
847 kn = "Shift_L";
848 ks = "Shift_L";
849 kc = "";
850 _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LSHIFT;
851 }
852 res = GetKeyState(VK_RSHIFT);
853 if (!(res & 0x8000) &&
854 (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RSHIFT))
855 {
856 kn = "Shift_R";
857 ks = "Shift_R";
858 kc = "";
859 _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RSHIFT;
860 }
861 *modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
862 }
863 break;
864 }
865 case VK_CONTROL:
866 {
867 SHORT res;
868
869 if (msg->discard_ctrl)
870 return 0;
871
872 if (is_down)
873 {
874 if (previous_key_state) return 0;
875 res = GetKeyState(VK_LCONTROL);
876 if (res & 0x8000)
877 {
878 _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LCONTROL;
879 kn = "Control_L";
880 ks = "Control_L";
881 kc = "";
882 break;
883 }
884 res = GetKeyState(VK_RCONTROL);
885 if (res & 0x8000)
886 {
887 _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RCONTROL;
888 kn = "Control_R";
889 ks = "Control_R";
890 kc = "";
891 break;
892 }
893 *modifiers |= ECORE_EVENT_MODIFIER_CTRL;
894 }
895 else /* is_up */
896 {
897 res = GetKeyState(VK_LCONTROL);
898 if (!(res & 0x8000) &&
899 (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LCONTROL))
900 {
901 kn = "Control_L";
902 ks = "Control_L";
903 kc = "";