mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-03-06 01:41:07 -05:00
First step towards drag and drop protocol
This commit is contained in:
parent
084d41aac1
commit
eef08fbb1a
11 changed files with 444 additions and 46 deletions
47
TODO
47
TODO
|
|
@ -1,7 +1,7 @@
|
||||||
Core wayland protocol
|
Core wayland protocol
|
||||||
|
|
||||||
- generate pointer_focus on raise/lower, move windows, all kinds of
|
- generate pointer_focus (and drag focus) on raise/lower, move
|
||||||
changes in surface stacking.
|
windows, all kinds of changes in surface stacking.
|
||||||
|
|
||||||
- glyph cache
|
- glyph cache
|
||||||
|
|
||||||
|
|
@ -9,10 +9,53 @@ Core wayland protocol
|
||||||
pass an fd through the compositor to the other client and let them
|
pass an fd through the compositor to the other client and let them
|
||||||
sort it out?
|
sort it out?
|
||||||
|
|
||||||
|
- DnD issues:
|
||||||
|
|
||||||
|
How to roboustly handle failing drag, ie the case where an
|
||||||
|
application gets a button event, tries to activate a drag, but when
|
||||||
|
the server gets the drag request, the button has already been
|
||||||
|
released and the grab is no longer active. What's the concern:
|
||||||
|
|
||||||
|
- Application may set a drag cursor that doesn't revert back,
|
||||||
|
since a failed drag doesn't result in a pointer_focus event to
|
||||||
|
give focus back to the surface. We could just do that: if the
|
||||||
|
pointer_focus is the same surface as we tried to start a grab
|
||||||
|
for, just remove and give back pointer_focus.
|
||||||
|
|
||||||
|
Alternatively, set drag cursors only in response to drag events,
|
||||||
|
like drag focus. But drag_focus and drag_motion are sent to the
|
||||||
|
drag target, so the source surface won't always get those. We
|
||||||
|
may also end up setting the cursor after the drag ends, but in
|
||||||
|
this case the drag started and ended and we'll get a
|
||||||
|
pointer_focus event, which will make the application reset the
|
||||||
|
pointer image. Could introduce a drag start event that
|
||||||
|
indicates that the drag active.
|
||||||
|
|
||||||
|
How to handle drop decline (accept with type=NULL)
|
||||||
|
|
||||||
|
- Targets must send a NULL type in accept if they don't accept a
|
||||||
|
drop at the drag_focus/drag_motion position. Root window will
|
||||||
|
send a NULL type or x-wayland/root-something type if the source
|
||||||
|
offers that.
|
||||||
|
|
||||||
|
Races between pointer motion, ending the drag, the target sending
|
||||||
|
accept request and the source receiving the target event.
|
||||||
|
|
||||||
|
- We've sent a drag focus or motion event to the source, but
|
||||||
|
haven't received an accept request corresponding to that event
|
||||||
|
and now the button is release. The compositor could wait for
|
||||||
|
the source to reply to outstanding focus/motion events before
|
||||||
|
sending the finish event to the source. Or we could send the
|
||||||
|
finish event through the source so that it needs to reply to the
|
||||||
|
finish event too. Either way, the state of the drag blocks on
|
||||||
|
the client. What if we drag to a client that doesn't doo dnd?
|
||||||
|
|
||||||
- copy-n-paste, store data in server (only one mime-type available)
|
- copy-n-paste, store data in server (only one mime-type available)
|
||||||
or do X style (content mime-type negotiation, but data goes away
|
or do X style (content mime-type negotiation, but data goes away
|
||||||
when client quits).
|
when client quits).
|
||||||
|
|
||||||
|
- Optional pointer images.
|
||||||
|
|
||||||
- Discard buffer, as in "wayland discarded your buffer, it's no
|
- Discard buffer, as in "wayland discarded your buffer, it's no
|
||||||
longer visible, you can stop updating it now.", reattach, as in "oh
|
longer visible, you can stop updating it now.", reattach, as in "oh
|
||||||
hey, I'm about to show your buffer that I threw away, what was it
|
hey, I'm about to show your buffer that I threw away, what was it
|
||||||
|
|
|
||||||
283
compositor.c
283
compositor.c
|
|
@ -239,15 +239,17 @@ create_pointer_images(struct wlsc_compositor *ec)
|
||||||
image_attribs[1] = width;
|
image_attribs[1] = width;
|
||||||
image_attribs[3] = height;
|
image_attribs[3] = height;
|
||||||
count = ARRAY_LENGTH(pointer_images);
|
count = ARRAY_LENGTH(pointer_images);
|
||||||
ec->pointer_images = malloc(count * sizeof *ec->pointer_images);
|
ec->pointer_buffers = malloc(count * sizeof *ec->pointer_buffers);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
ec->pointer_images[i] =
|
ec->pointer_buffers[i].image =
|
||||||
eglCreateDRMImageMESA(ec->display, image_attribs);
|
eglCreateDRMImageMESA(ec->display, image_attribs);
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
|
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
|
||||||
ec->pointer_images[i]);
|
ec->pointer_buffers[i].image);
|
||||||
texture_from_png(pointer_images[i].filename, width, height);
|
texture_from_png(pointer_images[i].filename, width, height);
|
||||||
|
ec->pointer_buffers[i].visual = &ec->argb_visual;
|
||||||
|
ec->pointer_buffers[i].width = width;
|
||||||
|
ec->pointer_buffers[i].height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlsc_surface *
|
static struct wlsc_surface *
|
||||||
|
|
@ -457,29 +459,43 @@ const static struct wl_surface_interface surface_interface = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
|
wlsc_input_device_attach(struct wlsc_input_device *device,
|
||||||
enum wlsc_pointer_type type)
|
struct wlsc_buffer *buffer, int x, int y)
|
||||||
{
|
{
|
||||||
struct wlsc_compositor *ec = device->ec;
|
struct wlsc_compositor *ec = device->ec;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, device->sprite->texture);
|
glBindTexture(GL_TEXTURE_2D, device->sprite->texture);
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, ec->pointer_images[type]);
|
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image);
|
||||||
device->sprite->visual = &ec->argb_visual;
|
device->sprite->visual = buffer->visual;
|
||||||
device->hotspot_x = pointer_images[type].hotspot_x;
|
device->hotspot_x = x;
|
||||||
device->hotspot_y = pointer_images[type].hotspot_y;
|
device->hotspot_y = y;
|
||||||
|
|
||||||
device->sprite->x = device->x - device->hotspot_x;
|
device->sprite->x = device->x - device->hotspot_x;
|
||||||
device->sprite->y = device->y - device->hotspot_y;
|
device->sprite->y = device->y - device->hotspot_y;
|
||||||
|
device->sprite->width = buffer->width;
|
||||||
|
device->sprite->height = buffer->height;
|
||||||
wlsc_surface_update_matrix(device->sprite);
|
wlsc_surface_update_matrix(device->sprite);
|
||||||
|
|
||||||
wlsc_compositor_schedule_repaint(ec);
|
wlsc_compositor_schedule_repaint(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
|
||||||
|
enum wlsc_pointer_type type)
|
||||||
|
{
|
||||||
|
struct wlsc_compositor *compositor = device->ec;
|
||||||
|
|
||||||
|
wlsc_input_device_attach(device,
|
||||||
|
&compositor->pointer_buffers[type],
|
||||||
|
pointer_images[type].hotspot_x,
|
||||||
|
pointer_images[type].hotspot_y);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wlsc_input_device_start_grab(struct wlsc_input_device *device,
|
wlsc_input_device_start_grab(struct wlsc_input_device *device,
|
||||||
uint32_t time,
|
uint32_t time,
|
||||||
enum wlsc_grab_type grab,
|
enum wlsc_grab_type grab)
|
||||||
enum wlsc_pointer_type pointer)
|
|
||||||
{
|
{
|
||||||
device->grab = grab;
|
device->grab = grab;
|
||||||
device->grab_surface = device->pointer_focus;
|
device->grab_surface = device->pointer_focus;
|
||||||
|
|
@ -491,8 +507,6 @@ wlsc_input_device_start_grab(struct wlsc_input_device *device,
|
||||||
wlsc_input_device_set_pointer_focus(device,
|
wlsc_input_device_set_pointer_focus(device,
|
||||||
(struct wlsc_surface *) &wl_grab_surface,
|
(struct wlsc_surface *) &wl_grab_surface,
|
||||||
time, 0, 0, 0, 0);
|
time, 0, 0, 0, 0);
|
||||||
|
|
||||||
wlsc_input_device_set_pointer_image(device, pointer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -507,9 +521,8 @@ shell_move(struct wl_client *client, struct wl_shell *shell,
|
||||||
&wd->pointer_focus->base != surface)
|
&wd->pointer_focus->base != surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wlsc_input_device_start_grab(wd, time,
|
wlsc_input_device_start_grab(wd, time, WLSC_DEVICE_GRAB_MOVE);
|
||||||
WLSC_DEVICE_GRAB_MOVE,
|
wlsc_input_device_set_pointer_image(wd, WLSC_POINTER_DRAGGING);
|
||||||
WLSC_POINTER_DRAGGING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -556,7 +569,8 @@ shell_resize(struct wl_client *client, struct wl_shell *shell,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlsc_input_device_start_grab(wd, time, edges, pointer);
|
wlsc_input_device_start_grab(wd, time, edges);
|
||||||
|
wlsc_input_device_set_pointer_image(wd, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const static struct wl_shell_interface shell_interface = {
|
const static struct wl_shell_interface shell_interface = {
|
||||||
|
|
@ -681,6 +695,13 @@ pick_surface(struct wlsc_input_device *device, int32_t *sx, int32_t *sy)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wl_drag_reset(struct wl_drag *drag);
|
||||||
|
static void
|
||||||
|
wl_drag_set_pointer_focus(struct wl_drag *drag,
|
||||||
|
struct wlsc_surface *surface, uint32_t time,
|
||||||
|
int32_t x, int32_t y, int32_t sx, int32_t sy);
|
||||||
|
|
||||||
void
|
void
|
||||||
notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
|
notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
@ -773,6 +794,17 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
|
||||||
WL_SHELL_CONFIGURE, time, device->grab,
|
WL_SHELL_CONFIGURE, time, device->grab,
|
||||||
&es->base, sx, sy, width, height);
|
&es->base, sx, sy, width, height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WLSC_DEVICE_GRAB_DRAG:
|
||||||
|
es = pick_surface(device, &sx, &sy);
|
||||||
|
wl_drag_set_pointer_focus(&device->drag,
|
||||||
|
es, time, x, y, sx, sy);
|
||||||
|
if (es)
|
||||||
|
wl_surface_post_event(&es->base, &device->drag.base,
|
||||||
|
WL_DRAG_MOTION,
|
||||||
|
time, x, y, sx, sy);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device->sprite->x = device->x - device->hotspot_x;
|
device->sprite->x = device->x - device->hotspot_x;
|
||||||
|
|
@ -785,9 +817,21 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
|
||||||
static void
|
static void
|
||||||
wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time)
|
wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time)
|
||||||
{
|
{
|
||||||
|
struct wl_drag *drag = &device->drag;
|
||||||
struct wlsc_surface *es;
|
struct wlsc_surface *es;
|
||||||
int32_t sx, sy;
|
int32_t sx, sy;
|
||||||
|
|
||||||
|
switch (device->grab) {
|
||||||
|
case WLSC_DEVICE_GRAB_DRAG:
|
||||||
|
wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
|
||||||
|
wl_surface_post_event(drag->source, &drag->base,
|
||||||
|
WL_DRAG_FINISH);
|
||||||
|
wl_drag_reset(drag);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
device->grab = WLSC_DEVICE_GRAB_NONE;
|
device->grab = WLSC_DEVICE_GRAB_NONE;
|
||||||
es = pick_surface(device, &sx, &sy);
|
es = pick_surface(device, &sx, &sy);
|
||||||
wlsc_input_device_set_pointer_focus(device, es, time,
|
wlsc_input_device_set_pointer_focus(device, es, time,
|
||||||
|
|
@ -836,7 +880,6 @@ notify_button(struct wlsc_input_device *device,
|
||||||
if (!state &&
|
if (!state &&
|
||||||
device->grab != WLSC_DEVICE_GRAB_NONE &&
|
device->grab != WLSC_DEVICE_GRAB_NONE &&
|
||||||
device->grab_button == button) {
|
device->grab_button == button) {
|
||||||
device->grab = WLSC_DEVICE_GRAB_NONE;
|
|
||||||
wlsc_input_device_end_grab(device, time);
|
wlsc_input_device_end_grab(device, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -919,17 +962,7 @@ input_device_attach(struct wl_client *client,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, device->sprite->texture);
|
wlsc_input_device_attach(device, buffer, x, y);
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image);
|
|
||||||
device->sprite->visual = buffer->visual;
|
|
||||||
device->hotspot_x = x;
|
|
||||||
device->hotspot_y = y;
|
|
||||||
|
|
||||||
device->sprite->x = device->x - device->hotspot_x;
|
|
||||||
device->sprite->y = device->y - device->hotspot_y;
|
|
||||||
wlsc_surface_update_matrix(device->sprite);
|
|
||||||
|
|
||||||
wlsc_compositor_schedule_repaint(device->ec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const static struct wl_input_device_interface input_device_interface = {
|
const static struct wl_input_device_interface input_device_interface = {
|
||||||
|
|
@ -962,6 +995,194 @@ handle_surface_destroy(struct wlsc_listener *listener,
|
||||||
wlsc_input_device_end_grab(device, time);
|
wlsc_input_device_end_grab(device, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wl_drag_set_pointer_focus(struct wl_drag *drag,
|
||||||
|
struct wlsc_surface *surface, uint32_t time,
|
||||||
|
int32_t x, int32_t y, int32_t sx, int32_t sy)
|
||||||
|
{
|
||||||
|
if (drag->pointer_focus == &surface->base)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (drag->pointer_focus &&
|
||||||
|
(!surface || drag->pointer_focus->client != surface->base.client))
|
||||||
|
wl_surface_post_event(drag->pointer_focus,
|
||||||
|
&drag->base,
|
||||||
|
WL_DRAG_POINTER_FOCUS,
|
||||||
|
time, NULL, 0, 0, 0, 0);
|
||||||
|
if (surface)
|
||||||
|
wl_surface_post_event(&surface->base,
|
||||||
|
&drag->base,
|
||||||
|
WL_DRAG_POINTER_FOCUS,
|
||||||
|
time, &surface->base,
|
||||||
|
x, y, sx, sy);
|
||||||
|
|
||||||
|
drag->pointer_focus = &surface->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wl_drag_reset(struct wl_drag *drag)
|
||||||
|
{
|
||||||
|
char **p, **end;
|
||||||
|
|
||||||
|
end = drag->types.data + drag->types.size;
|
||||||
|
for (p = drag->types.data; p < end; p++)
|
||||||
|
free(*p);
|
||||||
|
wl_array_release(&drag->types);
|
||||||
|
wl_array_init(&drag->types);
|
||||||
|
|
||||||
|
drag->source = NULL;
|
||||||
|
drag->target = NULL;
|
||||||
|
drag->time = 0;
|
||||||
|
drag->pointer_focus = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_prepare(struct wl_client *client,
|
||||||
|
struct wl_drag *drag, struct wl_surface *surface, uint32_t time,
|
||||||
|
struct wl_buffer *buffer, int32_t hotspot_x, int32_t hotspot_y)
|
||||||
|
{
|
||||||
|
struct wlsc_input_device *device =
|
||||||
|
(struct wlsc_input_device *) drag->input_device;
|
||||||
|
|
||||||
|
if (&device->pointer_focus->base != surface ||
|
||||||
|
device->grab_time != time)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wl_drag_reset(drag);
|
||||||
|
drag->source = surface;
|
||||||
|
drag->time = time;
|
||||||
|
drag->buffer = buffer;
|
||||||
|
drag->hotspot_x = hotspot_x;
|
||||||
|
drag->hotspot_y = hotspot_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_offer(struct wl_client *client, struct wl_drag *drag, const char *type)
|
||||||
|
{
|
||||||
|
struct wl_display *display = wl_client_get_display (client);
|
||||||
|
struct wlsc_input_device *device =
|
||||||
|
(struct wlsc_input_device *) drag->input_device;
|
||||||
|
char **p;
|
||||||
|
|
||||||
|
if (drag->source == NULL ||
|
||||||
|
drag->source->client != client ||
|
||||||
|
device->grab != WLSC_DEVICE_GRAB_MOTION ||
|
||||||
|
&device->pointer_focus->base != drag->source ||
|
||||||
|
device->grab_time != drag->time)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p = wl_array_add(&drag->types, sizeof *p);
|
||||||
|
if (p)
|
||||||
|
*p = strdup(type);
|
||||||
|
if (!p || !*p)
|
||||||
|
wl_client_post_event(client,
|
||||||
|
(struct wl_object *) display,
|
||||||
|
WL_DISPLAY_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_activate(struct wl_client *client,
|
||||||
|
struct wl_drag *drag)
|
||||||
|
{
|
||||||
|
struct wlsc_input_device *device =
|
||||||
|
(struct wlsc_input_device *) drag->input_device;
|
||||||
|
struct wlsc_surface *surface;
|
||||||
|
int32_t sx, sy;
|
||||||
|
|
||||||
|
if (drag->source == NULL ||
|
||||||
|
drag->source->client != client ||
|
||||||
|
device->grab != WLSC_DEVICE_GRAB_MOTION ||
|
||||||
|
&device->pointer_focus->base != drag->source ||
|
||||||
|
device->grab_time != drag->time)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wlsc_input_device_start_grab(device, drag->time,
|
||||||
|
WLSC_DEVICE_GRAB_DRAG);
|
||||||
|
wlsc_input_device_attach(device, (struct wlsc_buffer *) drag->buffer,
|
||||||
|
drag->hotspot_x, drag->hotspot_y);
|
||||||
|
|
||||||
|
surface = pick_surface(device, &sx, &sy);
|
||||||
|
wl_drag_set_pointer_focus(&device->drag, surface, drag->time,
|
||||||
|
device->x, device->y, sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_cancel(struct wl_client *client, struct wl_drag *drag)
|
||||||
|
{
|
||||||
|
struct wlsc_input_device *device =
|
||||||
|
(struct wlsc_input_device *) drag->input_device;
|
||||||
|
|
||||||
|
if (drag->source == NULL ||
|
||||||
|
drag->source->client != client ||
|
||||||
|
device->grab != WLSC_DEVICE_GRAB_DRAG)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wlsc_input_device_end_grab(device, get_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_send(struct wl_client *client,
|
||||||
|
struct wl_drag *drag, struct wl_array *contents)
|
||||||
|
{
|
||||||
|
wl_client_post_event(client, &drag->base, WL_DRAG_DROP, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_accept(struct wl_client *client,
|
||||||
|
struct wl_drag *drag, const char *type)
|
||||||
|
{
|
||||||
|
char **p, **end;
|
||||||
|
|
||||||
|
if (drag->pointer_focus->client != client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* FIXME: We need a serial number here to correlate the accept
|
||||||
|
* request with a pointer_focus/motion event. */
|
||||||
|
drag->target = client;
|
||||||
|
|
||||||
|
end = drag->types.data + drag->types.size;
|
||||||
|
for (p = drag->types.data; p < end; p++)
|
||||||
|
if (strcmp(*p, type) == 0)
|
||||||
|
drag->type = *p;
|
||||||
|
|
||||||
|
wl_surface_post_event(drag->source, &drag->base,
|
||||||
|
WL_DRAG_TARGET, drag->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_drag_interface drag_interface = {
|
||||||
|
drag_prepare,
|
||||||
|
drag_offer,
|
||||||
|
drag_activate,
|
||||||
|
drag_cancel,
|
||||||
|
drag_send,
|
||||||
|
drag_accept
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
wl_drag_post_device(struct wl_client *client, struct wl_object *global)
|
||||||
|
{
|
||||||
|
struct wl_drag *drag = container_of(global, struct wl_drag, base);
|
||||||
|
|
||||||
|
wl_client_post_event(client, global,
|
||||||
|
WL_DRAG_DEVICE, drag->input_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wl_drag_init(struct wl_drag *drag,
|
||||||
|
struct wl_display *display, struct wl_input_device *input_device)
|
||||||
|
{
|
||||||
|
drag->base.interface = &wl_drag_interface;
|
||||||
|
drag->base.implementation = (void (**)(void))
|
||||||
|
&drag_interface;
|
||||||
|
|
||||||
|
wl_display_add_object(display, &drag->base);
|
||||||
|
wl_display_add_global(display, &drag->base, wl_drag_post_device);
|
||||||
|
|
||||||
|
drag->source = NULL;
|
||||||
|
wl_array_init(&drag->types);
|
||||||
|
drag->input_device = input_device;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wlsc_input_device_init(struct wlsc_input_device *device,
|
wlsc_input_device_init(struct wlsc_input_device *device,
|
||||||
struct wlsc_compositor *ec)
|
struct wlsc_compositor *ec)
|
||||||
|
|
@ -972,6 +1193,8 @@ wlsc_input_device_init(struct wlsc_input_device *device,
|
||||||
wl_display_add_object(ec->wl_display, &device->base.base);
|
wl_display_add_object(ec->wl_display, &device->base.base);
|
||||||
wl_display_add_global(ec->wl_display, &device->base.base, NULL);
|
wl_display_add_global(ec->wl_display, &device->base.base, NULL);
|
||||||
|
|
||||||
|
wl_drag_init(&device->drag, ec->wl_display, &device->base);
|
||||||
|
|
||||||
device->x = 100;
|
device->x = 100;
|
||||||
device->y = 100;
|
device->y = 100;
|
||||||
device->ec = ec;
|
device->ec = ec;
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,8 @@ enum wlsc_grab_type {
|
||||||
WLSC_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT = 10,
|
WLSC_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT = 10,
|
||||||
WLSC_DEVICE_GRAB_RESIZE_MASK = 15,
|
WLSC_DEVICE_GRAB_RESIZE_MASK = 15,
|
||||||
WLSC_DEVICE_GRAB_MOVE = 16,
|
WLSC_DEVICE_GRAB_MOVE = 16,
|
||||||
WLSC_DEVICE_GRAB_MOTION = 17
|
WLSC_DEVICE_GRAB_MOTION = 17,
|
||||||
|
WLSC_DEVICE_GRAB_DRAG = 18
|
||||||
};
|
};
|
||||||
|
|
||||||
enum wlsc_pointer_type {
|
enum wlsc_pointer_type {
|
||||||
|
|
@ -106,6 +107,7 @@ struct wlsc_input_device {
|
||||||
int32_t grab_width, grab_height;
|
int32_t grab_width, grab_height;
|
||||||
int32_t grab_dx, grab_dy;
|
int32_t grab_dx, grab_dy;
|
||||||
uint32_t grab_button;
|
uint32_t grab_button;
|
||||||
|
struct wl_drag drag;
|
||||||
|
|
||||||
struct wlsc_listener listener;
|
struct wlsc_listener listener;
|
||||||
};
|
};
|
||||||
|
|
@ -118,6 +120,7 @@ struct wlsc_drm {
|
||||||
|
|
||||||
struct wlsc_buffer {
|
struct wlsc_buffer {
|
||||||
struct wl_buffer base;
|
struct wl_buffer base;
|
||||||
|
int32_t width, height;
|
||||||
EGLImageKHR image;
|
EGLImageKHR image;
|
||||||
struct wl_visual *visual;
|
struct wl_visual *visual;
|
||||||
};
|
};
|
||||||
|
|
@ -131,7 +134,7 @@ struct wlsc_compositor {
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
GLuint fbo, vbo;
|
GLuint fbo, vbo;
|
||||||
GLuint proj_uniform, tex_uniform;
|
GLuint proj_uniform, tex_uniform;
|
||||||
EGLImageKHR *pointer_images;
|
struct wlsc_buffer *pointer_buffers;
|
||||||
struct wl_display *wl_display;
|
struct wl_display *wl_display;
|
||||||
|
|
||||||
/* We implement the shell interface. */
|
/* We implement the shell interface. */
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ cursor_images = \
|
||||||
top_left_corner.png \
|
top_left_corner.png \
|
||||||
top_right_corner.png \
|
top_right_corner.png \
|
||||||
top_side.png \
|
top_side.png \
|
||||||
xterm.png
|
xterm.png \
|
||||||
|
hand1.png
|
||||||
|
|
||||||
all :
|
all :
|
||||||
|
|
||||||
|
|
|
||||||
BIN
data/hand1.png
Normal file
BIN
data/hand1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
88
protocol.xml
88
protocol.xml
|
|
@ -96,6 +96,94 @@
|
||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
|
<interface name="drag" version="1">
|
||||||
|
<request name="prepare">
|
||||||
|
<!-- Start a drag action from given surface and device for the
|
||||||
|
grab started by the button click at time -->
|
||||||
|
<arg name="surface" type="object" interface="surface"/>
|
||||||
|
<arg name="time" type="uint"/>
|
||||||
|
<arg name="buffer" type="object" interface="buffer"/>
|
||||||
|
<arg name="hotspot_x" type="int"/>
|
||||||
|
<arg name="hotspot_y" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Add an offered mime type. Can be called several times to
|
||||||
|
offer multiple types, but must be called before 'activate'. -->
|
||||||
|
<request name="offer">
|
||||||
|
<arg name="type" type="string"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="activate"/>
|
||||||
|
|
||||||
|
<!-- Cancel the drag. -->
|
||||||
|
<request name="cancel"/>
|
||||||
|
|
||||||
|
<!-- Send the data to the target that accepted the offer -->
|
||||||
|
<request name="send">
|
||||||
|
<arg name="contents" type="array"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Called by the drag target to accept the offer of the given
|
||||||
|
type -->
|
||||||
|
<request name="accept">
|
||||||
|
<arg name="type" type="string"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Sent at connect time to announce the association -->
|
||||||
|
<event name="device">
|
||||||
|
<arg name="device" type="object" interface="input_device"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Similar to device::pointer_focus. Sent to potential
|
||||||
|
target surfaces to offer drag data. If the device
|
||||||
|
leaves the window, the drag stops or the originator cancels
|
||||||
|
the drag, this event is sent with the NULL surface. -->
|
||||||
|
<event name="pointer_focus">
|
||||||
|
<arg name="time" type="uint"/>
|
||||||
|
<arg name="surface" type="object" interface="surface"/>
|
||||||
|
<arg name="x" type="int"/>
|
||||||
|
<arg name="y" type="int"/>
|
||||||
|
<arg name="surface_x" type="int"/>
|
||||||
|
<arg name="surface_y" type="int"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Sent after the pointer_focus event to announce the types
|
||||||
|
offered. One event per offered mime type. -->
|
||||||
|
<event name="offer">
|
||||||
|
<arg name="type" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Similar to device::motion. Sent to potential target surfaces
|
||||||
|
as the drag pointer moves around in the surface. -->
|
||||||
|
<event name="motion">
|
||||||
|
<arg name="time" type="uint"/>
|
||||||
|
<arg name="x" type="int"/>
|
||||||
|
<arg name="y" type="int"/>
|
||||||
|
<arg name="surface_x" type="int"/>
|
||||||
|
<arg name="surface_y" type="int"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Sent to drag originator in response to pointer_focus and
|
||||||
|
motion events. If a target does not accept any of the
|
||||||
|
offered types, type is NULL -->
|
||||||
|
<event name="target">
|
||||||
|
<arg name="mime_type" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Sent to drag originator when the drag is finished. It's also
|
||||||
|
sent in case an originator tries to activate a drag after the
|
||||||
|
grab was released. If the originator didn't receive a
|
||||||
|
'target' event before receiving the 'finish' event, no drag
|
||||||
|
target was found and the originator should not send data. -->
|
||||||
|
<event name="finish"/>
|
||||||
|
|
||||||
|
<!-- Sent to target, contains dragged data. Ends transaction on
|
||||||
|
the target side. -->
|
||||||
|
<event name="drop">
|
||||||
|
<arg name="contents" type="array"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
|
||||||
<interface name="surface" version="1">
|
<interface name="surface" version="1">
|
||||||
<request name="destroy"/>
|
<request name="destroy"/>
|
||||||
|
|
||||||
|
|
|
||||||
25
scanner.c
25
scanner.c
|
|
@ -273,6 +273,22 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
|
||||||
interface->name,
|
interface->name,
|
||||||
interface->name);
|
interface->name);
|
||||||
|
|
||||||
|
printf("static inline void\n"
|
||||||
|
"wl_%s_set_user_data(struct wl_%s *%s, void *user_data)\n"
|
||||||
|
"{\n"
|
||||||
|
"\twl_proxy_set_user_data((struct wl_proxy *) %s, user_data);\n"
|
||||||
|
"}\n\n",
|
||||||
|
interface->name, interface->name, interface->name,
|
||||||
|
interface->name);
|
||||||
|
|
||||||
|
printf("static inline void *\n"
|
||||||
|
"wl_%s_get_user_data(struct wl_%s *%s)\n"
|
||||||
|
"{\n"
|
||||||
|
"\treturn wl_proxy_get_user_data((struct wl_proxy *) %s);\n"
|
||||||
|
"}\n\n",
|
||||||
|
interface->name, interface->name, interface->name,
|
||||||
|
interface->name);
|
||||||
|
|
||||||
if (wl_list_empty(message_list))
|
if (wl_list_empty(message_list))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -424,7 +440,14 @@ static const char client_prototypes[] =
|
||||||
|
|
||||||
"extern int\n"
|
"extern int\n"
|
||||||
"wl_proxy_add_listener(struct wl_proxy *proxy,\n"
|
"wl_proxy_add_listener(struct wl_proxy *proxy,\n"
|
||||||
"\t\t void (**implementation)(void), void *data);\n\n";
|
"\t\t void (**implementation)(void), void *data);\n\n"
|
||||||
|
|
||||||
|
"extern void\n"
|
||||||
|
"wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);\n\n"
|
||||||
|
|
||||||
|
"extern void *\n"
|
||||||
|
"wl_proxy_get_user_data(struct wl_proxy *proxy);\n\n";
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_header(struct protocol *protocol, int server)
|
emit_header(struct protocol *protocol, int server)
|
||||||
|
|
|
||||||
|
|
@ -402,17 +402,13 @@ wl_display_allocate_id(struct wl_display *display)
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
wl_surface_set_user_data(struct wl_surface *surface, void *user_data)
|
wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data)
|
||||||
{
|
{
|
||||||
struct wl_proxy *proxy = (struct wl_proxy *) surface;
|
|
||||||
|
|
||||||
proxy->user_data = user_data;
|
proxy->user_data = user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT void *
|
WL_EXPORT void *
|
||||||
wl_surface_get_user_data(struct wl_surface *surface)
|
wl_proxy_get_user_data(struct wl_proxy *proxy)
|
||||||
{
|
{
|
||||||
struct wl_proxy *proxy = (struct wl_proxy *) surface;
|
|
||||||
|
|
||||||
return proxy->user_data;
|
return proxy->user_data;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,6 @@ wl_display_get_premultiplied_argb_visual(struct wl_display *display);
|
||||||
struct wl_visual *
|
struct wl_visual *
|
||||||
wl_display_get_rgb_visual(struct wl_display *display);
|
wl_display_get_rgb_visual(struct wl_display *display);
|
||||||
|
|
||||||
void wl_surface_set_user_data(struct wl_surface *surface, void *user_data);
|
|
||||||
void *wl_surface_get_user_data(struct wl_surface *surface);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,12 @@ wl_client_connection_update(struct wl_connection *connection,
|
||||||
return wl_event_source_fd_update(client->source, mask);
|
return wl_event_source_fd_update(client->source, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT struct wl_display *
|
||||||
|
wl_client_get_display(struct wl_client *client)
|
||||||
|
{
|
||||||
|
return client->display;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wl_display_post_range(struct wl_display *display, struct wl_client *client)
|
wl_display_post_range(struct wl_display *display, struct wl_client *client)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,22 @@ struct wl_visual {
|
||||||
struct wl_object base;
|
struct wl_object base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wl_drag {
|
||||||
|
struct wl_object base;
|
||||||
|
struct wl_surface *source;
|
||||||
|
struct wl_surface *pointer_focus;
|
||||||
|
struct wl_client *target;
|
||||||
|
int32_t x, y, sx, sy;
|
||||||
|
struct wl_input_device *input_device;
|
||||||
|
struct wl_array types;
|
||||||
|
const char *type;
|
||||||
|
uint32_t time;
|
||||||
|
|
||||||
|
struct wl_buffer *buffer;
|
||||||
|
int32_t hotspot_x;
|
||||||
|
int32_t hotspot_y;
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
wl_client_post_event(struct wl_client *client,
|
wl_client_post_event(struct wl_client *client,
|
||||||
struct wl_object *sender,
|
struct wl_object *sender,
|
||||||
|
|
@ -159,6 +175,9 @@ void
|
||||||
wl_client_add_resource(struct wl_client *client,
|
wl_client_add_resource(struct wl_client *client,
|
||||||
struct wl_resource *resource);
|
struct wl_resource *resource);
|
||||||
|
|
||||||
|
struct wl_display *
|
||||||
|
wl_client_get_display(struct wl_client *client);
|
||||||
|
|
||||||
void
|
void
|
||||||
wl_resource_destroy(struct wl_resource *resource, struct wl_client *client);
|
wl_resource_destroy(struct wl_resource *resource, struct wl_client *client);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue