mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-21 05:18:06 +01:00
wmaker: Improve drag-nd-drop support
This patch is cleaning the previous DnD support, and adds the get type list protocol negociation. Currently only supporting uri-list type.
This commit is contained in:
committed by
Carlos R. Mafra
parent
be5b58aaee
commit
2abb323777
196
src/xdnd.c
196
src/xdnd.c
@@ -1,26 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Window Maker window manager
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2003 Alfredo K. Kojima
|
||||||
|
* Copyright (c) 2014 Window Maker Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation
|
||||||
|
*/
|
||||||
|
|
||||||
/* Many part of code are ripped of an example from JX's site */
|
/* Many part of code are ripped of an example from JX's site */
|
||||||
|
|
||||||
#include "wconfig.h"
|
#include "wconfig.h"
|
||||||
|
|
||||||
#ifdef XDND
|
#ifdef XDND
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include "WindowMaker.h"
|
#include "WindowMaker.h"
|
||||||
#include "window.h"
|
|
||||||
#include "dock.h"
|
#include "dock.h"
|
||||||
#include "xdnd.h"
|
#include "xdnd.h"
|
||||||
#include "motif.h"
|
|
||||||
|
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
#define XDND_VERSION 3L
|
|
||||||
|
|
||||||
static Atom _XA_XdndAware;
|
static Atom _XA_XdndAware;
|
||||||
static Atom _XA_XdndEnter;
|
static Atom _XA_XdndEnter;
|
||||||
static Atom _XA_XdndLeave;
|
static Atom _XA_XdndLeave;
|
||||||
@@ -30,18 +43,13 @@ static Atom _XA_XdndStatus;
|
|||||||
static Atom _XA_XdndActionCopy;
|
static Atom _XA_XdndActionCopy;
|
||||||
static Atom _XA_XdndSelection;
|
static Atom _XA_XdndSelection;
|
||||||
static Atom _XA_XdndFinished;
|
static Atom _XA_XdndFinished;
|
||||||
|
static Atom _XA_XdndTypeList;
|
||||||
static Atom _XA_WINDOWMAKER_XDNDEXCHANGE;
|
static Atom _XA_WINDOWMAKER_XDNDEXCHANGE;
|
||||||
|
static Atom supported_typelist;
|
||||||
|
static Atom selected_typelist;
|
||||||
|
|
||||||
/*
|
void wXDNDInitializeAtoms(void)
|
||||||
Atom _XA_MOTIF_DRAG_RECEIVER_INFO;
|
|
||||||
Atom _XA_MOTIF_DRAG_AND_DROP_MESSAGE;
|
|
||||||
*/
|
|
||||||
|
|
||||||
static Atom atom_support;
|
|
||||||
|
|
||||||
void wXDNDInitializeAtoms()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
_XA_XdndAware = XInternAtom(dpy, "XdndAware", False);
|
_XA_XdndAware = XInternAtom(dpy, "XdndAware", False);
|
||||||
_XA_XdndEnter = XInternAtom(dpy, "XdndEnter", False);
|
_XA_XdndEnter = XInternAtom(dpy, "XdndEnter", False);
|
||||||
_XA_XdndLeave = XInternAtom(dpy, "XdndLeave", False);
|
_XA_XdndLeave = XInternAtom(dpy, "XdndLeave", False);
|
||||||
@@ -51,41 +59,21 @@ void wXDNDInitializeAtoms()
|
|||||||
_XA_XdndActionCopy = XInternAtom(dpy, "XdndActionCopy", False);
|
_XA_XdndActionCopy = XInternAtom(dpy, "XdndActionCopy", False);
|
||||||
_XA_XdndSelection = XInternAtom(dpy, "XdndSelection", False);
|
_XA_XdndSelection = XInternAtom(dpy, "XdndSelection", False);
|
||||||
_XA_XdndFinished = XInternAtom(dpy, "XdndFinished", False);
|
_XA_XdndFinished = XInternAtom(dpy, "XdndFinished", False);
|
||||||
|
_XA_XdndTypeList = XInternAtom(dpy, "XdndTypeList", False);
|
||||||
_XA_WINDOWMAKER_XDNDEXCHANGE = XInternAtom(dpy, "_WINDOWMAKER_XDNDEXCHANGE", False);
|
_XA_WINDOWMAKER_XDNDEXCHANGE = XInternAtom(dpy, "_WINDOWMAKER_XDNDEXCHANGE", False);
|
||||||
|
|
||||||
/*
|
supported_typelist = XInternAtom(dpy, "text/uri-list", 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)
|
void wXDNDMakeAwareness(Window window)
|
||||||
{
|
{
|
||||||
long int xdnd_version = 3;
|
long int xdnd_version = XDND_VERSION;
|
||||||
/*
|
XChangeProperty(dpy, window, _XA_XdndAware, XA_ATOM, 32,
|
||||||
MotifDragReceiverInfo info;
|
PropModeAppend, (unsigned char *)&xdnd_version, 1);
|
||||||
*/
|
|
||||||
XChangeProperty(dpy, window, _XA_XdndAware, XA_ATOM, 32, PropModeAppend, (unsigned 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 wXDNDDecodeURI(char *uri) {
|
static void wXDNDDecodeURI(char *uri)
|
||||||
|
{
|
||||||
char *last = uri + strlen(uri);
|
char *last = uri + strlen(uri);
|
||||||
while (uri < last-2) {
|
while (uri < last-2) {
|
||||||
if (*uri == '%') {
|
if (*uri == '%') {
|
||||||
@@ -114,7 +102,7 @@ Bool wXDNDProcessSelection(XEvent * event)
|
|||||||
|
|
||||||
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, selected_typelist, &ret_type, &ret_format,
|
||||||
&ret_item, &remain_byte, (unsigned char **)&delme);
|
&ret_item, &remain_byte, (unsigned char **)&delme);
|
||||||
|
|
||||||
/*send finished */
|
/*send finished */
|
||||||
@@ -178,16 +166,15 @@ Bool wXDNDProcessSelection(XEvent * event)
|
|||||||
wfree(tmp);
|
wfree(tmp);
|
||||||
}
|
}
|
||||||
WMFreeArray(items);
|
WMFreeArray(items);
|
||||||
if (scr->xdestring[0]) {
|
if (scr->xdestring[0])
|
||||||
wDockReceiveDNDDrop(scr, event);
|
wDockReceiveDNDDrop(scr, event);
|
||||||
}
|
|
||||||
wfree(scr->xdestring); /* this xdestring is not from Xlib (no XFree) */
|
wfree(scr->xdestring); /* this xdestring is not from Xlib (no XFree) */
|
||||||
}
|
}
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool isAwareXDND(Window window)
|
static Bool isAwareXDND(Window window)
|
||||||
{
|
{
|
||||||
Atom actual;
|
Atom actual;
|
||||||
int format;
|
int format;
|
||||||
@@ -208,14 +195,15 @@ Bool isAwareXDND(Window window)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool acceptXDND(Window window)
|
static Bool acceptXDND(Window window)
|
||||||
{
|
{
|
||||||
WScreen *scr = wScreenForWindow(window);
|
WScreen *scr = wScreenForWindow(window);
|
||||||
WDock *dock;
|
WDock *dock;
|
||||||
int icon_pos, i;
|
int icon_pos, i;
|
||||||
|
|
||||||
icon_pos = -1;
|
icon_pos = -1;
|
||||||
if ((dock = scr->dock) != NULL) {
|
dock = scr->dock;
|
||||||
|
if (dock) {
|
||||||
for (i = 0; i < dock->max_icons; i++) {
|
for (i = 0; i < dock->max_icons; i++) {
|
||||||
if (dock->icon_array[i]
|
if (dock->icon_array[i]
|
||||||
&& dock->icon_array[i]->icon->core->window == window) {
|
&& dock->icon_array[i]->icon->core->window == window) {
|
||||||
@@ -224,7 +212,9 @@ Bool acceptXDND(Window window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (icon_pos < 0 && (dock = w_global.workspace.array[w_global.workspace.current]->clip) != NULL) {
|
if (icon_pos < 0) {
|
||||||
|
dock = w_global.workspace.array[w_global.workspace.current]->clip;
|
||||||
|
if (dock) {
|
||||||
for (i = 0; i < dock->max_icons; i++) {
|
for (i = 0; i < dock->max_icons; i++) {
|
||||||
if (dock->icon_array[i]
|
if (dock->icon_array[i]
|
||||||
&& dock->icon_array[i]->icon->core->window == window) {
|
&& dock->icon_array[i]->icon->core->window == window) {
|
||||||
@@ -233,6 +223,7 @@ Bool acceptXDND(Window window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (icon_pos < 0)
|
if (icon_pos < 0)
|
||||||
return False;
|
return False;
|
||||||
if (!dock)
|
if (!dock)
|
||||||
@@ -246,74 +237,66 @@ Bool acceptXDND(Window window)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wXDNDGetTypeList(Display *dpy, Window window)
|
||||||
|
{
|
||||||
|
Atom type, *a;
|
||||||
|
Atom *typelist;
|
||||||
|
int format, i;
|
||||||
|
unsigned long count, remaining;
|
||||||
|
unsigned char *data = NULL;
|
||||||
|
|
||||||
|
XGetWindowProperty(dpy, window, _XA_XdndTypeList,
|
||||||
|
0, 0x8000000L, False, XA_ATOM,
|
||||||
|
&type, &format, &count, &remaining, &data);
|
||||||
|
|
||||||
|
if (type != XA_ATOM || format != 32 || count == 0 || !data) {
|
||||||
|
if (data)
|
||||||
|
XFree(data);
|
||||||
|
wwarning(_("wXDNDGetTypeList failed = %ld"), _XA_XdndTypeList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
typelist = malloc((count + 1) * sizeof(Atom));
|
||||||
|
a = (Atom *) data;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
typelist[i] = a[i];
|
||||||
|
if (typelist[i] == supported_typelist) {
|
||||||
|
selected_typelist = typelist[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typelist[count] = 0;
|
||||||
|
XFree(data);
|
||||||
|
free(typelist);
|
||||||
|
}
|
||||||
|
|
||||||
Bool wXDNDProcessClientMessage(XClientMessageEvent *event)
|
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->message_type == _XA_XdndEnter) {
|
||||||
if ((event->data.l[1] & 1) == 0) {
|
|
||||||
atom_support = event->data.l[2];
|
if (XDND_ENTER_THREE_TYPES(event)) {
|
||||||
}
|
selected_typelist = XDND_ENTER_TYPE(event, 0);
|
||||||
|
} else {
|
||||||
|
wXDNDGetTypeList(dpy, XDND_ENTER_SOURCE_WIN(event));
|
||||||
/*
|
/*
|
||||||
else puts("enter more than 3 types");
|
char *name = XGetAtomName(dpy, selected_typelist);
|
||||||
|
fprintf(stderr, "Get %s\n",name);
|
||||||
|
XFree(name);
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
return True;
|
return True;
|
||||||
} else if (event->message_type == _XA_XdndLeave) {
|
} else if (event->message_type == _XA_XdndLeave) {
|
||||||
return True;
|
return True;
|
||||||
} else if (event->message_type == _XA_XdndDrop) {
|
} else if (event->message_type == _XA_XdndDrop) {
|
||||||
if (event->data.l[0] == XGetSelectionOwner(dpy, _XA_XdndSelection)) {
|
if (XDND_DROP_SOURCE_WIN(event) == XGetSelectionOwner(dpy, _XA_XdndSelection)) {
|
||||||
XConvertSelection(dpy, _XA_XdndSelection, atom_support,
|
XConvertSelection(dpy, _XA_XdndSelection, selected_typelist,
|
||||||
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
|
|
||||||
} else {
|
|
||||||
//printf("weird selection owner? QT?\n");
|
|
||||||
XConvertSelection(dpy, _XA_XdndSelection, atom_support,
|
|
||||||
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
|
_XA_WINDOWMAKER_XDNDEXCHANGE, event->window, CurrentTime);
|
||||||
}
|
}
|
||||||
return True;
|
return True;
|
||||||
} else if (event->message_type == _XA_XdndPosition) {
|
} else if (event->message_type == _XA_XdndPosition) {
|
||||||
XEvent xevent;
|
XEvent xevent;
|
||||||
Window srcwin = event->data.l[0];
|
Window srcwin = XDND_POSITION_SOURCE_WIN(event);
|
||||||
if (atom_support != XInternAtom(dpy, "text/uri-list", False)) {
|
if (selected_typelist == supported_typelist) {
|
||||||
return True;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
memset(&xevent, 0, sizeof(xevent));
|
memset(&xevent, 0, sizeof(xevent));
|
||||||
xevent.xany.type = ClientMessage;
|
xevent.xany.type = ClientMessage;
|
||||||
xevent.xany.display = dpy;
|
xevent.xany.display = dpy;
|
||||||
@@ -324,7 +307,7 @@ Bool wXDNDProcessClientMessage(XClientMessageEvent * event)
|
|||||||
XDND_STATUS_TARGET_WIN(&xevent) = event->window;
|
XDND_STATUS_TARGET_WIN(&xevent) = event->window;
|
||||||
XDND_STATUS_WILL_ACCEPT_SET(&xevent, acceptXDND(event->window));
|
XDND_STATUS_WILL_ACCEPT_SET(&xevent, acceptXDND(event->window));
|
||||||
XDND_STATUS_WANT_POSITION_SET(&xevent, True);
|
XDND_STATUS_WANT_POSITION_SET(&xevent, True);
|
||||||
XDND_STATUS_RECT_SET(&xevent, 0, 0, 1024, 768);
|
XDND_STATUS_RECT_SET(&xevent, 0, 0, 0, 0);
|
||||||
XDND_STATUS_ACTION(&xevent) = _XA_XdndActionCopy;
|
XDND_STATUS_ACTION(&xevent) = _XA_XdndActionCopy;
|
||||||
|
|
||||||
XSendEvent(dpy, srcwin, 0, 0, &xevent);
|
XSendEvent(dpy, srcwin, 0, 0, &xevent);
|
||||||
@@ -333,5 +316,4 @@ Bool wXDNDProcessClientMessage(XClientMessageEvent * event)
|
|||||||
}
|
}
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
53
src/xdnd.h
53
src/xdnd.h
@@ -1,48 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Window Maker window manager
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997-2003 Alfredo K. Kojima
|
||||||
|
* Copyright (c) 2014 Window Maker Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _XDND_H_
|
#ifndef _XDND_H_
|
||||||
#define _XDND_H_
|
#define _XDND_H_
|
||||||
|
|
||||||
void wXDNDInitializeAtoms();
|
void wXDNDInitializeAtoms(void);
|
||||||
Bool wXDNDProcessSelection(XEvent *event);
|
Bool wXDNDProcessSelection(XEvent *event);
|
||||||
Bool wXDNDProcessClientMessage(XClientMessageEvent *event);
|
Bool wXDNDProcessClientMessage(XClientMessageEvent *event);
|
||||||
void wXDNDMakeAwareness(Window window);
|
void wXDNDMakeAwareness(Window window);
|
||||||
|
|
||||||
/* header was ripped from xdnd's example on its page */
|
#define XDND_VERSION 3L
|
||||||
|
|
||||||
#define XDND_THREE 3
|
#define XDND_ENTER_SOURCE_WIN(e) ((e)->data.l[0])
|
||||||
#define XDND_ENTER_SOURCE_WIN(e) ((e)->xclient.data.l[0])
|
#define XDND_ENTER_THREE_TYPES(e) (((e)->data.l[1] & 0x1UL) == 0)
|
||||||
#define XDND_ENTER_THREE_TYPES(e) (((e)->xclient.data.l[1] & 0x1UL) == 0)
|
#define XDND_ENTER_TYPE(e, i) ((e)->data.l[2 + i]) /* i => (0, 1, 2) */
|
||||||
#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 */
|
/* XdndPosition */
|
||||||
#define XDND_POSITION_SOURCE_WIN(e) ((e)->xclient.data.l[0])
|
#define XDND_POSITION_SOURCE_WIN(e) ((e)->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 */
|
/* XdndStatus */
|
||||||
#define XDND_STATUS_TARGET_WIN(e) ((e)->xclient.data.l[0])
|
#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_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_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_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])
|
#define XDND_STATUS_ACTION(e) ((e)->xclient.data.l[4])
|
||||||
|
|
||||||
/* XdndLeave */
|
|
||||||
#define XDND_LEAVE_SOURCE_WIN(e) ((e)->xclient.data.l[0])
|
|
||||||
|
|
||||||
/* XdndDrop */
|
/* XdndDrop */
|
||||||
#define XDND_DROP_SOURCE_WIN(e) ((e)->xclient.data.l[0])
|
#define XDND_DROP_SOURCE_WIN(e) ((e)->data.l[0])
|
||||||
#define XDND_DROP_TIME(e) ((e)->xclient.data.l[2])
|
|
||||||
|
|
||||||
/* XdndFinished */
|
/* XdndFinished */
|
||||||
#define XDND_FINISHED_TARGET_WIN(e) ((e)->xclient.data.l[0])
|
#define XDND_FINISHED_TARGET_WIN(e) ((e)->xclient.data.l[0])
|
||||||
|
|||||||
Reference in New Issue
Block a user