Xdnd drag code...

SVN revision: 9155
This commit is contained in:
xcomputerman 2004-02-29 08:15:47 +00:00 committed by xcomputerman
parent 51ffb9d7ec
commit 2d071118c6
3 changed files with 117 additions and 0 deletions

View File

@ -56,6 +56,7 @@ int
ecore_x_dnd_begin (Ecore_X_Window source, unsigned char *data, int size)
{
unsigned char *buf;
Atom _type_text_plain; /* FIXME: API-ize this stuff */
if (!ecore_x_dnd_version_get(source))
return 0;
@ -80,6 +81,11 @@ ecore_x_dnd_begin (Ecore_X_Window source, unsigned char *data, int size)
_xdnd->state = ECORE_X_DND_DRAGGING;
_xdnd->time = _ecore_x_event_last_time;
/* TODO: Set supported data types in API */
_type_text_plain = ecore_x_atom_get("text/plain");
_xdnd->num_types = 1;
_xdnd->types = (Atom *) calloc(1, sizeof(Atom));
_xdnd->types[0] = _type_text_plain;
return 1;
}
@ -134,3 +140,101 @@ ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectang
XSendEvent(_ecore_x_disp, _xdnd->source, False, 0, &xev);
}
void
_ecore_x_dnd_drag(int x, int y)
{
XEvent xev;
Ecore_X_Window win;
/* Preinitialize XEvent struct */
memset(&xev, 0, sizeof(XEvent));
xev.xany.type = ClientMessage;
xev.xany.display = _ecore_x_disp;
xev.xclient.format = 32;
/* Attempt to find a DND-capable window under the cursor */
win = ecore_x_window_at_xy_get(x, y);
while ((win) && !(ecore_x_dnd_version_get(win)))
win = ecore_x_window_parent_get(win);
/* Send XdndLeave to current destination window if we have left it */
if ((win != _xdnd->dest) && (_xdnd->dest))
{
xev.xclient.window = _xdnd->dest;
xev.xclient.message_type = _ecore_x_atom_xdnd_leave;
xev.xclient.data.l[0] = _xdnd->source;
XSendEvent(_ecore_x_disp, _xdnd->dest, False, 0, &xev);
}
if (win)
{
_xdnd->version = ECORE_MIN(ECORE_X_DND_VERSION,
ecore_x_dnd_version_get(win));
if (win != _xdnd->dest)
{
int i;
/* Entered new window, send XdndEnter */
xev.xclient.window = win;
xev.xclient.message_type = _ecore_x_atom_xdnd_enter;
xev.xclient.data.l[0] = _xdnd->source;
if(_xdnd->num_types > 3)
xev.xclient.data.l[1] |= 0x1UL;
else
xev.xclient.data.l[1] &= 0xfffffffeUL;
xev.xclient.data.l[1] |= ((unsigned long) _xdnd->version) << 24;
for (i = 0; i < ECORE_MIN(_xdnd->num_types, 3); ++i)
xev.xclient.data.l[i + 2] = _xdnd->types[i];
XSendEvent(_ecore_x_disp, win, False, 0, &xev);
_xdnd->await_status = 0;
}
/* FIXME: Handle box information */
if (!_xdnd->await_status)
{
xev.xclient.window = win;
xev.xclient.message_type = _ecore_x_atom_xdnd_position;
xev.xclient.data.l[0] = _xdnd->source;
xev.xclient.data.l[1] = 0; /* Reserved */
xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y * 0xffff);
xev.xclient.data.l[3] = CurrentTime; /* Version 1 */
xev.xclient.data.l[4] = _xdnd->action; /* Version 2, Needs to be pre-set */
XSendEvent(_ecore_x_disp, win, False, 0, &xev);
_xdnd->await_status = 1;
}
}
if (_xdnd->state == ECORE_X_DND_DROPPED)
{
if (win)
{
if (_xdnd->will_accept)
{
xev.xclient.window = win;
xev.xclient.message_type = _ecore_x_atom_xdnd_drop;
xev.xclient.data.l[0] = _xdnd->source;
xev.xclient.data.l[1] = 0;
xev.xclient.data.l[2] = CurrentTime;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
XSendEvent(_ecore_x_disp, win, False, 0, &xev);
}
else
{
xev.xclient.window = win;
xev.xclient.message_type = _ecore_x_atom_xdnd_leave;
xev.xclient.data.l[0] = _xdnd->source;
memset(xev.xclient.data.l + 1, 0, sizeof(long) * 3); /* Evil */
XSendEvent(_ecore_x_disp, win, False, 0, &xev);
}
}
_xdnd->will_accept = 0;
}
_xdnd->dest = win;
}

View File

@ -63,6 +63,7 @@ typedef struct _Ecore_X_DND_Protocol
enum {
ECORE_X_DND_IDLE,
ECORE_X_DND_DRAGGING,
ECORE_X_DND_DROPPED,
ECORE_X_DND_ENTERED,
ECORE_X_DND_TARGET_ENTERED,
ECORE_X_DND_TARGET_CONVERTING,
@ -86,6 +87,8 @@ typedef struct _Ecore_X_DND_Protocol
int will_accept;
int suppress;
int await_status;
struct {
Ecore_Event_Handler *mouse_move;

View File

@ -498,6 +498,11 @@ _ecore_x_window_at_xy_get(Window base, int bx, int by, int x, int y)
return base;
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
Ecore_X_Window
ecore_x_window_at_xy_get(int x, int y)
{
@ -514,6 +519,11 @@ ecore_x_window_at_xy_get(int x, int y)
return win ? win : root;
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
Ecore_X_Window
ecore_x_window_parent_get(Ecore_X_Window win)
{