X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=clients%2Fdnd.c;h=4aad070ca35f11d228da0eda78e4a5ba8719cb00;hb=b6eae9faf70e3d113fd379eb44229928a80ee3b4;hp=8e67dc4d1ab485143a1b78269f17a993a81c7e6b;hpb=3685c3abf6c6f7d03b571458df52731ccf928981;p=profile%2Fivi%2Fweston.git diff --git a/clients/dnd.c b/clients/dnd.c index 8e67dc4..4aad070 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -20,6 +20,7 @@ * OF THIS SOFTWARE. */ +#include #include #include #include @@ -32,9 +33,12 @@ #include #include +#include #include "window.h" -#include "cairo-util.h" +#include "../shared/cairo-util.h" + +struct dnd_drag; struct dnd { struct window *window; @@ -42,6 +46,8 @@ struct dnd { struct display *display; uint32_t key; struct item *items[16]; + int self_only; + struct dnd_drag *current_drag; }; struct dnd_drag { @@ -105,7 +111,8 @@ item_create(struct display *display, int x, int y, int seed) rect.width = item_width; rect.height = item_height; - item->surface = display_create_surface(display, NULL, &rect, 0); + item->surface = + display_create_surface(display, NULL, &rect, SURFACE_SHM); item->x = x; item->y = y; @@ -180,6 +187,9 @@ dnd_redraw_handler(struct widget *widget, void *data) cairo_set_source_rgba(cr, 0, 0, 0, 0.8); cairo_fill(cr); + cairo_rectangle(cr, allocation.x, allocation.y, + allocation.width, allocation.height); + cairo_clip(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) { if (!dnd->items[i]) @@ -259,6 +269,7 @@ data_source_target(void *data, wl_surface_attach(dnd_drag->drag_surface, buffer, 0, 0); wl_surface_damage(dnd_drag->drag_surface, 0, 0, dnd_drag->width, dnd_drag->height); + wl_surface_commit(dnd_drag->drag_surface); } static void @@ -311,25 +322,27 @@ create_drag_cursor(struct dnd_drag *dnd_drag, struct item *item, int32_t x, int32_t y, double opacity) { struct dnd *dnd = dnd_drag->dnd; - cairo_surface_t *surface, *pointer; - int32_t pointer_width, pointer_height, hotspot_x, hotspot_y; + cairo_surface_t *surface; + struct wl_cursor_image *pointer; struct rectangle rectangle; cairo_pattern_t *pattern; cairo_t *cr; - pointer = display_get_pointer_surface(dnd->display, - POINTER_DRAGGING, - &pointer_width, - &pointer_height, - &hotspot_x, - &hotspot_y); + pointer = display_get_pointer_image(dnd->display, CURSOR_DRAGGING); + if (!pointer) { + fprintf(stderr, "WARNING: grabbing cursor image not found\n"); + pointer = display_get_pointer_image(dnd->display, + CURSOR_LEFT_PTR); + assert(pointer && "no cursor image found"); + } - rectangle.width = item_width + 2 * pointer_width; - rectangle.height = item_height + 2 * pointer_height; - surface = display_create_surface(dnd->display, NULL, &rectangle, 0); + rectangle.width = item_width + 2 * pointer->width; + rectangle.height = item_height + 2 * pointer->height; + surface = display_create_surface(dnd->display, NULL, &rectangle, + SURFACE_SHM); cr = cairo_create(surface); - cairo_translate(cr, pointer_width, pointer_height); + cairo_translate(cr, pointer->width, pointer->height); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 0, 0, 0, 0); @@ -341,17 +354,12 @@ create_drag_cursor(struct dnd_drag *dnd_drag, cairo_mask(cr, pattern); cairo_pattern_destroy(pattern); - cairo_set_source_surface(cr, pointer, - x - item->x - hotspot_x, - y - item->y - hotspot_y); - cairo_surface_destroy(pointer); - cairo_paint(cr); /* FIXME: more cairo-gl brokeness */ surface_flush_device(surface); cairo_destroy(cr); - dnd_drag->hotspot_x = pointer_width + x - item->x; - dnd_drag->hotspot_y = pointer_height + y - item->y; + dnd_drag->hotspot_x = pointer->width + x - item->x; + dnd_drag->hotspot_y = pointer->height + y - item->y; dnd_drag->width = rectangle.width; dnd_drag->height = rectangle.height; @@ -361,7 +369,8 @@ create_drag_cursor(struct dnd_drag *dnd_drag, static void dnd_button_handler(struct widget *widget, struct input *input, uint32_t time, - int button, int state, void *data) + uint32_t button, enum wl_pointer_button_state state, + void *data) { struct dnd *dnd = data; int32_t x, y; @@ -372,6 +381,8 @@ dnd_button_handler(struct widget *widget, struct wl_compositor *compositor; struct wl_buffer *buffer; unsigned int i; + uint32_t serial; + cairo_surface_t *icon; widget_get_allocation(dnd->widget, &allocation); input_get_position(input, &x, &y); @@ -379,7 +390,7 @@ dnd_button_handler(struct widget *widget, x -= allocation.x; y -= allocation.y; - if (item && state == 1) { + if (item && state == WL_POINTER_BUTTON_STATE_PRESSED) { dnd_drag = malloc(sizeof *dnd_drag); dnd_drag->dnd = dnd; dnd_drag->input = input; @@ -397,37 +408,52 @@ dnd_button_handler(struct widget *widget, display = window_get_display(dnd->window); compositor = display_get_compositor(display); + serial = display_get_serial(display); dnd_drag->drag_surface = wl_compositor_create_surface(compositor); - dnd_drag->data_source = - display_create_data_source(dnd->display); - wl_data_source_add_listener(dnd_drag->data_source, - &data_source_listener, - dnd_drag); - wl_data_source_offer(dnd_drag->data_source, - "application/x-wayland-dnd-flower"); - wl_data_source_offer(dnd_drag->data_source, - "text/plain; charset=utf-8"); + input_ungrab(input); + + if (dnd->self_only) { + dnd_drag->data_source = NULL; + } else { + dnd_drag->data_source = + display_create_data_source(dnd->display); + wl_data_source_add_listener(dnd_drag->data_source, + &data_source_listener, + dnd_drag); + wl_data_source_offer(dnd_drag->data_source, + "application/x-wayland-dnd-flower"); + wl_data_source_offer(dnd_drag->data_source, + "text/plain; charset=utf-8"); + } + wl_data_device_start_drag(input_get_data_device(input), dnd_drag->data_source, window_get_wl_surface(dnd->window), dnd_drag->drag_surface, - time); + serial); - input_set_pointer_image(input, time, POINTER_DRAGGING); + input_set_pointer_image(input, CURSOR_DRAGGING); dnd_drag->opaque = create_drag_cursor(dnd_drag, item, x, y, 1); dnd_drag->translucent = create_drag_cursor(dnd_drag, item, x, y, 0.2); - buffer = display_get_buffer_for_surface(dnd->display, dnd_drag->translucent); + if (dnd->self_only) + icon = dnd_drag->opaque; + else + icon = dnd_drag->translucent; + + buffer = display_get_buffer_for_surface(dnd->display, icon); wl_surface_attach(dnd_drag->drag_surface, buffer, -dnd_drag->hotspot_x, -dnd_drag->hotspot_y); wl_surface_damage(dnd_drag->drag_surface, 0, 0, dnd_drag->width, dnd_drag->height); + wl_surface_commit(dnd_drag->drag_surface); + dnd->current_drag = dnd_drag; window_schedule_redraw(dnd->window); } } @@ -439,38 +465,44 @@ lookup_cursor(struct dnd *dnd, int x, int y) item = dnd_get_item(dnd, x, y); if (item) - return POINTER_HAND1; + return CURSOR_HAND1; else - return POINTER_LEFT_PTR; + return CURSOR_LEFT_PTR; } static int dnd_enter_handler(struct widget *widget, - struct input *input, uint32_t time, - int32_t x, int32_t y, void *data) + struct input *input, float x, float y, void *data) { - return lookup_cursor(data, x, y); + struct dnd *dnd = data; + + dnd->current_drag = NULL; + + return lookup_cursor(dnd, x, y); } static int dnd_motion_handler(struct widget *widget, struct input *input, uint32_t time, - int32_t x, int32_t y, void *data) + float x, float y, void *data) { return lookup_cursor(data, x, y); } static void dnd_data_handler(struct window *window, - struct input *input, uint32_t time, - int32_t x, int32_t y, const char **types, void *data) + struct input *input, + float x, float y, const char **types, void *data) { struct dnd *dnd = data; - if (!dnd_get_item(dnd, x, y)) { - input_accept(input, time, types[0]); + if (!types) + return; + + if (dnd_get_item(dnd, x, y) || dnd->self_only) { + input_accept(input, NULL); } else { - input_accept(input, time, NULL); + input_accept(input, types[0]); } } @@ -485,7 +517,7 @@ dnd_receive_func(void *data, size_t len, int32_t x, int32_t y, void *user_data) if (len == 0) { return; } else if (len != sizeof *message) { - fprintf(stderr, "odd message length %ld, expected %ld\n", + fprintf(stderr, "odd message length %zu, expected %zu\n", len, sizeof *message); return; } @@ -505,15 +537,26 @@ dnd_drop_handler(struct window *window, struct input *input, int32_t x, int32_t y, void *data) { struct dnd *dnd = data; + struct dnd_flower_message message; if (dnd_get_item(dnd, x, y)) { fprintf(stderr, "got 'drop', but no target\n"); return; } - input_receive_drag_data(input, - "application/x-wayland-dnd-flower", - dnd_receive_func, dnd); + if (!dnd->self_only) { + input_receive_drag_data(input, + "application/x-wayland-dnd-flower", + dnd_receive_func, dnd); + } else if (dnd->current_drag) { + message.seed = dnd->current_drag->item->seed; + message.x_offset = dnd->current_drag->x_offset; + message.y_offset = dnd->current_drag->y_offset; + dnd_receive_func(&message, sizeof message, x, y, dnd); + dnd->current_drag = NULL; + } else { + fprintf(stderr, "ignoring drop from another client\n"); + } } static struct dnd * @@ -559,7 +602,7 @@ dnd_create(struct display *display) width = 4 * (item_width + item_padding) + item_padding; height = 4 * (item_height + item_padding) + item_padding; - widget_schedule_resize(dnd->widget, width, height); + frame_set_child_size(dnd->widget, width, height); return dnd; } @@ -568,6 +611,8 @@ int main(int argc, char *argv[]) { struct display *d; + struct dnd *dnd; + int i; d = display_create(argc, argv); if (d == NULL) { @@ -575,7 +620,11 @@ main(int argc, char *argv[]) return -1; } - dnd_create(d); + dnd = dnd_create(d); + + for (i = 1; i < argc; i++) + if (strcmp("--self-only", argv[i]) == 0) + dnd->self_only = 1; display_run(d);