19bool GHOST_DropTargetX11::m_xdndInitialized =
false;
20DndClass GHOST_DropTargetX11::m_dndClass;
21Atom *GHOST_DropTargetX11::m_dndTypes =
nullptr;
22Atom *GHOST_DropTargetX11::m_dndActions =
nullptr;
23const char *GHOST_DropTargetX11::m_dndMimeTypes[] = {
24 "url/url",
"text/uri-list",
"text/plain",
"application/octet-stream"};
25int GHOST_DropTargetX11::m_refCounter = 0;
28#define dndTypeURIListID 1
29#define dndTypePlainTextID 2
30#define dndTypeOctetStreamID 3
32#define dndTypeURL m_dndTypes[dndTypeURLID]
33#define dndTypeURIList m_dndTypes[dndTypeURIListID]
34#define dndTypePlainText m_dndTypes[dndTypePlainTextID]
35#define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID]
37void GHOST_DropTargetX11::Initialize()
40 int dndTypesCount =
ARRAY_SIZE(m_dndMimeTypes);
43 xdnd_init(&m_dndClass, display);
45 m_dndTypes =
new Atom[dndTypesCount + 1];
46 XInternAtoms(display, (
char **)m_dndMimeTypes, dndTypesCount, 0, m_dndTypes);
47 m_dndTypes[dndTypesCount] = 0;
49 m_dndActions =
new Atom[8];
52 m_dndActions[counter++] = m_dndClass.XdndActionCopy;
53 m_dndActions[counter++] = m_dndClass.XdndActionMove;
56 dndActions[counter++] = dnd->XdndActionLink;
57 dndActions[counter++] = dnd->XdndActionAsk;
58 dndActions[counter++] = dnd->XdndActionPrivate;
59 dndActions[counter++] = dnd->XdndActionList;
60 dndActions[counter++] = dnd->XdndActionDescription;
63 m_dndActions[counter++] = 0;
66void GHOST_DropTargetX11::Uninitialize()
68 xdnd_shut(&m_dndClass);
70 delete[] m_dndActions;
75 : m_window(window), m_system(system)
77 if (!m_xdndInitialized) {
79 m_xdndInitialized =
true;
85 xdnd_set_dnd_aware(&m_dndClass, wnd,
nullptr);
86 xdnd_set_type_list(&m_dndClass, wnd, m_dndTypes);
95 if (m_refCounter == 0) {
97 m_xdndInitialized =
false;
102char *GHOST_DropTargetX11::FileUrlDecode(
const char *fileUrl)
104 if (strncmp(fileUrl,
"file://", 7) == 0) {
105 const char *file = fileUrl + 7;
112void *GHOST_DropTargetX11::getURIListGhostData(
const uchar *dropBuffer,
int dropBufferSize)
115 int totPaths = 0, curLength = 0;
118 for (
int i = 0; i <= dropBufferSize; i++) {
119 if (
ELEM(dropBuffer[i], 0,
'\n',
'\r')) {
135 for (
int i = 0; i <= dropBufferSize; i++) {
136 if (
ELEM(dropBuffer[i], 0,
'\n',
'\r')) {
138 char *curPath = (
char *)malloc(curLength + 1);
141 strncpy(curPath, (
char *)dropBuffer + i - curLength, curLength);
142 curPath[curLength] = 0;
144 decodedPath = FileUrlDecode(curPath);
164 void *data =
nullptr;
165 uchar *tmpBuffer = (
uchar *)malloc(dropBufferSize + 1);
166 bool needsFree =
true;
169 memcpy(tmpBuffer, dropBuffer, dropBufferSize);
170 tmpBuffer[dropBufferSize] = 0;
174 data = getURIListGhostData(tmpBuffer, dropBufferSize);
178 char *decodedPath = FileUrlDecode((
const char *)tmpBuffer);
205 int dropBufferSize, dropX, dropY;
217 void *data =
getGhostData(dropType, dropBuffer, dropBufferSize);
220 m_system->pushDragDropEvent(
void BLI_kdtree_nd_ free(KDTree *tree)
#define dndTypeOctetStream
char * GHOST_URL_decode_alloc(const char *buf_src, const int buf_src_len)
@ GHOST_kEventDraggingDropDone
@ GHOST_kDragnDropTypeUnknown
@ GHOST_kDragnDropTypeFilenames
@ GHOST_kDragnDropTypeString
bool GHOST_HandleClientMessage(XEvent *event)
void * getGhostData(Atom dropType, const unsigned char *dropBuffer, int dropBufferSize)
GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system)