17 bool GHOST_DropTargetX11::m_xdndInitialized =
false;
18 DndClass GHOST_DropTargetX11::m_dndClass;
19 Atom *GHOST_DropTargetX11::m_dndTypes =
nullptr;
20 Atom *GHOST_DropTargetX11::m_dndActions =
nullptr;
21 const char *GHOST_DropTargetX11::m_dndMimeTypes[] = {
22 "url/url",
"text/uri-list",
"text/plain",
"application/octet-stream"};
23 int GHOST_DropTargetX11::m_refCounter = 0;
25 #define dndTypeURLID 0
26 #define dndTypeURIListID 1
27 #define dndTypePlainTextID 2
28 #define dndTypeOctetStreamID 3
30 #define dndTypeURL m_dndTypes[dndTypeURLID]
31 #define dndTypeURIList m_dndTypes[dndTypeURIListID]
32 #define dndTypePlainText m_dndTypes[dndTypePlainTextID]
33 #define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID]
35 void GHOST_DropTargetX11::Initialize()
38 int dndTypesCount =
ARRAY_SIZE(m_dndMimeTypes);
41 xdnd_init(&m_dndClass, display);
43 m_dndTypes =
new Atom[dndTypesCount + 1];
44 XInternAtoms(display, (
char **)m_dndMimeTypes, dndTypesCount, 0, m_dndTypes);
45 m_dndTypes[dndTypesCount] = 0;
47 m_dndActions =
new Atom[8];
50 m_dndActions[
counter++] = m_dndClass.XdndActionCopy;
51 m_dndActions[
counter++] = m_dndClass.XdndActionMove;
54 dndActions[
counter++] = dnd->XdndActionLink;
55 dndActions[
counter++] = dnd->XdndActionAsk;
56 dndActions[
counter++] = dnd->XdndActionPrivate;
57 dndActions[
counter++] = dnd->XdndActionList;
58 dndActions[
counter++] = dnd->XdndActionDescription;
64 void GHOST_DropTargetX11::Uninitialize()
66 xdnd_shut(&m_dndClass);
68 delete[] m_dndActions;
73 : m_window(window), m_system(system)
75 if (!m_xdndInitialized) {
77 m_xdndInitialized =
true;
83 xdnd_set_dnd_aware(&m_dndClass, wnd, 0);
84 xdnd_set_type_list(&m_dndClass, wnd, m_dndTypes);
93 if (m_refCounter == 0) {
95 m_xdndInitialized =
false;
109 void GHOST_DropTargetX11::UrlDecode(
char *decodedOut,
int bufferSize,
const char *encodedIn)
112 unsigned int len = strlen(encodedIn);
115 unsigned int asciiCharacter;
116 char tempNumBuf[3] = {0};
117 bool bothDigits =
true;
119 memset(decodedOut, 0, bufferSize);
121 for (i = 0; i <
len; ++i) {
124 if (encodedIn[i] !=
'%') {
125 strncat(decodedOut, &encodedIn[i], 1);
126 assert((
int)strlen(decodedOut) < bufferSize);
131 state = STATE_CONVERTING;
134 case STATE_CONVERTING:
139 memset(tempNumBuf, 0,
sizeof(tempNumBuf));
142 state = STATE_SEARCH;
144 strncpy(tempNumBuf, &encodedIn[i], 2);
148 for (j = 0; j < 2; ++j) {
149 if (!isxdigit(tempNumBuf[j])) {
158 sscanf(tempNumBuf,
"%x", &asciiCharacter);
161 assert((
int)strlen(decodedOut) < bufferSize);
164 strncat(decodedOut, (
char *)&asciiCharacter, 1);
173 char *GHOST_DropTargetX11::FileUrlDecode(
char *fileUrl)
175 if (strncmp(fileUrl,
"file://", 7) == 0) {
177 int decodedSize = 4 * strlen(fileUrl) + 1;
178 char *decodedPath = (
char *)malloc(decodedSize);
180 UrlDecode(decodedPath, decodedSize, fileUrl + 7);
188 void *GHOST_DropTargetX11::getURIListGhostData(
unsigned char *dropBuffer,
int dropBufferSize)
191 int totPaths = 0, curLength = 0;
194 for (
int i = 0; i <= dropBufferSize; i++) {
195 if (dropBuffer[i] == 0 || dropBuffer[i] ==
'\n' || dropBuffer[i] ==
'\r') {
211 for (
int i = 0; i <= dropBufferSize; i++) {
212 if (dropBuffer[i] == 0 || dropBuffer[i] ==
'\n' || dropBuffer[i] ==
'\r') {
214 char *curPath = (
char *)malloc(curLength + 1);
217 strncpy(curPath, (
char *)dropBuffer + i - curLength, curLength);
218 curPath[curLength] = 0;
220 decodedPath = FileUrlDecode(curPath);
239 unsigned char *dropBuffer,
242 void *
data =
nullptr;
243 unsigned char *tmpBuffer = (
unsigned char *)malloc(dropBufferSize + 1);
244 bool needsFree =
true;
247 memcpy(tmpBuffer, dropBuffer, dropBufferSize);
248 tmpBuffer[dropBufferSize] = 0;
252 data = getURIListGhostData(tmpBuffer, dropBufferSize);
256 char *decodedPath = FileUrlDecode((
char *)tmpBuffer);
282 unsigned char *dropBuffer;
283 int dropBufferSize, dropX, dropY;
297 m_system->pushDragDropEvent(
void BLI_kdtree_nd_() free(KDTree *tree)
#define dndTypeOctetStream
enum DecodeState_e { STATE_SEARCH=0, STATE_CONVERTING } DecodeState_e
@ GHOST_kEventDraggingDropDone
@ GHOST_kDragnDropTypeUnknown
@ GHOST_kDragnDropTypeFilenames
@ GHOST_kDragnDropTypeString
bool GHOST_HandleClientMessage(XEvent *event)
void * getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize)
GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system)
ccl_gpu_kernel_postfix ccl_global int * counter