forked from enlightenment/enlightenment
implement wl->x11 dnd operations
seems to work fine, large selection data (ref T2330) still untested
This commit is contained in:
parent
c696fa7088
commit
8e211f1950
|
@ -281,8 +281,21 @@ _e_comp_wl_data_device_drag_finished(E_Drag *drag, int dropped)
|
||||||
evas_object_hide(o);
|
evas_object_hide(o);
|
||||||
evas_object_pass_events_set(o, 1);
|
evas_object_pass_events_set(o, 1);
|
||||||
if (e_comp->wl_comp_data->drag != drag) return;
|
if (e_comp->wl_comp_data->drag != drag) return;
|
||||||
|
e_comp->wl_comp_data->drag = NULL;
|
||||||
|
e_comp->wl_comp_data->drag_client = NULL;
|
||||||
|
e_screensaver_inhibit_toggle(0);
|
||||||
if (e_comp->wl_comp_data->selection.target && (!dropped))
|
if (e_comp->wl_comp_data->selection.target && (!dropped))
|
||||||
{
|
{
|
||||||
|
#ifndef HAVE_WAYLAND_ONLY
|
||||||
|
if (e_client_has_xwindow(e_comp->wl_comp_data->selection.target))
|
||||||
|
{
|
||||||
|
ecore_x_client_message32_send(e_client_util_win_get(e_comp->wl_comp_data->selection.target),
|
||||||
|
ECORE_X_ATOM_XDND_DROP, ECORE_X_EVENT_MASK_NONE,
|
||||||
|
e_comp->cm_selection, 0, ecore_x_current_time_get(), 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
struct wl_resource *res;
|
struct wl_resource *res;
|
||||||
|
|
||||||
res = e_comp_wl_data_find_for_client(wl_resource_get_client(e_comp->wl_comp_data->selection.target->comp_data->surface));
|
res = e_comp_wl_data_find_for_client(wl_resource_get_client(e_comp->wl_comp_data->selection.target->comp_data->surface));
|
||||||
|
@ -291,12 +304,17 @@ _e_comp_wl_data_device_drag_finished(E_Drag *drag, int dropped)
|
||||||
wl_data_device_send_drop(res);
|
wl_data_device_send_drop(res);
|
||||||
wl_data_device_send_leave(res);
|
wl_data_device_send_leave(res);
|
||||||
}
|
}
|
||||||
|
#ifndef HAVE_WAYLAND_ONLY
|
||||||
|
if ((e_comp->comp_type != E_PIXMAP_TYPE_X) && e_comp_util_has_x())
|
||||||
|
{
|
||||||
|
ecore_x_selection_owner_set(0, ECORE_X_ATOM_SELECTION_XDND, 0);
|
||||||
|
ecore_x_window_hide(e_comp->cm_selection);
|
||||||
}
|
}
|
||||||
e_comp->wl_comp_data->drag = NULL;
|
#endif
|
||||||
e_comp->wl_comp_data->drag_client = NULL;
|
|
||||||
e_comp->wl_comp_data->selection.target = NULL;
|
e_comp->wl_comp_data->selection.target = NULL;
|
||||||
e_comp->wl_comp_data->drag_source = NULL;
|
e_comp->wl_comp_data->drag_source = NULL;
|
||||||
e_screensaver_inhibit_toggle(0);
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -346,6 +364,13 @@ _e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct wl_resourc
|
||||||
if (ec)
|
if (ec)
|
||||||
e_drag_object_set(e_comp->wl_comp_data->drag, ec->frame);
|
e_drag_object_set(e_comp->wl_comp_data->drag, ec->frame);
|
||||||
e_drag_start(e_comp->wl_comp_data->drag, x, y);
|
e_drag_start(e_comp->wl_comp_data->drag, x, y);
|
||||||
|
#ifndef HAVE_WAYLAND_ONLY
|
||||||
|
if ((e_comp->comp_type != E_PIXMAP_TYPE_X) && e_comp_util_has_x())
|
||||||
|
{
|
||||||
|
ecore_x_window_show(e_comp->cm_selection);
|
||||||
|
ecore_x_selection_owner_set(e_comp->cm_selection, ECORE_X_ATOM_SELECTION_XDND, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (e_comp->wl_comp_data->ptr.ec)
|
if (e_comp->wl_comp_data->ptr.ec)
|
||||||
e_comp_wl_data_device_send_enter(e_comp->wl_comp_data->ptr.ec);
|
e_comp_wl_data_device_send_enter(e_comp->wl_comp_data->ptr.ec);
|
||||||
e_screensaver_inhibit_toggle(1);
|
e_screensaver_inhibit_toggle(1);
|
||||||
|
@ -675,38 +700,60 @@ e_comp_wl_data_device_send_enter(E_Client *ec)
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
if (e_client_has_xwindow(ec)) return;
|
if (e_client_has_xwindow(ec) && e_client_has_xwindow(e_comp->wl_comp_data->drag_client)) return;
|
||||||
|
if (!e_client_has_xwindow(ec))
|
||||||
|
{
|
||||||
data_device_res =
|
data_device_res =
|
||||||
e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
|
e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
|
||||||
if (!data_device_res) return;
|
if (!data_device_res) return;
|
||||||
|
|
||||||
offer_res = e_comp_wl_data_device_send_offer(ec);
|
offer_res = e_comp_wl_data_device_send_offer(ec);
|
||||||
if (e_comp->wl_comp_data->selection.data_source && (!offer_res)) return;
|
if (e_comp->wl_comp_data->drag_source && (!offer_res)) return;
|
||||||
|
}
|
||||||
e_comp->wl_comp_data->selection.target = ec;
|
e_comp->wl_comp_data->selection.target = ec;
|
||||||
evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
|
evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
|
||||||
|
|
||||||
#ifndef HAVE_WAYLAND_ONLY
|
#ifndef HAVE_WAYLAND_ONLY
|
||||||
if (e_client_has_xwindow(e_comp->wl_comp_data->drag_client))
|
if (e_client_has_xwindow(ec))
|
||||||
{
|
{
|
||||||
int d1 = 0x5UL, d2, d3, d4;
|
int d1 = 0x5UL, d2, d3, d4;
|
||||||
|
E_Comp_Wl_Data_Source *source;
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
d2 = d3 = d4 = 0;
|
d2 = d3 = d4 = 0;
|
||||||
|
source = e_comp->wl_comp_data->drag_source;
|
||||||
|
|
||||||
|
if (eina_list_count(source->mime_types) > 3)
|
||||||
|
{
|
||||||
|
const char *type, *types[eina_list_count(source->mime_types)];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
if (e_comp->wl_comp_data->drag->num_types > 3)
|
|
||||||
d1 |= 0x1UL;
|
d1 |= 0x1UL;
|
||||||
|
EINA_LIST_FOREACH(source->mime_types, l, type)
|
||||||
|
types[i++] = type;
|
||||||
|
ecore_x_dnd_types_set(e_comp->cm_selection, types, i);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (e_comp->wl_comp_data->drag->num_types > 0)
|
l = source->mime_types;
|
||||||
|
|
||||||
|
if (source->mime_types)
|
||||||
d2 = ecore_x_atom_get(e_comp->wl_comp_data->drag->types[0]);
|
d2 = ecore_x_atom_get(e_comp->wl_comp_data->drag->types[0]);
|
||||||
if (e_comp->wl_comp_data->drag->num_types > 1)
|
if (eina_list_count(source->mime_types) > 1)
|
||||||
d3 = ecore_x_atom_get(e_comp->wl_comp_data->drag->types[1]);
|
{
|
||||||
if (e_comp->wl_comp_data->drag->num_types > 2)
|
l = eina_list_next(l);
|
||||||
d4 = ecore_x_atom_get(e_comp->wl_comp_data->drag->types[2]);
|
d3 = ecore_x_atom_get(eina_list_data_get(l));
|
||||||
|
}
|
||||||
|
if (eina_list_count(source->mime_types) > 2)
|
||||||
|
{
|
||||||
|
l = eina_list_next(l);
|
||||||
|
d4 = ecore_x_atom_get(eina_list_data_get(l));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ecore_x_client_message32_send(e_client_util_win_get(e_comp->wl_comp_data->drag_client),
|
ecore_x_client_message32_send(e_client_util_win_get(ec),
|
||||||
ECORE_X_ATOM_XDND_ENTER, ECORE_X_EVENT_MASK_NONE,
|
ECORE_X_ATOM_XDND_ENTER, ECORE_X_EVENT_MASK_NONE,
|
||||||
e_comp->cm_selection, d1, d2, d3, d4);
|
e_comp->cm_selection, d1, d2, d3, d4);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
x = wl_fixed_to_int(e_comp->wl_comp_data->ptr.x) - e_comp->wl_comp_data->selection.target->client.x;
|
x = wl_fixed_to_int(e_comp->wl_comp_data->ptr.x) - e_comp->wl_comp_data->selection.target->client.x;
|
||||||
|
@ -721,16 +768,17 @@ e_comp_wl_data_device_send_leave(E_Client *ec)
|
||||||
{
|
{
|
||||||
struct wl_resource *res;
|
struct wl_resource *res;
|
||||||
|
|
||||||
if (e_client_has_xwindow(ec)) return;
|
if (e_client_has_xwindow(ec) && e_client_has_xwindow(e_comp->wl_comp_data->drag_client)) return;
|
||||||
evas_object_event_callback_del_full(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
|
evas_object_event_callback_del_full(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
|
||||||
if (e_comp->wl_comp_data->selection.target == ec)
|
if (e_comp->wl_comp_data->selection.target == ec)
|
||||||
e_comp->wl_comp_data->selection.target = NULL;
|
e_comp->wl_comp_data->selection.target = NULL;
|
||||||
#ifndef HAVE_WAYLAND_ONLY
|
#ifndef HAVE_WAYLAND_ONLY
|
||||||
if (e_client_has_xwindow(e_comp->wl_comp_data->drag_client))
|
if (e_client_has_xwindow(ec))
|
||||||
{
|
{
|
||||||
ecore_x_client_message32_send(e_client_util_win_get(e_comp->wl_comp_data->drag_client),
|
ecore_x_client_message32_send(e_client_util_win_get(ec),
|
||||||
ECORE_X_ATOM_XDND_LEAVE, ECORE_X_EVENT_MASK_NONE,
|
ECORE_X_ATOM_XDND_LEAVE, ECORE_X_EVENT_MASK_NONE,
|
||||||
e_comp->cm_selection, 0, 0, 0, 0);
|
e_comp->cm_selection, 0, 0, 0, 0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
res = e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
|
res = e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
|
||||||
|
|
|
@ -1218,8 +1218,9 @@ _e_dnd_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
{
|
{
|
||||||
if (e_comp->wl_comp_data->drag != _drag_current) return ECORE_CALLBACK_RENEW;
|
if (e_comp->wl_comp_data->drag != _drag_current) return ECORE_CALLBACK_RENEW;
|
||||||
if (!e_comp->wl_comp_data->ptr.ec) return ECORE_CALLBACK_RENEW;
|
if (!e_comp->wl_comp_data->ptr.ec) return ECORE_CALLBACK_RENEW;
|
||||||
if (e_client_has_xwindow(e_comp->wl_comp_data->ptr.ec)) return ECORE_CALLBACK_RENEW;
|
if (!e_client_has_xwindow(e_comp->wl_comp_data->ptr.ec)) return ECORE_CALLBACK_RENEW;
|
||||||
ecore_x_client_message32_send(e_client_util_win_get(e_comp->wl_comp_data->drag_client),
|
if (e_client_has_xwindow(e_comp->wl_comp_data->drag_client)) return ECORE_CALLBACK_RENEW;
|
||||||
|
ecore_x_client_message32_send(e_client_util_win_get(e_comp->wl_comp_data->ptr.ec),
|
||||||
ECORE_X_ATOM_XDND_POSITION, ECORE_X_EVENT_MASK_NONE,
|
ECORE_X_ATOM_XDND_POSITION, ECORE_X_EVENT_MASK_NONE,
|
||||||
e_comp->cm_selection, 0, ((ev->x << 16) & 0xffff0000) | (ev->y & 0xffff),
|
e_comp->cm_selection, 0, ((ev->x << 16) & 0xffff0000) | (ev->y & 0xffff),
|
||||||
ev->timestamp, ECORE_X_ATOM_XDND_ACTION_COPY);
|
ev->timestamp, ECORE_X_ATOM_XDND_ACTION_COPY);
|
||||||
|
|
|
@ -3,14 +3,39 @@
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#define WL_TEXT_STR "text/plain;charset=utf-8"
|
#define WL_TEXT_STR "text/plain;charset=utf-8"
|
||||||
|
#define INCR_CHUNK_SIZE 1 << 17
|
||||||
|
|
||||||
static void (*xconvertselection)(Ecore_X_Display *, Ecore_X_Atom, Ecore_X_Atom, Ecore_X_Atom, Ecore_X_Window, Ecore_X_Time);
|
static void (*xconvertselection)(Ecore_X_Display *, Ecore_X_Atom, Ecore_X_Atom, Ecore_X_Atom, Ecore_X_Window, Ecore_X_Time);
|
||||||
static Ecore_X_Atom string_atom;
|
static Ecore_X_Atom string_atom;
|
||||||
static Ecore_X_Atom xwl_dnd_atom;
|
static Ecore_X_Atom xwl_dnd_atom;
|
||||||
|
static Ecore_X_Atom timestamp_atom;
|
||||||
|
static Ecore_X_Atom incr_atom;
|
||||||
|
static Ecore_X_Atom int_atom;
|
||||||
|
|
||||||
static int32_t cur_fd = -1;
|
static int32_t cur_fd = -1;
|
||||||
|
|
||||||
static Eina_List *handlers;
|
static Eina_List *handlers;
|
||||||
|
static Eina_Hash *pipes;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Ecore_Fd_Handler *fdh;
|
||||||
|
E_Comp_Wl_Data_Source *source;
|
||||||
|
Ecore_X_Window win;
|
||||||
|
Ecore_X_Atom atom;
|
||||||
|
Ecore_X_Atom selection;
|
||||||
|
Ecore_X_Atom property;
|
||||||
|
Eina_Binbuf *buf;
|
||||||
|
Eina_Bool incr : 1;
|
||||||
|
} Pipe;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_pipe_free(Pipe *p)
|
||||||
|
{
|
||||||
|
ecore_main_fd_handler_del(p->fdh);
|
||||||
|
eina_binbuf_free(p->buf);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_xdnd_finish(Eina_Bool success)
|
_xdnd_finish(Eina_Bool success)
|
||||||
|
@ -19,6 +44,24 @@ _xdnd_finish(Eina_Bool success)
|
||||||
e_comp->cm_selection, !!success, (!!success) * ECORE_X_ATOM_XDND_ACTION_COPY, 0, 0);
|
e_comp->cm_selection, !!success, (!!success) * ECORE_X_ATOM_XDND_ACTION_COPY, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_incr_update(Pipe *p, Eina_Bool success)
|
||||||
|
{
|
||||||
|
ecore_x_selection_notify_send(p->win, p->selection, p->atom, (!!success) * p->property, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_incr_upload(Pipe *p)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
size = eina_binbuf_length_get(p->buf);
|
||||||
|
size = MIN(size, INCR_CHUNK_SIZE);
|
||||||
|
ecore_x_window_prop_property_set(p->win, p->property, p->atom, 8, (void*)eina_binbuf_string_get(p->buf), size);
|
||||||
|
eina_binbuf_free(p->buf);
|
||||||
|
p->buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_xwayland_dnd_finish(void)
|
_xwayland_dnd_finish(void)
|
||||||
{
|
{
|
||||||
|
@ -46,8 +89,6 @@ _xwayland_drop(E_Drag *drag, int dropped)
|
||||||
{
|
{
|
||||||
wl_data_device_send_drop(res);
|
wl_data_device_send_drop(res);
|
||||||
wl_data_device_send_leave(res);
|
wl_data_device_send_leave(res);
|
||||||
ecore_x_client_message32_send(e_client_util_win_get(e_comp->wl_comp_data->drag_client), ECORE_X_ATOM_XDND_DROP, ECORE_X_EVENT_MASK_NONE,
|
|
||||||
e_comp->cm_selection, 0, ecore_x_current_time_get(), 0, 0);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +131,7 @@ _xwayland_cancelled_send(E_Comp_Wl_Data_Source *source)
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_xwl_fixes_selection_notify(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Fixes_Selection_Notify *ev)
|
_xwl_fixes_selection_notify(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Fixes_Selection_Notify *ev)
|
||||||
{
|
{
|
||||||
|
if (ev->owner == e_comp->cm_selection) return ECORE_CALLBACK_RENEW;
|
||||||
if (ev->atom == ECORE_X_ATOM_SELECTION_XDND)
|
if (ev->atom == ECORE_X_ATOM_SELECTION_XDND)
|
||||||
{
|
{
|
||||||
if (ev->owner)
|
if (ev->owner)
|
||||||
|
@ -189,6 +231,125 @@ _xwl_selection_notify(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Sele
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_xwl_pipe_read(void *data, Ecore_Fd_Handler *fdh)
|
||||||
|
{
|
||||||
|
Pipe *p = data;
|
||||||
|
ssize_t len;
|
||||||
|
unsigned char *buf;
|
||||||
|
|
||||||
|
buf = malloc(INCR_CHUNK_SIZE);
|
||||||
|
len = read(ecore_main_fd_handler_fd_get(fdh), (void*)buf, INCR_CHUNK_SIZE);
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
_incr_update(p, 0);
|
||||||
|
eina_hash_del_by_key(pipes, &p->win);
|
||||||
|
}
|
||||||
|
if (len == INCR_CHUNK_SIZE)
|
||||||
|
{
|
||||||
|
p->buf = eina_binbuf_manage_new(buf, len, 0);
|
||||||
|
if (p->incr)
|
||||||
|
_incr_upload(p);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned long size = INCR_CHUNK_SIZE;
|
||||||
|
|
||||||
|
p->incr = 1;
|
||||||
|
ecore_x_window_prop_property_set(p->win, p->atom, incr_atom, 32, &size, 1);
|
||||||
|
_incr_update(p, 1);
|
||||||
|
}
|
||||||
|
ecore_main_fd_handler_active_set(p->fdh, 0);
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
if (len)
|
||||||
|
p->buf = eina_binbuf_manage_new(buf, len, 0);
|
||||||
|
_incr_upload(p);
|
||||||
|
if (p->incr)
|
||||||
|
ecore_main_fd_handler_active_set(p->fdh, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_incr_update(p, 1);
|
||||||
|
eina_hash_del_by_key(pipes, &p->win);
|
||||||
|
}
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_xwl_selection_request(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Selection_Request *ev)
|
||||||
|
{
|
||||||
|
E_Comp_Wl_Data_Source *source;
|
||||||
|
const char *type;
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
if (!e_comp->wl_comp_data->drag_source) return ECORE_CALLBACK_RENEW;
|
||||||
|
|
||||||
|
source = e_comp->wl_comp_data->drag_source;
|
||||||
|
if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS)
|
||||||
|
{
|
||||||
|
Ecore_X_Atom *atoms;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
atoms = alloca((2 + eina_list_count(source->mime_types)) * sizeof(void*));
|
||||||
|
EINA_LIST_FOREACH(source->mime_types, l, type)
|
||||||
|
atoms[i++] = ecore_x_atom_get(type);
|
||||||
|
atoms[i++] = timestamp_atom;
|
||||||
|
atoms[i++] = ECORE_X_ATOM_SELECTION_TARGETS;
|
||||||
|
ecore_x_window_prop_property_set(ev->requestor, ev->property, ECORE_X_ATOM_ATOM, 32, atoms, i);
|
||||||
|
ecore_x_selection_notify_send(ev->requestor, ev->selection, ev->target, ev->property, 0);
|
||||||
|
}
|
||||||
|
else if (ev->target == timestamp_atom)
|
||||||
|
{
|
||||||
|
Ecore_X_Time timestamp;
|
||||||
|
|
||||||
|
timestamp = ecore_x_current_time_get();
|
||||||
|
ecore_x_window_prop_property_set(ev->requestor, ev->property, int_atom, 32, (void*)×tamp, 1);
|
||||||
|
ecore_x_selection_notify_send(ev->requestor, ev->selection, ev->target, ev->property, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
Pipe *p;
|
||||||
|
|
||||||
|
name = ecore_x_atom_name_get(ev->target);
|
||||||
|
EINA_LIST_FOREACH(source->mime_types, l, type)
|
||||||
|
if (eina_streq(name, type))
|
||||||
|
{
|
||||||
|
E_Client *ec;
|
||||||
|
int fds[2];
|
||||||
|
|
||||||
|
p = E_NEW(Pipe, 1);
|
||||||
|
socketpair(AF_UNIX, (SOCK_STREAM | SOCK_CLOEXEC), 0, fds);
|
||||||
|
fcntl(fds[0], F_SETFL, O_NONBLOCK);
|
||||||
|
p->fdh = ecore_main_fd_handler_add(fds[0], ECORE_FD_READ, _xwl_pipe_read, p, NULL, NULL);
|
||||||
|
p->win = ev->requestor;
|
||||||
|
p->source = source;
|
||||||
|
wl_data_source_send_send(source->resource, type, dup(fds[1]));
|
||||||
|
close(fds[1]);
|
||||||
|
p->atom = ev->target;
|
||||||
|
p->selection = ev->selection;
|
||||||
|
p->property = ev->property;
|
||||||
|
ec = e_pixmap_find_client(E_PIXMAP_TYPE_X, ev->requestor);
|
||||||
|
if (ec && ec->override)
|
||||||
|
ecore_x_window_sniff(ev->requestor);
|
||||||
|
eina_hash_add(pipes, &p->win, p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_xwl_property(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Window_Property *ev)
|
||||||
|
{
|
||||||
|
Pipe *p;
|
||||||
|
|
||||||
|
p = eina_hash_find(pipes, &ev->win);
|
||||||
|
if (!p) return ECORE_CALLBACK_RENEW;
|
||||||
|
/* FIXME: WHO FORGOT THE FUCKING STATE FLAG???? */
|
||||||
|
ecore_main_fd_handler_active_set(p->fdh, ECORE_FD_READ);
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
EINTERN void
|
EINTERN void
|
||||||
dnd_init(void)
|
dnd_init(void)
|
||||||
{
|
{
|
||||||
|
@ -196,9 +357,15 @@ dnd_init(void)
|
||||||
ecore_x_fixes_selection_notification_request(ECORE_X_ATOM_SELECTION_XDND);
|
ecore_x_fixes_selection_notification_request(ECORE_X_ATOM_SELECTION_XDND);
|
||||||
E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, _xwl_fixes_selection_notify, NULL);
|
E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, _xwl_fixes_selection_notify, NULL);
|
||||||
E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_SELECTION_NOTIFY, _xwl_selection_notify, NULL);
|
E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_SELECTION_NOTIFY, _xwl_selection_notify, NULL);
|
||||||
|
E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_SELECTION_REQUEST, _xwl_selection_request, NULL);
|
||||||
|
E_LIST_HANDLER_APPEND(handlers, ECORE_X_EVENT_WINDOW_PROPERTY, _xwl_property, NULL);
|
||||||
xconvertselection = dlsym(NULL, "XConvertSelection");
|
xconvertselection = dlsym(NULL, "XConvertSelection");
|
||||||
string_atom = ecore_x_atom_get("UTF8_STRING");
|
string_atom = ecore_x_atom_get("UTF8_STRING");
|
||||||
|
timestamp_atom = ecore_x_atom_get("TIMESTAMP");
|
||||||
|
int_atom = ecore_x_atom_get("INTEGER");
|
||||||
|
incr_atom = ecore_x_atom_get("TIMESTAMP");
|
||||||
xwl_dnd_atom = ecore_x_atom_get("E_XWL_DND_ATOM_HAHA");
|
xwl_dnd_atom = ecore_x_atom_get("E_XWL_DND_ATOM_HAHA");
|
||||||
|
pipes = eina_hash_int32_new((Eina_Free_Cb)_pipe_free);
|
||||||
e_comp_shape_queue();
|
e_comp_shape_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,4 +373,5 @@ EINTERN void
|
||||||
dnd_shutdown(void)
|
dnd_shutdown(void)
|
||||||
{
|
{
|
||||||
E_FREE_LIST(handlers, ecore_event_handler_del);
|
E_FREE_LIST(handlers, ecore_event_handler_del);
|
||||||
|
E_FREE_FUNC(pipes, eina_hash_free);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue