19bool GHOST_DropTargetX11::xdnd_initialized_ =
false;
20DndClass GHOST_DropTargetX11::dnd_class_;
21Atom *GHOST_DropTargetX11::dnd_types_ =
nullptr;
22Atom *GHOST_DropTargetX11::dnd_actions_ =
nullptr;
23const char *GHOST_DropTargetX11::dnd_mime_types_[] = {
24 "url/url",
"text/uri-list",
"text/plain",
"application/octet-stream"};
25int GHOST_DropTargetX11::ref_counter_ = 0;
28#define dndTypeURIListID 1
29#define dndTypePlainTextID 2
30#define dndTypeOctetStreamID 3
32#define dndTypeURL dnd_types_[dndTypeURLID]
33#define dndTypeURIList dnd_types_[dndTypeURIListID]
34#define dndTypePlainText dnd_types_[dndTypePlainTextID]
35#define dndTypeOctetStream dnd_types_[dndTypeOctetStreamID]
37void GHOST_DropTargetX11::Initialize()
40 int dndTypesCount =
ARRAY_SIZE(dnd_mime_types_);
43 xdnd_init(&dnd_class_, display);
45 dnd_types_ =
new Atom[dndTypesCount + 1];
46 XInternAtoms(display, (
char **)dnd_mime_types_, dndTypesCount, 0, dnd_types_);
47 dnd_types_[dndTypesCount] = 0;
49 dnd_actions_ =
new Atom[8];
52 dnd_actions_[counter++] = dnd_class_.XdndActionCopy;
53 dnd_actions_[counter++] = dnd_class_.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 dnd_actions_[counter++] = 0;
66void GHOST_DropTargetX11::Uninitialize()
68 xdnd_shut(&dnd_class_);
70 delete[] dnd_actions_;
75 : window_(window), system_(system)
77 if (!xdnd_initialized_) {
79 xdnd_initialized_ =
true;
85 xdnd_set_dnd_aware(&dnd_class_, wnd,
nullptr);
86 xdnd_set_type_list(&dnd_class_, wnd, dnd_types_);
95 if (ref_counter_ == 0) {
97 xdnd_initialized_ =
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)
114 GHOST_TStringArray *strArray =
nullptr;
115 int totPaths = 0, curLength = 0;
118 for (
int i = 0;
i <= dropBufferSize;
i++) {
119 if (
ELEM(dropBuffer[
i], 0,
'\n',
'\r')) {
130 strArray = (GHOST_TStringArray *)malloc(
sizeof(GHOST_TStringArray));
132 strArray->
strings = (
uint8_t **)malloc(totPaths *
sizeof(uint8_t *));
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;
207 if (xdnd_get_drop(system_->getXDisplay(),
220 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
BMesh const char void * data
bool GHOST_HandleClientMessage(XEvent *event)
void * getGhostData(Atom dropType, const unsigned char *dropBuffer, int dropBufferSize)
GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system)