[gtk+] wayland: Expose basic mechanism for getting selection content by callback
- From: Rob Bradford <rbradford src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] wayland: Expose basic mechanism for getting selection content by callback
- Date: Fri, 13 Jan 2012 16:52:31 +0000 (UTC)
commit cd795de6bf21107051842062f501094feda96232
Author: Rob Bradford <rob linux intel com>
Date: Wed Dec 14 14:09:52 2011 +0000
wayland: Expose basic mechanism for getting selection content by callback
This version has a couple of TODOs/FIXMEs:
* We should do something better than g_io_channel_read_to_end
* Need to check the mime type is valid
gdk/wayland/gdkdevice-wayland.c | 115 +++++++++++++++++++++++++++++++++++++++
gdk/wayland/gdkwayland.h | 13 ++++-
2 files changed, 127 insertions(+), 1 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 73601db..f25c157 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -17,6 +17,11 @@
* Boston, MA 02111-1307, USA.
*/
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
#include "config.h"
#include <string.h>
@@ -32,6 +37,8 @@
#include <X11/extensions/XKBcommon.h>
#include <X11/keysym.h>
+#include <sys/time.h>
+
#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ())
#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore))
#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
@@ -956,3 +963,111 @@ gdk_wayland_device_get_selection_type_atoms (GdkDevice *gdk_device,
*atoms_out = atoms;
return device->selection_offer->types->len;
}
+
+typedef struct
+{
+ GdkWaylandDevice *device;
+ DataOffer *offer;
+ GIOChannel *channel;
+ GdkDeviceWaylandRequestContentCallback cb;
+ gpointer userdata;
+} RequestContentClosure;
+
+static gboolean
+_request_content_io_func (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer userdata)
+{
+ RequestContentClosure *closure = (RequestContentClosure *)userdata;
+ gchar *data = NULL;
+ gsize len = 0;
+ GError *error = NULL;
+
+ /* FIXME: We probably want to do something better than this to avoid
+ * blocking on the transfer of large pieces of data: call the callback
+ * multiple times I should think.
+ */
+ if (g_io_channel_read_to_end (channel,
+ &data,
+ &len,
+ &error) != G_IO_STATUS_NORMAL)
+ {
+ g_warning (G_STRLOC ": Error reading content from pipe: %s", error->message);
+ g_clear_error (&error);
+ }
+
+ /* Since we use _read_to_end we've got a guaranteed EOF and thus can go
+ * ahead and close the fd
+ */
+ g_io_channel_shutdown (channel, TRUE, NULL);
+
+ closure->cb (closure->device->pointer, data, len, closure->userdata);
+
+ data_offer_unref (closure->offer);
+ g_io_channel_unref (channel);
+ g_free (closure);
+
+ return FALSE;
+}
+
+gboolean
+gdk_wayland_device_request_selection_content (GdkDevice *gdk_device,
+ const gchar *requested_mime_type,
+ GdkDeviceWaylandRequestContentCallback cb,
+ gpointer userdata)
+{
+ int pipe_fd[2];
+ RequestContentClosure *closure;
+ GdkWaylandDevice *device;
+ GError *error = NULL;
+
+ g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), FALSE);
+ g_return_val_if_fail (requested_mime_type != NULL, FALSE);
+ g_return_val_if_fail (cb != NULL, FALSE);
+
+ device = GDK_DEVICE_CORE (gdk_device)->device;
+
+ if (!device->selection_offer)
+ return FALSE;
+
+ /* TODO: Check mimetypes */
+
+ closure = g_new0 (RequestContentClosure, 1);
+
+ device->selection_offer->ref_count++;
+
+ pipe2 (pipe_fd, O_CLOEXEC);
+ wl_data_offer_receive (device->selection_offer->offer,
+ requested_mime_type,
+ pipe_fd[1]);
+ close (pipe_fd[1]);
+
+ closure->device = device;
+ closure->offer = device->selection_offer;
+ closure->channel = g_io_channel_unix_new (pipe_fd[0]);
+ closure->cb = cb;
+ closure->userdata = userdata;
+
+ if (!g_io_channel_set_encoding (closure->channel, NULL, &error))
+ {
+ g_warning (G_STRLOC ": Error setting encoding on channel: %s",
+ error->message);
+ g_clear_error (&error);
+ goto error;
+ }
+
+ g_io_add_watch (closure->channel,
+ G_IO_IN,
+ _request_content_io_func,
+ closure);
+
+ return TRUE;
+
+error:
+ data_offer_unref (closure->offer);
+ g_io_channel_unref (closure->channel);
+ close (pipe_fd[1]);
+ g_free (closure);
+
+ return FALSE;
+}
diff --git a/gdk/wayland/gdkwayland.h b/gdk/wayland/gdkwayland.h
index d4616cd..e7028cd 100644
--- a/gdk/wayland/gdkwayland.h
+++ b/gdk/wayland/gdkwayland.h
@@ -37,7 +37,18 @@ GType gdk_wayland_display_manager_get_type (void);
#define gdk_wayland_device_get_selection_type_atoms gdk_wayland_device_get_selection_type_atoms_libgtk_only
int
gdk_wayland_device_get_selection_type_atoms (GdkDevice *device,
- GdkAtom **atoms_out);
+ GdkAtom **atoms_out);
+
+typedef void (*GdkDeviceWaylandRequestContentCallback) (GdkDevice *device, gchar *data, gsize len, gpointer userdata);
+
+#define gdk_wayland_device_request_selection_content gdk_wayland_device_request_selection_content_libgtk_only
+gboolean
+gdk_wayland_device_request_selection_content (GdkDevice *device,
+ const gchar *requested_mime_type,
+ GdkDeviceWaylandRequestContentCallback cb,
+ gpointer userdata);
+
+
#endif
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]