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