Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_win32 / ecore_win32_dnd.c
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
19 static int _ecore_win32_dnd_init_count = 0;
20
21 static 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  */
61 EAPI int
62 ecore_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  */
88 EAPI int
89 ecore_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  */
113 EAPI Eina_Bool
114 ecore_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  */
184 EAPI Eina_Bool
185 ecore_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  */
207 EAPI void
208 ecore_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  */