]> Pileus Git - ~andy/gtk/blobdiff - gdk/wayland/gdkdevice-wayland.c
Change FSF Address
[~andy/gtk] / gdk / wayland / gdkdevice-wayland.c
index c7ea5aa8f41f7c06caf09d5ffb9b94dffbc423c4..7381d217b920b9b5702d37780c1b28058038bc5b 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
  */
 
 #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