mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-21 05:18:06 +01:00
wmaker: fix xdnd accepted type
This patch is ensuring that the data dropped is a file format URI and converting it as stated by XDND specs. It solves: *crash in my env when arbitrary stuff is dropped *correct handling of non ascii chars
This commit is contained in:
committed by
Carlos R. Mafra
parent
fe177c6966
commit
be5b58aaee
45
src/xdnd.c
45
src/xdnd.c
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ void wXDNDMakeAwareness(Window window)
|
|||||||
/*
|
/*
|
||||||
MotifDragReceiverInfo info;
|
MotifDragReceiverInfo info;
|
||||||
*/
|
*/
|
||||||
XChangeProperty(dpy, window, _XA_XdndAware, XA_ATOM, 32, PropModeAppend, (char *)&xdnd_version, 1);
|
XChangeProperty(dpy, window, _XA_XdndAware, XA_ATOM, 32, PropModeAppend, (unsigned char *)&xdnd_version, 1);
|
||||||
|
|
||||||
/*** MOTIF ***
|
/*** MOTIF ***
|
||||||
info.byte_order = '\0';
|
info.byte_order = '\0';
|
||||||
@@ -84,6 +85,21 @@ void wXDNDMakeAwareness(Window window)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wXDNDDecodeURI(char *uri) {
|
||||||
|
char *last = uri + strlen(uri);
|
||||||
|
while (uri < last-2) {
|
||||||
|
if (*uri == '%') {
|
||||||
|
int h;
|
||||||
|
if (sscanf(uri+1, "%2X", &h) != 1)
|
||||||
|
break;
|
||||||
|
*uri = h;
|
||||||
|
memmove(uri+1, uri+3, last - (uri+2));
|
||||||
|
last -= 2;
|
||||||
|
}
|
||||||
|
uri++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Bool wXDNDProcessSelection(XEvent * event)
|
Bool wXDNDProcessSelection(XEvent * event)
|
||||||
{
|
{
|
||||||
WScreen *scr = wScreenForWindow(event->xselection.requestor);
|
WScreen *scr = wScreenForWindow(event->xselection.requestor);
|
||||||
@@ -95,15 +111,11 @@ Bool wXDNDProcessSelection(XEvent * event)
|
|||||||
char *delme;
|
char *delme;
|
||||||
XEvent xevent;
|
XEvent xevent;
|
||||||
Window selowner = XGetSelectionOwner(dpy, _XA_XdndSelection);
|
Window selowner = XGetSelectionOwner(dpy, _XA_XdndSelection);
|
||||||
WMArray *items;
|
|
||||||
|
|
||||||
XGetWindowProperty(dpy, event->xselection.requestor,
|
XGetWindowProperty(dpy, event->xselection.requestor,
|
||||||
_XA_WINDOWMAKER_XDNDEXCHANGE,
|
_XA_WINDOWMAKER_XDNDEXCHANGE,
|
||||||
0, 65536, True, atom_support, &ret_type, &ret_format,
|
0, 65536, True, atom_support, &ret_type, &ret_format,
|
||||||
&ret_item, &remain_byte, (unsigned char **)&delme);
|
&ret_item, &remain_byte, (unsigned char **)&delme);
|
||||||
if (delme) {
|
|
||||||
scr->xdestring = delme;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*send finished */
|
/*send finished */
|
||||||
memset(&xevent, 0, sizeof(xevent));
|
memset(&xevent, 0, sizeof(xevent));
|
||||||
@@ -116,12 +128,14 @@ Bool wXDNDProcessSelection(XEvent * event)
|
|||||||
XSendEvent(dpy, selowner, 0, 0, &xevent);
|
XSendEvent(dpy, selowner, 0, 0, &xevent);
|
||||||
|
|
||||||
/*process dropping */
|
/*process dropping */
|
||||||
if (scr->xdestring) {
|
if (delme) {
|
||||||
|
WMArray *items;
|
||||||
WMArrayIterator iter;
|
WMArrayIterator iter;
|
||||||
int length, str_size;
|
int length, str_size;
|
||||||
int total_size = 0;
|
int total_size = 0;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
|
scr->xdestring = delme;
|
||||||
items = WMCreateArray(4);
|
items = WMCreateArray(4);
|
||||||
retain = wstrdup(scr->xdestring);
|
retain = wstrdup(scr->xdestring);
|
||||||
XFree(scr->xdestring); /* since xdestring was created by Xlib */
|
XFree(scr->xdestring); /* since xdestring was created by Xlib */
|
||||||
@@ -153,23 +167,20 @@ Bool wXDNDProcessSelection(XEvent * event)
|
|||||||
scr->xdestring = wmalloc(total_size);
|
scr->xdestring = wmalloc(total_size);
|
||||||
scr->xdestring[0] = 0; /* empty string */
|
scr->xdestring[0] = 0; /* empty string */
|
||||||
WM_ETARETI_ARRAY(items, tmp, iter) {
|
WM_ETARETI_ARRAY(items, tmp, iter) {
|
||||||
if (!strncmp(tmp, "file:", 5)) {
|
/* only supporting file: URI objects */
|
||||||
/* add more 2 chars while removing 5 is harmless */
|
if (!strncmp(tmp, "file://", 7)) {
|
||||||
|
/* drag-and-drop file name format as per the spec is encoded as an URI */
|
||||||
|
wXDNDDecodeURI(&tmp[7]);
|
||||||
strcat(scr->xdestring, " \"");
|
strcat(scr->xdestring, " \"");
|
||||||
strcat(scr->xdestring, &tmp[5]);
|
strcat(scr->xdestring, &tmp[7]);
|
||||||
strcat(scr->xdestring, "\"");
|
strcat(scr->xdestring, "\"");
|
||||||
} else {
|
|
||||||
/* unsupport object, still need more " ? tell ]d */
|
|
||||||
strcat(scr->xdestring, &tmp[5]);
|
|
||||||
}
|
}
|
||||||
wfree(tmp);
|
wfree(tmp);
|
||||||
}
|
}
|
||||||
WMFreeArray(items);
|
WMFreeArray(items);
|
||||||
|
if (scr->xdestring[0]) {
|
||||||
wDockReceiveDNDDrop(scr, event);
|
wDockReceiveDNDDrop(scr, event);
|
||||||
/*
|
}
|
||||||
printf("free ");
|
|
||||||
puts(scr->xdestring);
|
|
||||||
*/
|
|
||||||
wfree(scr->xdestring); /* this xdestring is not from Xlib (no XFree) */
|
wfree(scr->xdestring); /* this xdestring is not from Xlib (no XFree) */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,7 +302,7 @@ Bool wXDNDProcessClientMessage(XClientMessageEvent * event)
|
|||||||
XConvertSelection(dpy, _XA_XdndSelection, atom_support,
|
XConvertSelection(dpy, _XA_XdndSelection, atom_support,
|
||||||
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
|
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
|
||||||
} else {
|
} else {
|
||||||
puts("wierd selection owner? QT?");
|
//printf("weird selection owner? QT?\n");
|
||||||
XConvertSelection(dpy, _XA_XdndSelection, atom_support,
|
XConvertSelection(dpy, _XA_XdndSelection, atom_support,
|
||||||
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
|
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user