svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_win32 / ecore_win32_dnd.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #include <windows.h>
10
11 #include "Ecore_Win32.h"
12 #include "ecore_win32_private.h"
13
14
15 static int _ecore_win32_dnd_init_count = 0;
16
17 static HANDLE DataToHandle(const char *data, int size)
18 {
19    char *ptr;
20    ptr = (char *)GlobalAlloc(GMEM_FIXED, size);
21    memcpy(ptr, data, size);
22    return ptr;
23 }
24
25
26 int
27 ecore_win32_dnd_init()
28 {
29    if (_ecore_win32_dnd_init_count > 0)
30      {
31         _ecore_win32_dnd_init_count++;
32         return _ecore_win32_dnd_init_count;
33      }
34
35    if (OleInitialize(NULL) != S_OK)
36      return 0;
37
38    _ecore_win32_dnd_init_count++;
39
40    return _ecore_win32_dnd_init_count;
41 }
42
43 int ecore_win32_dnd_shutdown()
44 {
45    _ecore_win32_dnd_init_count--;
46    if (_ecore_win32_dnd_init_count > 0) return _ecore_win32_dnd_init_count;
47
48    OleUninitialize();
49
50    if (_ecore_win32_dnd_init_count < 0) _ecore_win32_dnd_init_count = 0;
51
52    return _ecore_win32_dnd_init_count;
53 }
54
55 int ecore_win32_dnd_begin(const char *data,
56                           int         size)
57 {
58    IDataObject *pDataObject = NULL;
59    IDropSource *pDropSource = NULL;
60    FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
61    STGMEDIUM stgmed = { TYMED_HGLOBAL, { 0 }, 0 };
62    int res = 0;
63
64    if (data == NULL)
65       return 0;
66    if (size < 0)
67       size = strlen(data) + 1;
68
69    stgmed.hGlobal = DataToHandle(data, size);
70
71    // create the data object
72    pDataObject = (IDataObject *)_ecore_win32_dnd_data_object_new((void *)&fmtetc,
73                                                                  (void *)&stgmed,
74                                                                  1);
75    pDropSource = (IDropSource *)_ecore_win32_dnd_drop_source_new();
76
77    if (pDataObject && pDropSource)
78    {
79       DWORD dwResult;
80       DWORD dwEffect = DROPEFFECT_COPY;
81
82       // do the drag-drop!
83       dwResult = DoDragDrop(pDataObject, pDropSource, DROPEFFECT_COPY, &dwEffect);
84
85       // finished. Check the return values to see if we need to do anything else
86       if (dwResult == DRAGDROP_S_DROP)
87       {
88          //printf(">>> \"%s\" Dropped <<<\n", str);
89          if(dwEffect == DROPEFFECT_MOVE)
90          {
91             // remove the data we just dropped from active document
92          }
93       }
94       //else if (dwResult == DRAGDROP_S_CANCEL)
95       //   printf("DND cancelled\n");
96       //else
97       //   printf("DND error\n");
98
99       res = 1;
100    }
101
102    _ecore_win32_dnd_data_object_free(pDataObject);
103    _ecore_win32_dnd_drop_source_free(pDropSource);
104
105    // cleanup
106    ReleaseStgMedium(&stgmed);
107    return (int)res;
108 }
109
110 int ecore_win32_dnd_register_drop_target(Ecore_Win32_Window                 *window,
111                                          Ecore_Win32_Dnd_DropTarget_Callback callback)
112 {
113    struct _Ecore_Win32_Window *wnd = (struct _Ecore_Win32_Window *)window;
114
115    if (window == NULL)
116       return 0;
117
118    wnd->dnd_drop_target = _ecore_win32_dnd_register_drop_window(wnd->window,
119                                                                 callback,
120                                                                 (void *)wnd);
121    return (int)(wnd->dnd_drop_target != NULL);
122 }
123
124 void ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window)
125 {
126    struct _Ecore_Win32_Window *wnd = (struct _Ecore_Win32_Window *)window;
127
128    if (window == NULL)
129       return;
130
131    if (wnd->dnd_drop_target != NULL)
132       _ecore_win32_dnd_unregister_drop_window(wnd->window, wnd->dnd_drop_target);
133 }