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:
@@ -77,8 +77,8 @@ wmaker_SOURCES = \
|
||||
texture.h \
|
||||
usermenu.c \
|
||||
usermenu.h \
|
||||
xde.h \
|
||||
xde.c \
|
||||
xdnd.h \
|
||||
xdnd.c \
|
||||
xmodifier.h \
|
||||
xmodifier.c \
|
||||
xutil.c \
|
||||
|
||||
@@ -99,7 +99,7 @@ bin_PROGRAMS = wmaker
|
||||
|
||||
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)\"
|
||||
@@ -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 \
|
||||
moveres.o openlook.o pixmap.o placement.o properties.o proplist.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 \
|
||||
workspace.o wmsound.o text.o
|
||||
wmaker_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.a \
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#include "framewin.h"
|
||||
#include "dialog.h"
|
||||
#include "client.h"
|
||||
#ifdef XDND
|
||||
#include "xdnd.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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);
|
||||
if (path)
|
||||
free(path);
|
||||
#ifdef XDND
|
||||
wXDNDMakeAwareness(dicon->icon->core->window);
|
||||
#endif
|
||||
#ifdef REDUCE_APPICONS
|
||||
dicon->num_apps = 0;
|
||||
#endif
|
||||
@@ -219,6 +225,9 @@ wAppIconCreate(WWindow *leader_win)
|
||||
CWSaveUnder, &attribs);
|
||||
}
|
||||
#endif
|
||||
#ifdef XDND
|
||||
wXDNDMakeAwareness(aicon->icon->core->window);
|
||||
#endif
|
||||
|
||||
/* will be overriden if docked */
|
||||
aicon->icon->core->descriptor.handle_mousedown = appIconMouseDown;
|
||||
|
||||
34
src/event.c
34
src/event.c
@@ -34,8 +34,8 @@
|
||||
#ifdef SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
#ifdef XDE_DND
|
||||
#include "xde.h"
|
||||
#ifdef XDND
|
||||
#include "xdnd.h"
|
||||
#endif
|
||||
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
@@ -405,6 +405,7 @@ handleDeadProcess(void *foo)
|
||||
static void
|
||||
saveTimestamp(XEvent *event)
|
||||
{
|
||||
WScreen *scr = wScreenForWindow(event->xany.window);
|
||||
LastTimestamp = CurrentTime;
|
||||
|
||||
switch (event->type) {
|
||||
@@ -434,6 +435,29 @@ saveTimestamp(XEvent *event)
|
||||
break;
|
||||
case SelectionNotify:
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -911,10 +935,10 @@ handleClientMessage(XEvent *event)
|
||||
} else if (wKWMProcessClientMessage(&event->xclient)) {
|
||||
/* do nothing */
|
||||
#endif /* KWM_HINTS */
|
||||
#ifdef XDE_DND
|
||||
} else if (wXDEProcessClientMessage(&event->xclient)) {
|
||||
#ifdef XDND
|
||||
} else if (wXDNDProcessClientMessage(&event->xclient)) {
|
||||
/* do nothing */
|
||||
#endif /* XDE_DND */
|
||||
#endif /* XDND */
|
||||
#ifdef OFFIX_DND
|
||||
} else if (event->xclient.message_type==_XA_DND_PROTOCOL) {
|
||||
WScreen *scr = wScreenForWindow(event->xclient.window);
|
||||
|
||||
@@ -113,15 +113,6 @@ Atom _XA_WINDOWMAKER_COMMAND;
|
||||
Atom _XA_DND_PROTOCOL;
|
||||
Atom _XA_DND_SELECTION;
|
||||
#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 */
|
||||
Cursor wCursor[WCUR_LAST];
|
||||
|
||||
@@ -875,8 +875,11 @@ get_dnd_selection(WScreen *scr)
|
||||
char *flat_string;
|
||||
int count;
|
||||
|
||||
#ifdef XDE_DND
|
||||
#ifdef XDND
|
||||
if(scr->xdestring) {
|
||||
/*
|
||||
printf(" return %s\n",scr->xdestring);
|
||||
*/
|
||||
return (wstrdup(scr->xdestring));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
#include "WindowMaker.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef XDE_DND
|
||||
#include <gdk/gdk.h>
|
||||
#endif
|
||||
|
||||
#include <proplist.h>
|
||||
|
||||
|
||||
@@ -298,7 +294,7 @@ typedef struct _WScreen {
|
||||
struct WWindow *shortcutWindow[MAX_WINDOW_SHORTCUTS];
|
||||
struct LinkedList *shortcutSelectedWindows[MAX_WINDOW_SHORTCUTS];
|
||||
|
||||
#ifdef XDE_DND
|
||||
#ifdef XDND
|
||||
char *xdestring;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
#include "defaults.h"
|
||||
#include "properties.h"
|
||||
#include "dialog.h"
|
||||
#ifdef XDND
|
||||
#include "xdnd.h"
|
||||
#endif
|
||||
|
||||
#include "xutil.h"
|
||||
|
||||
@@ -125,14 +128,6 @@ extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
|
||||
extern Atom _XA_DND_PROTOCOL;
|
||||
extern Atom _XA_DND_SELECTION;
|
||||
#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 */
|
||||
@@ -697,13 +692,8 @@ StartUp(Bool defaultScreenOnly)
|
||||
_XA_DND_SELECTION = XInternAtom(dpy, "DndSelection", False);
|
||||
_XA_DND_PROTOCOL = XInternAtom(dpy, "DndProtocol", False);
|
||||
#endif
|
||||
#ifdef XDE_DND
|
||||
_XA_XDE_ENTER = XInternAtom(dpy, "_XDE_ENTER", False);
|
||||
_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);
|
||||
#ifdef XDND
|
||||
wXDNDInitializeAtoms();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -72,9 +72,9 @@
|
||||
#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
|
||||
|
||||
@@ -69,9 +69,6 @@ wCoreCreateTopLevel(WScreen *screen, int x, int y, int width, int height,
|
||||
attribs.border_pixel = screen->frame_border_pixel;
|
||||
attribs.event_mask = SubstructureRedirectMask | ButtonPressMask
|
||||
| ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask
|
||||
#ifdef XDE_DND
|
||||
| StructureNotifyMask
|
||||
#endif
|
||||
| LeaveWindowMask;
|
||||
|
||||
vmask |= CWColormap;
|
||||
|
||||
113
src/xde.c
113
src/xde.c
@@ -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
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
#ifndef _XDE_H_
|
||||
#define _XDE_H_
|
||||
|
||||
Bool wXDEProcessClientMessage(XClientMessageEvent *event);
|
||||
|
||||
|
||||
#endif
|
||||
276
src/xdnd.c
Normal file
276
src/xdnd.c
Normal 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
53
src/xdnd.h
Normal 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
|
||||
Reference in New Issue
Block a user