X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fwayland%2Fgdkdevice-wayland.c;h=7381d217b920b9b5702d37780c1b28058038bc5b;hb=9d0febc9a64a5bfb0fcfc3a88de4757f6c1ff090;hp=c7ea5aa8f41f7c06caf09d5ffb9b94dffbc423c4;hpb=368d6c50b71e3fa2b6052c4a6549c81923521e2d;p=~andy%2Fgtk diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index c7ea5aa8f..7381d217b 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ #define _GNU_SOURCE @@ -68,6 +66,9 @@ struct _GdkWaylandDevice uint32_t time; GdkWindow *pointer_grab_window; uint32_t pointer_grab_time; + guint32 repeat_timer; + guint32 repeat_key; + guint32 repeat_count; DataOffer *drag_offer; DataOffer *selection_offer; @@ -375,6 +376,19 @@ input_handle_button(void *data, struct wl_input_device *input_device, GdkDisplayWayland *display = GDK_DISPLAY_WAYLAND (device->display); GdkEvent *event; uint32_t modifier; + int gdk_button; + + switch (button) { + case 273: + gdk_button = 3; + break; + case 274: + gdk_button = 2; + break; + default: + gdk_button = button - 271; + break; + } device->time = time; event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); @@ -387,10 +401,10 @@ input_handle_button(void *data, struct wl_input_device *input_device, event->button.y_root = (gdouble) device->y; event->button.axes = NULL; event->button.state = device->modifiers; - event->button.button = button - 271; + event->button.button = gdk_button; gdk_event_set_screen (event, display->screen); - modifier = 1 << (8 + button - 272); + modifier = 1 << (8 + gdk_button - 1); if (state) device->modifiers |= modifier; else @@ -468,11 +482,13 @@ translate_keyboard_string (GdkEventKey *event) } } -static void -input_handle_key(void *data, struct wl_input_device *input_device, - uint32_t time, uint32_t key, uint32_t state) +static gboolean +keyboard_repeat (gpointer data); + +static gboolean +deliver_key_event(GdkWaylandDevice *device, + uint32_t time, uint32_t key, uint32_t state) { - GdkWaylandDevice *device = data; GdkEvent *event; uint32_t code, modifier, level; struct xkb_desc *xkb; @@ -515,6 +531,60 @@ input_handle_key(void *data, struct wl_input_device *input_device, "string %s, mods 0x%x", code, event->key.keyval, event->key.string, event->key.state)); + + device->repeat_count++; + device->repeat_key = key; + + if (state == 0) + { + if (device->repeat_timer) + { + g_source_remove (device->repeat_timer); + device->repeat_timer = 0; + } + return FALSE; + } + else if (modifier) + { + return FALSE; + } + else switch (device->repeat_count) + { + case 1: + if (device->repeat_timer) + { + g_source_remove (device->repeat_timer); + device->repeat_timer = 0; + } + + device->repeat_timer = + gdk_threads_add_timeout (400, keyboard_repeat, device); + return TRUE; + case 2: + device->repeat_timer = + gdk_threads_add_timeout (80, keyboard_repeat, device); + return FALSE; + default: + return TRUE; + } +} + +static gboolean +keyboard_repeat (gpointer data) +{ + GdkWaylandDevice *device = data; + + return deliver_key_event (device, device->time, device->repeat_key, 1); +} + +static void +input_handle_key(void *data, struct wl_input_device *input_device, + uint32_t time, uint32_t key, uint32_t state) +{ + GdkWaylandDevice *device = data; + + device->repeat_count = 0; + deliver_key_event (data, time, key, state); } static void @@ -616,6 +686,7 @@ input_handle_keyboard_focus(void *data, device->time = time; if (device->keyboard_focus) { + _gdk_wayland_window_remove_focus (device->keyboard_focus); event = gdk_event_new (GDK_FOCUS_CHANGE); event->focus_change.window = g_object_ref (device->keyboard_focus); event->focus_change.send_event = FALSE; @@ -650,6 +721,8 @@ input_handle_keyboard_focus(void *data, device, device->keyboard_focus)); _gdk_wayland_display_deliver_event (device->display, event); + + _gdk_wayland_window_add_focus (device->keyboard_focus); } } @@ -787,6 +860,17 @@ data_device_selection (void *data, g_debug (G_STRLOC ": %s wl_data_device = %p wl_data_offer = %p", G_STRFUNC, wl_data_device, offer); + if (!offer) + { + if (device->selection_offer) + { + data_offer_unref (device->selection_offer); + device->selection_offer = NULL; + } + + return; + } + if (device->selection_offer) { data_offer_unref (device->selection_offer); @@ -946,7 +1030,7 @@ gdk_wayland_device_get_selection_type_atoms (GdkDevice *gdk_device, device = GDK_DEVICE_CORE (gdk_device)->device; - if (device->selection_offer->types->len == 0) + if (!device->selection_offer || device->selection_offer->types->len == 0) { *atoms_out = NULL; return 0; @@ -1007,6 +1091,7 @@ _request_content_io_func (GIOChannel *channel, closure->cb (closure->device->pointer, data, len, closure->userdata); + g_free (data); data_offer_unref (closure->offer); g_io_channel_unref (channel); g_free (closure); @@ -1099,8 +1184,8 @@ data_source_send (void *data, int32_t fd) { GdkWaylandSelectionOffer *offer = (GdkWaylandSelectionOffer *)data;; - const gchar *buf; - gssize len, bytes_written; + gchar *buf; + gssize len, bytes_written = 0; g_debug (G_STRLOC ": %s source = %p, mime_type = %s fd = %d", G_STRFUNC, source, mime_type, fd); @@ -1109,13 +1194,14 @@ data_source_send (void *data, while (len > 0) { - bytes_written = write (fd, buf, len); + bytes_written += write (fd, buf + bytes_written, len); if (bytes_written == -1) goto error; len -= bytes_written; } close (fd); + g_free (buf); return; error: @@ -1124,6 +1210,7 @@ error: g_strerror (errno)); close (fd); + g_free (buf); } static void