1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00

xdnd drop support on dock.

This commit is contained in:
id
1999-05-17 20:21:43 +00:00
parent d6f1c81924
commit d40250728d
14 changed files with 383 additions and 165 deletions

View File

@@ -77,8 +77,8 @@ wmaker_SOURCES = \
texture.h \ texture.h \
usermenu.c \ usermenu.c \
usermenu.h \ usermenu.h \
xde.h \ xdnd.h \
xde.c \ xdnd.c \
xmodifier.h \ xmodifier.h \
xmodifier.c \ xmodifier.c \
xutil.c \ xutil.c \

View File

@@ -99,7 +99,7 @@ bin_PROGRAMS = wmaker
EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h
wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c appicon.h application.c application.h appmenu.c appmenu.h balloon.c balloon.h client.c client.h colormap.c def_pixmaps.h defaults.c defaults.h dialog.c dialog.h dock.c dockedapp.c dock.h event.c framewin.c framewin.h gnome.c gnome.h funcs.h icon.c icon.h keybind.h kwm.h kwm.c list.c list.h main.c menu.c menu.h misc.c motif.c motif.h moveres.c openlook.c openlook.h pixmap.c pixmap.h placement.c properties.c properties.h proplist.c resources.c resources.h rootmenu.c screen.c screen.h session.h session.c shutdown.c stacking.c stacking.h startup.c superfluous.c superfluous.h switchmenu.c texture.c texture.h usermenu.c usermenu.h xde.h xde.c xmodifier.h xmodifier.c xutil.c xutil.h wconfig.h wcore.c wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c winspector.h winspector.c workspace.c workspace.h wmsound.c wmsound.h text.c text.h wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c appicon.h application.c application.h appmenu.c appmenu.h balloon.c balloon.h client.c client.h colormap.c def_pixmaps.h defaults.c defaults.h dialog.c dialog.h dock.c dockedapp.c dock.h event.c framewin.c framewin.h gnome.c gnome.h funcs.h icon.c icon.h keybind.h kwm.h kwm.c list.c list.h main.c menu.c menu.h misc.c motif.c motif.h moveres.c openlook.c openlook.h pixmap.c pixmap.h placement.c properties.c properties.h proplist.c resources.c resources.h rootmenu.c screen.c screen.h session.h session.c shutdown.c stacking.c stacking.h startup.c superfluous.c superfluous.h switchmenu.c texture.c texture.h usermenu.c usermenu.h xdnd.h xdnd.c xmodifier.h xmodifier.c xutil.c xutil.h wconfig.h wcore.c wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c winspector.h winspector.c workspace.c workspace.h wmsound.c wmsound.h text.c text.h
CPPFLAGS = @CPPFLAGS@ @DFLAGS@ -DLOCALEDIR=\"$(NLSDIR)\" CPPFLAGS = @CPPFLAGS@ @DFLAGS@ -DLOCALEDIR=\"$(NLSDIR)\"
@@ -126,7 +126,7 @@ client.o colormap.o defaults.o dialog.o dock.o dockedapp.o event.o \
framewin.o gnome.o icon.o kwm.o list.o main.o menu.o misc.o motif.o \ framewin.o gnome.o icon.o kwm.o list.o main.o menu.o misc.o motif.o \
moveres.o openlook.o pixmap.o placement.o properties.o proplist.o \ moveres.o openlook.o pixmap.o placement.o properties.o proplist.o \
resources.o rootmenu.o screen.o session.o shutdown.o stacking.o \ resources.o rootmenu.o screen.o session.o shutdown.o stacking.o \
startup.o superfluous.o switchmenu.o texture.o usermenu.o xde.o \ startup.o superfluous.o switchmenu.o texture.o usermenu.o xdnd.o \
xmodifier.o xutil.o wcore.o wdefaults.o window.o winmenu.o winspector.o \ xmodifier.o xutil.o wcore.o wdefaults.o window.o winmenu.o winspector.o \
workspace.o wmsound.o text.o workspace.o wmsound.o text.o
wmaker_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.a \ wmaker_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.a \

View File

@@ -44,6 +44,9 @@
#include "framewin.h" #include "framewin.h"
#include "dialog.h" #include "dialog.h"
#include "client.h" #include "client.h"
#ifdef XDND
#include "xdnd.h"
#endif
/* /*
* icon_file for the dock is got from the preferences file by * icon_file for the dock is got from the preferences file by
@@ -103,6 +106,9 @@ wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance,
dicon->icon = wIconCreateWithIconFile(scr, path, tile); dicon->icon = wIconCreateWithIconFile(scr, path, tile);
if (path) if (path)
free(path); free(path);
#ifdef XDND
wXDNDMakeAwareness(dicon->icon->core->window);
#endif
#ifdef REDUCE_APPICONS #ifdef REDUCE_APPICONS
dicon->num_apps = 0; dicon->num_apps = 0;
#endif #endif
@@ -219,6 +225,9 @@ wAppIconCreate(WWindow *leader_win)
CWSaveUnder, &attribs); CWSaveUnder, &attribs);
} }
#endif #endif
#ifdef XDND
wXDNDMakeAwareness(aicon->icon->core->window);
#endif
/* will be overriden if docked */ /* will be overriden if docked */
aicon->icon->core->descriptor.handle_mousedown = appIconMouseDown; aicon->icon->core->descriptor.handle_mousedown = appIconMouseDown;

View File

@@ -34,8 +34,8 @@
#ifdef SHAPE #ifdef SHAPE
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#endif #endif
#ifdef XDE_DND #ifdef XDND
#include "xde.h" #include "xdnd.h"
#endif #endif
#ifdef KEEP_XKB_LOCK_STATUS #ifdef KEEP_XKB_LOCK_STATUS
@@ -405,6 +405,7 @@ handleDeadProcess(void *foo)
static void static void
saveTimestamp(XEvent *event) saveTimestamp(XEvent *event)
{ {
WScreen *scr = wScreenForWindow(event->xany.window);
LastTimestamp = CurrentTime; LastTimestamp = CurrentTime;
switch (event->type) { switch (event->type) {
@@ -434,6 +435,29 @@ saveTimestamp(XEvent *event)
break; break;
case SelectionNotify: case SelectionNotify:
LastTimestamp = event->xselection.time; LastTimestamp = event->xselection.time;
#ifdef XDND
wXDNDProcessSelection(&event->xselection);
{
char *retain = scr->xdestring;
for (;retain[0];retain++) {
if (retain[0] < 32) retain[0] = 32;
if (!strncmp(retain, "file:", 5)) {
int i;
for (i=0;i<5;retain[i++]=' ');
}
}
retain = scr->xdestring;
if (scr->xdestring){
if (!strncmp(scr->xdestring, "file:", 5))
scr->xdestring+=5;
}
wDockReceiveDNDDrop(scr,event);
if (retain){
XFree(retain);
scr->xdestring = NULL;
}
}
#endif
break; break;
} }
} }
@@ -911,10 +935,10 @@ handleClientMessage(XEvent *event)
} else if (wKWMProcessClientMessage(&event->xclient)) { } else if (wKWMProcessClientMessage(&event->xclient)) {
/* do nothing */ /* do nothing */
#endif /* KWM_HINTS */ #endif /* KWM_HINTS */
#ifdef XDE_DND #ifdef XDND
} else if (wXDEProcessClientMessage(&event->xclient)) { } else if (wXDNDProcessClientMessage(&event->xclient)) {
/* do nothing */ /* do nothing */
#endif /* XDE_DND */ #endif /* XDND */
#ifdef OFFIX_DND #ifdef OFFIX_DND
} else if (event->xclient.message_type==_XA_DND_PROTOCOL) { } else if (event->xclient.message_type==_XA_DND_PROTOCOL) {
WScreen *scr = wScreenForWindow(event->xclient.window); WScreen *scr = wScreenForWindow(event->xclient.window);

View File

@@ -113,15 +113,6 @@ Atom _XA_WINDOWMAKER_COMMAND;
Atom _XA_DND_PROTOCOL; Atom _XA_DND_PROTOCOL;
Atom _XA_DND_SELECTION; Atom _XA_DND_SELECTION;
#endif #endif
#ifdef XDE_DND
Atom _XA_XDE_REQUEST;
Atom _XA_XDE_ENTER;
Atom _XA_XDE_LEAVE;
Atom _XA_XDE_DATA_AVAILABLE;
Atom _XDE_FILETYPE;
Atom _XDE_URLTYPE;
#endif
/* cursors */ /* cursors */
Cursor wCursor[WCUR_LAST]; Cursor wCursor[WCUR_LAST];

View File

@@ -875,8 +875,11 @@ get_dnd_selection(WScreen *scr)
char *flat_string; char *flat_string;
int count; int count;
#ifdef XDE_DND #ifdef XDND
if(scr->xdestring) { if(scr->xdestring) {
/*
printf(" return %s\n",scr->xdestring);
*/
return (wstrdup(scr->xdestring)); return (wstrdup(scr->xdestring));
} }
#endif #endif

View File

@@ -26,10 +26,6 @@
#include "WindowMaker.h" #include "WindowMaker.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef XDE_DND
#include <gdk/gdk.h>
#endif
#include <proplist.h> #include <proplist.h>
@@ -298,7 +294,7 @@ typedef struct _WScreen {
struct WWindow *shortcutWindow[MAX_WINDOW_SHORTCUTS]; struct WWindow *shortcutWindow[MAX_WINDOW_SHORTCUTS];
struct LinkedList *shortcutSelectedWindows[MAX_WINDOW_SHORTCUTS]; struct LinkedList *shortcutSelectedWindows[MAX_WINDOW_SHORTCUTS];
#ifdef XDE_DND #ifdef XDND
char *xdestring; char *xdestring;
#endif #endif

View File

@@ -57,6 +57,9 @@
#include "defaults.h" #include "defaults.h"
#include "properties.h" #include "properties.h"
#include "dialog.h" #include "dialog.h"
#ifdef XDND
#include "xdnd.h"
#endif
#include "xutil.h" #include "xutil.h"
@@ -125,14 +128,6 @@ extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
extern Atom _XA_DND_PROTOCOL; extern Atom _XA_DND_PROTOCOL;
extern Atom _XA_DND_SELECTION; extern Atom _XA_DND_SELECTION;
#endif #endif
#ifdef XDE_DND
extern Atom _XA_XDE_REQUEST;
extern Atom _XA_XDE_ENTER;
extern Atom _XA_XDE_LEAVE;
extern Atom _XA_XDE_DATA_AVAILABLE;
extern Atom _XDE_FILETYPE;
extern Atom _XDE_URLTYPE;
#endif
/* cursors */ /* cursors */
@@ -697,13 +692,8 @@ StartUp(Bool defaultScreenOnly)
_XA_DND_SELECTION = XInternAtom(dpy, "DndSelection", False); _XA_DND_SELECTION = XInternAtom(dpy, "DndSelection", False);
_XA_DND_PROTOCOL = XInternAtom(dpy, "DndProtocol", False); _XA_DND_PROTOCOL = XInternAtom(dpy, "DndProtocol", False);
#endif #endif
#ifdef XDE_DND #ifdef XDND
_XA_XDE_ENTER = XInternAtom(dpy, "_XDE_ENTER", False); wXDNDInitializeAtoms();
_XA_XDE_REQUEST = XInternAtom(dpy, "_XDE_REQUEST", False);
_XA_XDE_LEAVE = XInternAtom(dpy, "_XDE_LEAVE", False);
_XA_XDE_DATA_AVAILABLE = XInternAtom(dpy, "_XDE_DATA_AVAILABLE", False);
_XDE_FILETYPE = XInternAtom(dpy, "file:ALL", False);
_XDE_URLTYPE = XInternAtom(dpy, "url:ALL", False);
#endif #endif

View File

@@ -72,9 +72,9 @@
#define OFFIX_DND #define OFFIX_DND
/* /*
* support for XDE drang and drop in the Dock. Experimental * support for XDND drop in the Dock. Experimental
*/ */
#undef XDE_DND #undef XDND
/* /*
* support for Motif window manager (mwm) window hints * support for Motif window manager (mwm) window hints

View File

@@ -69,9 +69,6 @@ wCoreCreateTopLevel(WScreen *screen, int x, int y, int width, int height,
attribs.border_pixel = screen->frame_border_pixel; attribs.border_pixel = screen->frame_border_pixel;
attribs.event_mask = SubstructureRedirectMask | ButtonPressMask attribs.event_mask = SubstructureRedirectMask | ButtonPressMask
| ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask
#ifdef XDE_DND
| StructureNotifyMask
#endif
| LeaveWindowMask; | LeaveWindowMask;
vmask |= CWColormap; vmask |= CWColormap;

113
src/xde.c
View File

@@ -1,113 +0,0 @@
#include "wconfig.h"
#ifdef XDE_DND
#include <X11/Xlib.h>
#include "WindowMaker.h"
#include "window.h"
#include "stdlib.h"
#include <X11/Xatom.h>
#include <gdk/gdk.h>
extern Atom _XA_XDE_REQUEST;
extern Atom _XA_XDE_ENTER;
extern Atom _XA_XDE_LEAVE;
extern Atom _XA_XDE_DATA_AVAILABLE;
extern Atom _XDE_FILETYPE;
extern Atom _XDE_URLTYPE;
Bool
wXDEProcessClientMessage(XClientMessageEvent *event)
{
Bool done = False;
if (event->message_type==_XA_XDE_DATA_AVAILABLE) {
GdkEvent gdkev;
WScreen *scr = wScreenForWindow(event->window);
Atom tmpatom;
int datalenght;
long tmplong;
char * tmpstr, * runstr, * freestr, * tofreestr;
printf("x\n");
gdkev.dropdataavailable.u.allflags = event->data.l[1];
gdkev.dropdataavailable.timestamp = event->data.l[4];
if(gdkev.dropdataavailable.u.flags.isdrop){
gdkev.dropdataavailable.type = GDK_DROP_DATA_AVAIL;
gdkev.dropdataavailable.requestor = event->data.l[0];
XGetWindowProperty(dpy,gdkev.dropdataavailable.requestor,
event->data.l[2],
0, LONG_MAX -1,
0, XA_PRIMARY, &tmpatom,
&datalenght,
&gdkev.dropdataavailable.data_numbytes,
&tmplong,
&tmpstr);
datalenght=gdkev.dropdataavailable.data_numbytes-1;
tofreestr=tmpstr;
runstr=NULL;
for(;datalenght>0;datalenght-=(strlen(tmpstr)+1),tmpstr=&tmpstr[strlen(tmpstr)+1]){
freestr=runstr;runstr=wstrappend(runstr,tmpstr);free(freestr);
freestr=runstr;runstr=wstrappend(runstr," ");free(freestr);
}
free(tofreestr);
scr->xdestring=runstr;
/* no need to redirect ? */
wDockReceiveDNDDrop(scr,event);
free(runstr);
scr->xdestring=NULL;
}
done = True;
} else if (event->message_type==_XA_XDE_LEAVE) {
printf("leave\n");
done = True;
} else if (event->message_type==_XA_XDE_ENTER) {
GdkEvent gdkev;
XEvent replyev;
gdkev.dropenter.u.allflags=event->data.l[1];
printf("from win %x\n",event->data.l[0]);
printf("to win %x\n",event->window);
printf("enter %x\n",event->data.l[1]);
printf("v %x ",event->data.l[2]);
printf("%x ",event->data.l[3]);
printf("%x\n",event->data.l[4]);
if(event->data.l[2]==_XDE_FILETYPE ||
event->data.l[3]==_XDE_FILETYPE ||
event->data.l[4]==_XDE_FILETYPE ||
event->data.l[2]==_XDE_URLTYPE ||
event->data.l[3]==_XDE_URLTYPE ||
event->data.l[4]==_XDE_URLTYPE)
if(gdkev.dropenter.u.flags.sendreply){
/*reply*/
replyev.xclient.type = ClientMessage;
replyev.xclient.window = event->data.l[0];
replyev.xclient.format = 32;
replyev.xclient.message_type = _XA_XDE_REQUEST;
replyev.xclient.data.l[0] = event->window;
gdkev.dragrequest.u.allflags = 0;
gdkev.dragrequest.u.flags.protocol_version = 0;
gdkev.dragrequest.u.flags.willaccept = 1;
gdkev.dragrequest.u.flags.delete_data = 0;
replyev.xclient.data.l[1] = gdkev.dragrequest.u.allflags;
replyev.xclient.data.l[2] = replyev.xclient.data.l[3] = 0;
replyev.xclient.data.l[4] = event->data.l[2];
XSendEvent(dpy, replyev.xclient.window, 0, NoEventMask, &replyev);
XSync(dpy, 0);
}
done = True;
}
return done;
}
#endif

View File

@@ -1,8 +0,0 @@
#ifndef _XDE_H_
#define _XDE_H_
Bool wXDEProcessClientMessage(XClientMessageEvent *event);
#endif

276
src/xdnd.c Normal file
View File

@@ -0,0 +1,276 @@
/* Many part of code are ripped of an example from JX's site */
#include "wconfig.h"
#ifdef XDND
#include <X11/Xlib.h>
#include "WindowMaker.h"
#include "window.h"
#include "dock.h"
#include "xdnd.h"
#include "motif.h"
#include "workspace.h"
#include "stdlib.h"
#include <X11/Xatom.h>
#define XDND_VERSION 3L
Atom _XA_XdndAware;
Atom _XA_XdndEnter;
Atom _XA_XdndLeave;
Atom _XA_XdndDrop;
Atom _XA_XdndPosition;
Atom _XA_XdndStatus;
Atom _XA_XdndActionCopy;
Atom _XA_XdndSelection;
Atom _XA_XdndFinished;
Atom _XA_WINDOWMAKER_XDNDEXCHANGE;
/*
Atom _XA_MOTIF_DRAG_RECEIVER_INFO;
Atom _XA_MOTIF_DRAG_AND_DROP_MESSAGE;
*/
Atom atom_support;
void wXDNDInitializeAtoms()
{
_XA_XdndAware = XInternAtom(dpy, "XdndAware", False);
_XA_XdndEnter = XInternAtom(dpy, "XdndEnter", False);
_XA_XdndLeave = XInternAtom(dpy, "XdndLeave", False);
_XA_XdndDrop = XInternAtom(dpy, "XdndDrop", False);
_XA_XdndPosition = XInternAtom(dpy, "XdndPosition", False);
_XA_XdndStatus = XInternAtom(dpy, "XdndStatus", False);
_XA_XdndActionCopy = XInternAtom(dpy, "XdndActionCopy", False);
_XA_XdndSelection = XInternAtom(dpy, "XdndSelection", False);
_XA_XdndFinished = XInternAtom(dpy, "XdndFinished", False);
_XA_WINDOWMAKER_XDNDEXCHANGE = XInternAtom(dpy, "_WINDOWMAKER_XDNDEXCHANGE", False);
/*
_XA_MOTIF_DRAG_RECEIVER_INFO = XInternAtom(dpy, "_MOTIF_DRAG_RECEIVER_INFO",False);
_XA_MOTIF_DRAG_AND_DROP_MESSAGE = XInternAtom(dpy, "_MOTIF_DRAG_AND_DROP_MESSAGE", False);
*/
}
void wXDNDMakeAwareness(Window window) {
long int xdnd_version = 3;
/*
MotifDragReceiverInfo info;
*/
XChangeProperty (dpy, window, _XA_XdndAware, XA_ATOM,
32, PropModeAppend, (char *)&xdnd_version, 1);
/*** MOTIF ***
info.byte_order = '\0';
info.protocol_version = 0;
info.protocol_style = XmDRAG_DYNAMIC;
info.proxy_window = 0;
info.num_drop_sites = 0;
info.total_size = sizeof(info);
XChangeProperty (dpy, window,
_XA_MOTIF_DRAG_RECEIVER_INFO,
_XA_MOTIF_DRAG_RECEIVER_INFO,
8, PropModeReplace,
(unsigned char *)&info,
sizeof (info));
*/
}
void wXDNDClearAwareness(Window window) {
long int xdnd_version = 3;
XDeleteProperty (dpy, window, _XA_XdndAware);
}
Bool
wXDNDProcessSelection(XSelectionEvent *event)
{
WScreen *scr = wScreenForWindow(event->requestor);
char *dropdata;
Atom ret_type;
int ret_format;
unsigned long ret_item;
unsigned long remain_byte;
char * delme;
Window selowner = XGetSelectionOwner(dpy,_XA_XdndSelection);
XGetWindowProperty(dpy, event->requestor, _XA_WINDOWMAKER_XDNDEXCHANGE,
0, 65536, True, atom_support, &ret_type, &ret_format,
&ret_item, &remain_byte, (unsigned char **)&delme);
if (delme){
/*
printf("get -%s-\n",delme);
*/
scr->xdestring=delme;
}
{
/*finished*/
XEvent xevent;
memset (&xevent, 0, sizeof(xevent));
xevent.xany.type = ClientMessage;
xevent.xany.display = dpy;
xevent.xclient.window = selowner;
xevent.xclient.message_type = _XA_XdndFinished;
xevent.xclient.format = 32;
XDND_FINISHED_TARGET_WIN(&xevent) = event->requestor;
XSendEvent(dpy, selowner, 0, 0, &xevent);
}
}
Bool
isAwareXDND(Window window)
{
Atom actual;
int format;
unsigned long count, remaining;
unsigned char *data=0;
Atom *types, *t;
if (!window) return False;
XGetWindowProperty (dpy, window, _XA_XdndAware,
0, 0x8000000L, False, XA_ATOM,
&actual, &format,
&count, &remaining, &data);
if (actual != XA_ATOM || format != 32 || count == 0 || !data) {
if (data)
XFree (data);
return False;
}
if (data)
XFree (data);
return True;
}
Bool
acceptXDND(Window window)
{
WScreen *scr = wScreenForWindow(window);
WWindow *wwin = wWindowFor(window);
WDock *dock;
int icon_pos,i;
icon_pos = -1;
if ((dock = scr->dock)!=NULL) {
for (i=0; i<dock->max_icons; i++) {
if (dock->icon_array[i]
&& dock->icon_array[i]->icon->core->window==window) {
icon_pos = i;
break;
}
}
}
if (icon_pos<0 && (dock = scr->workspaces[scr->current_workspace]->clip)!=NULL) {
for (i=0; i<dock->max_icons; i++) {
if (dock->icon_array[i]
&& dock->icon_array[i]->icon->core->window==window) {
icon_pos = i;
break;
}
}
}
if (icon_pos<0) return False;
if (!dock) return False;
if (isAwareXDND(dock->icon_array[icon_pos]->icon->icon_win)) return False;
if (dock->icon_array[icon_pos]->dnd_command!=NULL) return True;
return False;
}
Bool
wXDNDProcessClientMessage(XClientMessageEvent *event)
{
/* test */
{
char * name = XGetAtomName(dpy, event->message_type);
/*
printf("Get %s\n",name);
*/
XFree(name);
}
/*
if (event->message_type == _XA_MOTIF_DRAG_AND_DROP_MESSAGE) {
printf("motif dnd msg %d\n",event->data.b[0]);
if (event->data.b[0] == XmDROP_START){
unsigned x_root, y_root, flags;
unsigned char reason;
unsigned long timestamp;
Atom atom;
Window source_window;
MotifDragInitiatorInfo *initiator_info;
Atom ret_type;
int ret_format;
unsigned long ret_item;
unsigned long remain_byte;
reason = event->data.b[0];
flags = event->data.s[1];
timestamp = event->data.l[1];
x_root = event->data.s[4];
y_root = event->data.s[5];
atom = event->data.l[3];
source_window = event->data.l[4];
XGetWindowProperty(dpy, source_window, atom,
0, sizeof(*initiator_info), True, atom_support,
&ret_type, &ret_format,
&ret_item, &remain_byte, (unsigned char **)&initiator_info);
}
}
else */
if (event->message_type == _XA_XdndEnter) {
if ((event->data.l[1] & 1) == 0){
atom_support = event->data.l[2];
}
/*
else puts("enter more than 3 types");
*/
return True;
} else if (event->message_type == _XA_XdndLeave) {
return True;
} else if (event->message_type == _XA_XdndDrop) {
if (event->data.l[0] == XGetSelectionOwner(dpy, _XA_XdndSelection)){
XConvertSelection(dpy, _XA_XdndSelection, atom_support,
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
}
/*
else puts("wierd selection owner");
*/
return True;
} else if (event->message_type == _XA_XdndPosition) {
XEvent xevent;
Window srcwin = event->data.l[0];
if (atom_support != XInternAtom(dpy, "text/uri-list", False)) {
return True;
}
{
memset (&xevent, 0, sizeof(xevent));
xevent.xany.type = ClientMessage;
xevent.xany.display = dpy;
xevent.xclient.window = srcwin;
xevent.xclient.message_type = _XA_XdndStatus;
xevent.xclient.format = 32;
XDND_STATUS_TARGET_WIN (&xevent) = event->window;
XDND_STATUS_WILL_ACCEPT_SET (&xevent, acceptXDND(event->window));
XDND_STATUS_WANT_POSITION_SET(&xevent, True);
XDND_STATUS_RECT_SET(&xevent, 0, 0, 1024,768);
XDND_STATUS_ACTION(&xevent) = _XA_XdndActionCopy;
XSendEvent(dpy, srcwin, 0, 0, &xevent);
}
return True;
}
return False;
}
#endif

53
src/xdnd.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef _XDND_H_
#define _XDND_H_
void wXDNDInitializeAtoms();
Bool wXDNDProcessSelection(XSelectionEvent *event);
Bool wXDNDProcessClientMessage(XClientMessageEvent *event);
void wXDNDMakeAwareness(Window window);
void wXDNDClearAwareness(Window window);
/* header was ripped from xdnd's example on its page */
#define XDND_THREE 3
#define XDND_ENTER_SOURCE_WIN(e) ((e)->xclient.data.l[0])
#define XDND_ENTER_THREE_TYPES(e) (((e)->xclient.data.l[1] & 0x1UL) == 0)
#define XDND_ENTER_THREE_TYPES_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL)
#define XDND_ENTER_VERSION(e) ((e)->xclient.data.l[1] >> 24)
#define XDND_ENTER_VERSION_SET(e,v) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~(0xFF << 24)) | ((v) << 24)
#define XDND_ENTER_TYPE(e,i) ((e)->xclient.data.l[2 + i]) /* i => (0, 1, 2) */
/* XdndPosition */
#define XDND_POSITION_SOURCE_WIN(e) ((e)->xclient.data.l[0])
#define XDND_POSITION_ROOT_X(e) ((e)->xclient.data.l[2] >> 16)
#define XDND_POSITION_ROOT_Y(e) ((e)->xclient.data.l[2] & 0xFFFFUL)
#define XDND_POSITION_ROOT_SET(e,x,y) (e)->xclient.data.l[2] = ((x) << 16) | ((y) & 0xFFFFUL)
#define XDND_POSITION_TIME(e) ((e)->xclient.data.l[3])
#define XDND_POSITION_ACTION(e) ((e)->xclient.data.l[4])
/* XdndStatus */
#define XDND_STATUS_TARGET_WIN(e) ((e)->xclient.data.l[0])
#define XDND_STATUS_WILL_ACCEPT(e) ((e)->xclient.data.l[1] & 0x1L)
#define XDND_STATUS_WILL_ACCEPT_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x1UL) | (((b) == 0) ? 0 : 0x1UL)
#define XDND_STATUS_WANT_POSITION(e) ((e)->xclient.data.l[1] & 0x2UL)
#define XDND_STATUS_WANT_POSITION_SET(e,b) (e)->xclient.data.l[1] = ((e)->xclient.data.l[1] & ~0x2UL) | (((b) == 0) ? 0 : 0x2UL)
#define XDND_STATUS_RECT_X(e) ((e)->xclient.data.l[2] >> 16)
#define XDND_STATUS_RECT_Y(e) ((e)->xclient.data.l[2] & 0xFFFFL)
#define XDND_STATUS_RECT_WIDTH(e) ((e)->xclient.data.l[3] >> 16)
#define XDND_STATUS_RECT_HEIGHT(e) ((e)->xclient.data.l[3] & 0xFFFFL)
#define XDND_STATUS_RECT_SET(e,x,y,w,h) {(e)->xclient.data.l[2] = ((x) << 16) | ((y) & 0xFFFFUL); (e)->xclient.data.l[3] = ((w) << 16) | ((h) & 0xFFFFUL); }
#define XDND_STATUS_ACTION(e) ((e)->xclient.data.l[4])
/* XdndLeave */
#define XDND_LEAVE_SOURCE_WIN(e) ((e)->xclient.data.l[0])
/* XdndDrop */
#define XDND_DROP_SOURCE_WIN(e) ((e)->xclient.data.l[0])
#define XDND_DROP_TIME(e) ((e)->xclient.data.l[2])
/* XdndFinished */
#define XDND_FINISHED_TARGET_WIN(e) ((e)->xclient.data.l[0])
#endif