32 bool GHOST_DropTargetX11::m_xdndInitialized =
false;
33 DndClass GHOST_DropTargetX11::m_dndClass;
34 Atom *GHOST_DropTargetX11::m_dndTypes =
NULL;
35 Atom *GHOST_DropTargetX11::m_dndActions =
NULL;
36 const char *GHOST_DropTargetX11::m_dndMimeTypes[] = {
37 "url/url",
"text/uri-list",
"text/plain",
"application/octet-stream"};
38 int GHOST_DropTargetX11::m_refCounter = 0;
40 #define dndTypeURLID 0
41 #define dndTypeURIListID 1
42 #define dndTypePlainTextID 2
43 #define dndTypeOctetStreamID 3
45 #define dndTypeURL m_dndTypes[dndTypeURLID]
46 #define dndTypeURIList m_dndTypes[dndTypeURIListID]
47 #define dndTypePlainText m_dndTypes[dndTypePlainTextID]
48 #define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID]
50 void GHOST_DropTargetX11::Initialize(
void)
53 int dndTypesCount =
sizeof(m_dndMimeTypes) /
sizeof(
char *);
56 xdnd_init(&m_dndClass, display);
58 m_dndTypes =
new Atom[dndTypesCount + 1];
59 XInternAtoms(display, (
char **)m_dndMimeTypes, dndTypesCount, 0, m_dndTypes);
60 m_dndTypes[dndTypesCount] = 0;
62 m_dndActions =
new Atom[8];
65 m_dndActions[counter++] = m_dndClass.XdndActionCopy;
66 m_dndActions[counter++] = m_dndClass.XdndActionMove;
69 dndActions[counter++] = dnd->XdndActionLink;
70 dndActions[counter++] = dnd->XdndActionAsk;
71 dndActions[counter++] = dnd->XdndActionPrivate;
72 dndActions[counter++] = dnd->XdndActionList;
73 dndActions[counter++] = dnd->XdndActionDescription;
76 m_dndActions[counter++] = 0;
79 void GHOST_DropTargetX11::Uninitialize(
void)
81 xdnd_shut(&m_dndClass);
83 delete[] m_dndActions;
88 : m_window(window), m_system(system)
90 if (!m_xdndInitialized) {
92 m_xdndInitialized =
true;
98 xdnd_set_dnd_aware(&m_dndClass, wnd, 0);
99 xdnd_set_type_list(&m_dndClass, wnd, m_dndTypes);
108 if (m_refCounter == 0) {
110 m_xdndInitialized =
false;
123 void GHOST_DropTargetX11::UrlDecode(
char *decodedOut,
int bufferSize,
const char *encodedIn)
126 unsigned int len = strlen(encodedIn);
129 unsigned int asciiCharacter;
130 char tempNumBuf[3] = {0};
131 bool bothDigits =
true;
133 memset(decodedOut, 0, bufferSize);
135 for (i = 0; i <
len; ++i) {
138 if (encodedIn[i] !=
'%') {
139 strncat(decodedOut, &encodedIn[i], 1);
140 assert(strlen(decodedOut) < bufferSize);
153 memset(tempNumBuf, 0,
sizeof(tempNumBuf));
158 strncpy(tempNumBuf, &encodedIn[i], 2);
162 for (j = 0; j < 2; ++j) {
163 if (!isxdigit(tempNumBuf[j]))
171 sscanf(tempNumBuf,
"%x", &asciiCharacter);
174 assert(strlen(decodedOut) < bufferSize);
177 strncat(decodedOut, (
char *)&asciiCharacter, 1);
186 char *GHOST_DropTargetX11::FileUrlDecode(
char *fileUrl)
188 if (strncmp(fileUrl,
"file://", 7) == 0) {
190 int decodedSize = 4 * strlen(fileUrl) + 1;
191 char *decodedPath = (
char *)malloc(decodedSize);
193 UrlDecode(decodedPath, decodedSize, fileUrl + 7);
201 void *GHOST_DropTargetX11::getURIListGhostData(
unsigned char *dropBuffer,
int dropBufferSize)
204 int totPaths = 0, curLength = 0;
207 for (
int i = 0; i <= dropBufferSize; i++) {
208 if (dropBuffer[i] == 0 || dropBuffer[i] ==
'\n' || dropBuffer[i] ==
'\r') {
223 for (
int i = 0; i <= dropBufferSize; i++) {
224 if (dropBuffer[i] == 0 || dropBuffer[i] ==
'\n' || dropBuffer[i] ==
'\r') {
226 char *curPath = (
char *)malloc(curLength + 1);
229 strncpy(curPath, (
char *)dropBuffer + i - curLength, curLength);
230 curPath[curLength] = 0;
232 decodedPath = FileUrlDecode(curPath);
250 unsigned char *dropBuffer,
254 unsigned char *tmpBuffer = (
unsigned char *)malloc(dropBufferSize + 1);
255 bool needsFree =
true;
258 memcpy(tmpBuffer, dropBuffer, dropBufferSize);
259 tmpBuffer[dropBufferSize] = 0;
263 data = getURIListGhostData(tmpBuffer, dropBufferSize);
267 char *decodedPath = FileUrlDecode((
char *)tmpBuffer);
292 unsigned char *dropBuffer;
293 int dropBufferSize, dropX, dropY;
307 m_system->pushDragDropEvent(
void BLI_kdtree_nd_() free(KDTree *tree)
@ STATE_SEARCH
searching for an ampersand to convert
@ STATE_CONVERTING
convert the two proceeding characters from hex
#define dndTypeOctetStream
@ GHOST_kEventDraggingDropDone
@ GHOST_kDragnDropTypeUnknown
@ GHOST_kDragnDropTypeFilenames
@ GHOST_kDragnDropTypeString
unsigned char GHOST_TUns8
bool GHOST_HandleClientMessage(XEvent *event)
void * getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize)
GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system)