2 * Copyright 2020 Olaf Wintermann
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
29 static Atom XdndAware;
30 static Atom XdndSelection;
31 static Atom XdndStatus;
32 static Atom XdndActionCopy;
33 static Atom XdndFinished;
41 XtCallbackProc dropCallback;
44 static void checkSelectionValue(Widget w, XtPointer clientData, Atom *selType,
45 Atom *type, XtPointer value, unsigned long *length, int *format)
48 canDrop = 1; // we have a text/uri-list value
53 static void getSelectionValue(Widget w, XtPointer clientData, Atom *selType,
54 Atom *type, XtPointer value, unsigned long *length, int *format)
58 dropCallback(w, value, dropData);
65 memset(&msg, 0, sizeof(XEvent));
66 msg.xany.type = ClientMessage;
67 msg.xany.display = XtDisplay(w);
68 msg.xclient.window = src;
69 msg.xclient.message_type = XdndFinished;
70 msg.xclient.format = 32;
71 msg.xclient.data.l[0] = XtWindow(w);
72 XSendEvent(XtDisplay(w), msg.xclient.window, 0, 0, &msg);
78 static void xdnd_enter(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
79 //printf("xdnd_enter\n");
80 XtGetSelectionValue(w, XdndSelection, selType, checkSelectionValue, NULL, 0);
83 static void xdnd_position(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
84 //printf("xdnd_position\n");
86 src = event->xclient.data.l[0];
89 memset(&msg, 0, sizeof(XEvent));
90 msg.xany.type = ClientMessage;
91 msg.xany.display = XtDisplay(w);
92 msg.xclient.window = src;
93 msg.xclient.message_type = XdndStatus;
94 msg.xclient.format = 32;
95 msg.xclient.data.l[0] = XtWindow(w);
96 msg.xclient.data.l[1] = canDrop;
97 msg.xclient.data.l[4] = XdndActionCopy;
98 XSendEvent(XtDisplay(w), msg.xclient.window, 0, 0, &msg);
101 static void xdnd_drop(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
102 //printf("xdnd_drop\n");
104 XtGetSelectionValue(w, XdndSelection, selType, getSelectionValue, NULL, 0);
109 static void xdnd_leave(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
110 //printf("xdnd_leave\n");
114 static XtActionsRec xdndactions[] = {
115 {"xdnd_enter", xdnd_enter},
116 {"xdnd_position", xdnd_position},
117 {"xdnd_drop", xdnd_drop},
118 {"xdnd_leave", xdnd_leave}
125 XtCallbackProc dropCB,
126 XtPointer dropCBData)
129 XdndAware = XInternAtom(dpy, "XdndAware", False);
130 XdndSelection = XInternAtom(dpy, "XdndSelection", False);
131 XdndStatus = XInternAtom(dpy, "XdndStatus", False);
132 XdndActionCopy = XInternAtom(dpy, "XdndActionCopy", False);
133 XdndFinished = XInternAtom(dpy, "XdndFinished", False);
134 selType = XInternAtom(dpy, "text/uri-list", False);
139 sizeof(xdndactions) / sizeof(XtActionsRec));
141 dropCallback = dropCB;
142 dropData = dropCBData;
145 void XdndEnable(Widget w) {
158 XtOverrideTranslations(w, XtParseTranslationTable(
159 "<Message>XdndEnter: xdnd_enter()\n"
160 "<Message>XdndPosition: xdnd_position()\n"
161 "<Message>XdndDrop: xdnd_drop()\n"
162 "<Message>XdndLeave: xdnd_leave()\n"));