|
|
@ -47,6 +47,8 @@ struct dnd { |
|
|
|
|
|
|
|
|
|
|
|
struct wl_buffer *buffer; |
|
|
|
struct wl_buffer *buffer; |
|
|
|
int hotspot_x, hotspot_y; |
|
|
|
int hotspot_x, hotspot_y; |
|
|
|
|
|
|
|
uint32_t tag; |
|
|
|
|
|
|
|
const char *drag_type; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct item { |
|
|
|
struct item { |
|
|
@ -221,9 +223,20 @@ drag_pointer_focus(void *data, |
|
|
|
uint32_t time, struct wl_surface *surface, |
|
|
|
uint32_t time, struct wl_surface *surface, |
|
|
|
int32_t x, int32_t y, int32_t surface_x, int32_t surface_y) |
|
|
|
int32_t x, int32_t y, int32_t surface_x, int32_t surface_y) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
struct dnd *dnd = data; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* FIXME: We need the offered types before we get the
|
|
|
|
|
|
|
|
* pointer_focus event so we know which one we want and can |
|
|
|
|
|
|
|
* send the accept request back. */ |
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "drag pointer focus %p\n", surface); |
|
|
|
fprintf(stderr, "drag pointer focus %p\n", surface); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (surface) { |
|
|
|
wl_drag_accept(drag, "text/plain"); |
|
|
|
wl_drag_accept(drag, "text/plain"); |
|
|
|
|
|
|
|
dnd->drag_type = "text/plain"; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
dnd->drag_type = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
static void |
|
|
@ -239,13 +252,14 @@ drag_motion(void *data, |
|
|
|
uint32_t time, |
|
|
|
uint32_t time, |
|
|
|
int32_t x, int32_t y, int32_t surface_x, int32_t surface_y) |
|
|
|
int32_t x, int32_t y, int32_t surface_x, int32_t surface_y) |
|
|
|
{ |
|
|
|
{ |
|
|
|
fprintf(stderr, "drag motion %d,%d\n", surface_x, surface_y); |
|
|
|
struct dnd *dnd = data; |
|
|
|
|
|
|
|
|
|
|
|
/* FIXME: Need to correlate this with the offer event.
|
|
|
|
/* FIXME: Need to correlate this with the offer event.
|
|
|
|
* Problem is, we don't know when we've seen that last offer |
|
|
|
* Problem is, we don't know when we've seen that last offer |
|
|
|
* event, and we might need to look at all of them before we |
|
|
|
* event, and we might need to look at all of them before we |
|
|
|
* can decide which one to go with. */ |
|
|
|
* can decide which one to go with. */ |
|
|
|
wl_drag_accept(drag, "text/plain"); |
|
|
|
wl_drag_accept(drag, "text/plain"); |
|
|
|
|
|
|
|
dnd->drag_type = "text/plain"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
static void |
|
|
@ -256,32 +270,63 @@ drag_target(void *data, |
|
|
|
struct input *input; |
|
|
|
struct input *input; |
|
|
|
struct wl_input_device *device; |
|
|
|
struct wl_input_device *device; |
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "target %s\n", mime_type); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
input = wl_drag_get_user_data(drag); |
|
|
|
input = wl_drag_get_user_data(drag); |
|
|
|
device = input_get_input_device(input); |
|
|
|
device = input_get_input_device(input); |
|
|
|
wl_input_device_attach(device, dnd->buffer, |
|
|
|
wl_input_device_attach(device, dnd->buffer, |
|
|
|
dnd->hotspot_x, dnd->hotspot_y); |
|
|
|
dnd->hotspot_x, dnd->hotspot_y); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean |
|
|
|
|
|
|
|
drop_io_func(GIOChannel *source, GIOCondition condition, gpointer data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct dnd *dnd = data; |
|
|
|
|
|
|
|
char buffer[256]; |
|
|
|
|
|
|
|
int fd; |
|
|
|
|
|
|
|
unsigned int len; |
|
|
|
|
|
|
|
GError *err = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_io_channel_read_chars(source, buffer, sizeof buffer, &len, &err); |
|
|
|
|
|
|
|
fprintf(stderr, "read %d bytes: %s\n", len, buffer); |
|
|
|
|
|
|
|
fd = g_io_channel_unix_get_fd(source); |
|
|
|
|
|
|
|
close(fd); |
|
|
|
|
|
|
|
g_source_remove(dnd->tag); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_io_channel_unref(source); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return TRUE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
static void |
|
|
|
drag_finish(void *data, struct wl_drag *drag) |
|
|
|
drag_drop(void *data, struct wl_drag *drag) |
|
|
|
{ |
|
|
|
{ |
|
|
|
fprintf(stderr, "drag finish\n"); |
|
|
|
struct dnd *dnd = data; |
|
|
|
struct wl_array a; |
|
|
|
int p[2]; |
|
|
|
char text[] = "[drop data]"; |
|
|
|
GIOChannel *channel; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!dnd->drag_type) { |
|
|
|
|
|
|
|
fprintf(stderr, "got 'drop', but no target\n"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "got 'drop', sending write end of pipe\n"); |
|
|
|
|
|
|
|
|
|
|
|
a.data = text; |
|
|
|
pipe(p); |
|
|
|
a.size = sizeof text; |
|
|
|
wl_drag_receive(drag, p[1]); |
|
|
|
|
|
|
|
close(p[1]); |
|
|
|
|
|
|
|
|
|
|
|
wl_drag_send(drag, &a); |
|
|
|
channel = g_io_channel_unix_new(p[0]); |
|
|
|
|
|
|
|
dnd->tag = g_io_add_watch(channel, G_IO_IN, drop_io_func, dnd); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
static void |
|
|
|
drag_data(void *data, |
|
|
|
drag_finish(void *data, struct wl_drag *drag, int fd) |
|
|
|
struct wl_drag *drag, struct wl_array *contents) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
fprintf(stderr, "drag drop, data %s\n", (char *) contents->data); |
|
|
|
char text[] = "[drop data]"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "got 'finish', fd %d, sending message\n", fd); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
write(fd, text, sizeof text); |
|
|
|
|
|
|
|
close(fd); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static const struct wl_drag_listener drag_listener = { |
|
|
|
static const struct wl_drag_listener drag_listener = { |
|
|
@ -290,8 +335,8 @@ static const struct wl_drag_listener drag_listener = { |
|
|
|
drag_offer, |
|
|
|
drag_offer, |
|
|
|
drag_motion, |
|
|
|
drag_motion, |
|
|
|
drag_target, |
|
|
|
drag_target, |
|
|
|
drag_finish, |
|
|
|
drag_drop, |
|
|
|
drag_data |
|
|
|
drag_finish |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
static void |
|
|
|