[Spice-devel] [RFC spice-vdagent 4/8] build: make GTK+ mandatory
Victor Toso
victortoso at redhat.com
Thu Aug 9 13:35:52 UTC 2018
Hi,
On Thu, May 31, 2018 at 10:52:21PM +0200, Jakub Janků wrote:
> Use GTK+ instead of Xlib where possible,
> remove Xlib code that handles clipboard.
@teuf, double checking here if you think requiring gtk and
dropping xlib would be a problem.
With possible problems in mind I asked gtk to be optional at
build time for the 0.18.0 release but I don't see much point in
working in features in gtk and x11 so I'd say this is fine.
Cheers,
Victor
> ---
> configure.ac | 13 +-
> src/vdagent/clipboard.c | 49 +-
> src/vdagent/clipboard.h | 4 +-
> src/vdagent/vdagent.c | 14 +-
> src/vdagent/x11-priv.h | 94 ----
> src/vdagent/x11.c | 1177 +--------------------------------------
> src/vdagent/x11.h | 18 +-
> 7 files changed, 21 insertions(+), 1348 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 89f617c..1eb17a9 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -75,16 +75,6 @@ if test "x$init_systemd" = "xyes"; then
> fi
> fi
>
> -AC_ARG_WITH([gtk],
> - [AS_HELP_STRING([--with-gtk], [Use GTK+ instead of Xlib])],
> - [],
> - [with_gtk="auto"])
> -if test "x$with_gtk" != "xno"; then
> - PKG_CHECK_MODULES([GTK], [gtk+-3.0 >= 3.10],
> - [AC_DEFINE([WITH_GTK], [1], [If defined, vdagent will favor GTK+ over Xlib])],
> - [AS_IF([test "x$with_gtk" = "xyes"], [AC_MSG_ERROR([GTK+ requested but not found])])])
> -fi
> -
> AC_ARG_ENABLE([pciaccess],
> [AS_HELP_STRING([--enable-pciaccess], [Enable libpciaccess use for auto generation of Xinerama xorg.conf (default: yes)])],
> [enable_pciaccess="$enableval"],
> @@ -96,6 +86,7 @@ AC_ARG_ENABLE([static-uinput],
> [enable_static_uinput="no"])
>
> PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.34])
> +PKG_CHECK_MODULES([GTK], [gtk+-3.0 >= 3.10])
> PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11])
> PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.13])
> PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.22])
> @@ -219,8 +210,6 @@ AC_MSG_NOTICE([
> install systemd service: ${init_systemd}
> udevdir: ${udevdir}
>
> - use GTK+: ${with_gtk}
> -
> Now type 'make' to build $PACKAGE
>
> ])
> diff --git a/src/vdagent/clipboard.c b/src/vdagent/clipboard.c
> index 667c168..101e535 100644
> --- a/src/vdagent/clipboard.c
> +++ b/src/vdagent/clipboard.c
> @@ -20,17 +20,14 @@
> # include <config.h>
> #endif
>
> -#ifdef WITH_GTK
> -# include <gtk/gtk.h>
> -# include <syslog.h>
> +#include <gtk/gtk.h>
> +#include <syslog.h>
>
> -# include "vdagentd-proto.h"
> -# include "spice/vd_agent.h"
> -#endif
> +#include "vdagentd-proto.h"
> +#include "spice/vd_agent.h"
>
> #include "clipboard.h"
>
> -#ifdef WITH_GTK
> /* 2 selections supported - _SELECTION_CLIPBOARD = 0, _SELECTION_PRIMARY = 1 */
> #define SELECTION_COUNT (VD_AGENT_CLIPBOARD_SELECTION_PRIMARY + 1)
> #define TYPE_COUNT (VD_AGENT_CLIPBOARD_IMAGE_JPG + 1)
> @@ -59,18 +56,12 @@ typedef struct {
>
> GdkAtom targets[TYPE_COUNT];
> } Selection;
> -#endif
>
> struct VDAgentClipboards {
> -#ifdef WITH_GTK
> struct udscs_connection *conn;
> Selection selections[SELECTION_COUNT];
> -#else
> - struct vdagent_x11 *x11;
> -#endif
> };
>
> -#ifdef WITH_GTK
> static const struct {
> guint type;
> const gchar *atom_name;
> @@ -298,14 +289,10 @@ static void clipboard_clear_cb(GtkClipboard *clipboard, gpointer user_data)
> VDAgentClipboards *c = user_data;
> clipboard_new_owner(c, sel_id_from_clip(clipboard), OWNER_NONE);
> }
> -#endif
>
> void vdagent_clipboard_grab(VDAgentClipboards *c, guint sel_id,
> guint32 *types, guint n_types)
> {
> -#ifndef WITH_GTK
> - vdagent_x11_clipboard_grab(c->x11, sel_id, types, n_types);
> -#else
> GtkTargetEntry targets[G_N_ELEMENTS(atom2agent)];
> guint n_targets, i, t;
>
> @@ -333,15 +320,11 @@ void vdagent_clipboard_grab(VDAgentClipboards *c, guint sel_id,
> syslog(LOG_ERR, "%s: sel_id=%u: clipboard grab failed", __func__, sel_id);
> clipboard_new_owner(c, sel_id, OWNER_NONE);
> }
> -#endif
> }
>
> void vdagent_clipboard_data(VDAgentClipboards *c, guint sel_id,
> guint type, guchar *data, guint size)
> {
> -#ifndef WITH_GTK
> - vdagent_x11_clipboard_data(c->x11, sel_id, type, data, size);
> -#else
> g_return_if_fail(sel_id < SELECTION_COUNT);
> Selection *sel = &c->selections[sel_id];
> AppRequest *req;
> @@ -364,28 +347,20 @@ void vdagent_clipboard_data(VDAgentClipboards *c, guint sel_id,
> 8, data, size);
>
> g_main_loop_quit(req->loop);
> -#endif
> }
>
> void vdagent_clipboard_release(VDAgentClipboards *c, guint sel_id)
> {
> -#ifndef WITH_GTK
> - vdagent_x11_clipboard_release(c->x11, sel_id);
> -#else
> g_return_if_fail(sel_id < SELECTION_COUNT);
> if (c->selections[sel_id].owner != OWNER_CLIENT)
> return;
>
> clipboard_new_owner(c, sel_id, OWNER_NONE);
> gtk_clipboard_clear(c->selections[sel_id].clipboard);
> -#endif
> }
>
> void vdagent_clipboards_release_all(VDAgentClipboards *c)
> {
> -#ifndef WITH_GTK
> - vdagent_x11_client_disconnected(c->x11);
> -#else
> guint sel_id, owner;
>
> for (sel_id = 0; sel_id < SELECTION_COUNT; sel_id++) {
> @@ -396,14 +371,10 @@ void vdagent_clipboards_release_all(VDAgentClipboards *c)
> else if (owner == OWNER_GUEST && c->conn)
> udscs_write(c->conn, VDAGENTD_CLIPBOARD_RELEASE, sel_id, 0, NULL, 0);
> }
> -#endif
> }
>
> void vdagent_clipboard_request(VDAgentClipboards *c, guint sel_id, guint type)
> {
> -#ifndef WITH_GTK
> - vdagent_x11_clipboard_request(c->x11, sel_id, type);
> -#else
> Selection *sel;
>
> if (sel_id >= SELECTION_COUNT)
> @@ -428,25 +399,18 @@ void vdagent_clipboard_request(VDAgentClipboards *c, guint sel_id, guint type)
> err:
> udscs_write(c->conn, VDAGENTD_CLIPBOARD_DATA, sel_id,
> VD_AGENT_CLIPBOARD_NONE, NULL, 0);
> -#endif
> }
>
> -VDAgentClipboards *vdagent_clipboards_init(struct vdagent_x11 *x11,
> - struct udscs_connection *conn)
> +VDAgentClipboards *vdagent_clipboards_init(struct udscs_connection *conn)
> {
> -#ifdef WITH_GTK
> guint sel_id;
> const GdkAtom sel_atom[SELECTION_COUNT] = {
> GDK_SELECTION_CLIPBOARD, /* VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD */
> GDK_SELECTION_PRIMARY, /* VD_AGENT_CLIPBOARD_SELECTION_PRIMARY */
> };
> -#endif
>
> VDAgentClipboards *c;
> c = g_new0(VDAgentClipboards, 1);
> -#ifndef WITH_GTK
> - c->x11 = x11;
> -#else
> c->conn = conn;
>
> for (sel_id = 0; sel_id < SELECTION_COUNT; sel_id++) {
> @@ -458,14 +422,12 @@ VDAgentClipboards *vdagent_clipboards_init(struct vdagent_x11 *x11,
> g_signal_connect(G_OBJECT(clipboard), "owner-change",
> G_CALLBACK(clipboard_owner_change_cb), c);
> }
> -#endif
>
> return c;
> }
>
> void vdagent_clipboards_finalize(VDAgentClipboards *c, gboolean conn_alive)
> {
> -#ifdef WITH_GTK
> guint sel_id;
> for (sel_id = 0; sel_id < SELECTION_COUNT; sel_id++)
> g_signal_handlers_disconnect_by_func(c->selections[sel_id].clipboard,
> @@ -474,7 +436,6 @@ void vdagent_clipboards_finalize(VDAgentClipboards *c, gboolean conn_alive)
> if (conn_alive == FALSE)
> c->conn = NULL;
> vdagent_clipboards_release_all(c);
> -#endif
>
> g_free(c);
> }
> diff --git a/src/vdagent/clipboard.h b/src/vdagent/clipboard.h
> index f819b49..e007a37 100644
> --- a/src/vdagent/clipboard.h
> +++ b/src/vdagent/clipboard.h
> @@ -21,13 +21,11 @@
>
> #include <glib.h>
>
> -#include "x11.h"
> #include "udscs.h"
>
> typedef struct VDAgentClipboards VDAgentClipboards;
>
> -VDAgentClipboards *vdagent_clipboards_init(struct vdagent_x11 *x11,
> - struct udscs_connection *conn);
> +VDAgentClipboards *vdagent_clipboards_init(struct udscs_connection *conn);
> void vdagent_clipboards_finalize(VDAgentClipboards *c, gboolean conn_alive);
>
> void vdagent_clipboard_request(VDAgentClipboards *c, guint sel_id, guint type);
> diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
> index 3f8ef31..711e4f8 100644
> --- a/src/vdagent/vdagent.c
> +++ b/src/vdagent/vdagent.c
> @@ -36,9 +36,7 @@
> #include <spice/vd_agent.h>
> #include <poll.h>
> #include <glib-unix.h>
> -#ifdef WITH_GTK
> -# include <gtk/gtk.h>
> -#endif
> +#include <gtk/gtk.h>
>
> #include "udscs.h"
> #include "vdagentd-proto.h"
> @@ -113,7 +111,7 @@ static const gchar *xfer_get_download_directory(VDAgent *agent)
> return fx_dir;
> }
>
> - return g_get_user_special_dir(vdagent_x11_has_icons_on_desktop(agent->x11) ?
> + return g_get_user_special_dir(vdagent_x11_has_icons_on_desktop() ?
> G_USER_DIRECTORY_DESKTOP :
> G_USER_DIRECTORY_DOWNLOAD);
> }
> @@ -143,7 +141,7 @@ static gboolean vdagent_init_file_xfer(VDAgent *agent)
> }
>
> open_dir = fx_open_dir == -1 ?
> - !vdagent_x11_has_icons_on_desktop(agent->x11) :
> + !vdagent_x11_has_icons_on_desktop() :
> fx_open_dir;
>
> agent->xfers = vdagent_file_xfers_create(agent->conn, xfer_dir,
> @@ -391,7 +389,7 @@ static gboolean vdagent_init_async_cb(gpointer user_data)
> if (!vdagent_init_file_xfer(agent))
> syslog(LOG_WARNING, "File transfer is disabled");
>
> - agent->clipboards = vdagent_clipboards_init(agent->x11, agent->conn);
> + agent->clipboards = vdagent_clipboards_init(agent->conn);
>
> if (parent_socket != -1) {
> if (write(parent_socket, "OK", 2) != 2)
> @@ -419,9 +417,7 @@ int main(int argc, char *argv[])
> g_option_context_set_summary(context,
> "\tSpice session guest agent: X11\n"
> "\tVersion: " VERSION);
> -#ifdef WITH_GTK
> g_option_context_add_group(context, gtk_get_option_group(FALSE));
> -#endif
> g_option_context_parse(context, &argc, &argv, &error);
> g_option_context_free(context);
>
> @@ -449,10 +445,8 @@ int main(int argc, char *argv[])
> if (do_daemonize)
> parent_socket = daemonize();
>
> -#ifdef WITH_GTK
> gdk_set_allowed_backends("x11");
> gtk_init(NULL, NULL);
> -#endif
>
> reconnect:
> if (version_mismatch) {
> diff --git a/src/vdagent/x11-priv.h b/src/vdagent/x11-priv.h
> index e7c64bd..f341048 100644
> --- a/src/vdagent/x11-priv.h
> +++ b/src/vdagent/x11-priv.h
> @@ -1,10 +1,6 @@
> #ifndef VDAGENT_X11_PRIV
> #define VDAGENT_X11_PRIV
>
> -#ifdef HAVE_CONFIG_H
> -# include <config.h>
> -#endif
> -
> #include <stdint.h>
> #include <stdio.h>
>
> @@ -12,66 +8,6 @@
>
> #include <X11/extensions/Xrandr.h>
>
> -#ifndef WITH_GTK
> -/* Macros to print a message to the logfile prefixed by the selection */
> -#define SELPRINTF(format, ...) \
> - syslog(LOG_ERR, "%s: " format, \
> - vdagent_x11_sel_to_str(selection), ##__VA_ARGS__)
> -
> -#define VSELPRINTF(format, ...) \
> - do { \
> - if (x11->debug) { \
> - syslog(LOG_DEBUG, "%s: " format, \
> - vdagent_x11_sel_to_str(selection), ##__VA_ARGS__); \
> - } \
> - } while (0)
> -
> -enum { owner_none, owner_guest, owner_client };
> -
> -/* X11 terminology is confusing a selection request is a request from an
> - app to get clipboard data from us, so iow from the spice client through
> - the vdagent channel. We handle these one at a time and queue any which
> - come in while we are still handling the current one. */
> -struct vdagent_x11_selection_request {
> - XEvent event;
> - uint8_t selection;
> - struct vdagent_x11_selection_request *next;
> -};
> -
> -/* A conversion request is X11 speak for asking another app to give its
> - clipboard data to us, we do these on behalf of the spice client to copy
> - data from the guest to the client. Like selection requests we process
> - these one at a time. */
> -struct vdagent_x11_conversion_request {
> - Atom target;
> - uint8_t selection;
> - struct vdagent_x11_conversion_request *next;
> -};
> -
> -struct clipboard_format_tmpl {
> - uint32_t type;
> - const char *atom_names[16];
> -};
> -
> -struct clipboard_format_info {
> - uint32_t type;
> - Atom atoms[16];
> - int atom_count;
> -};
> -
> -static const struct clipboard_format_tmpl clipboard_format_templates[] = {
> - { VD_AGENT_CLIPBOARD_UTF8_TEXT, { "UTF8_STRING", "text/plain;charset=UTF-8",
> - "text/plain;charset=utf-8", "STRING", NULL }, },
> - { VD_AGENT_CLIPBOARD_IMAGE_PNG, { "image/png", NULL }, },
> - { VD_AGENT_CLIPBOARD_IMAGE_BMP, { "image/bmp", "image/x-bmp",
> - "image/x-MS-bmp", "image/x-win-bitmap", NULL }, },
> - { VD_AGENT_CLIPBOARD_IMAGE_TIFF, { "image/tiff", NULL }, },
> - { VD_AGENT_CLIPBOARD_IMAGE_JPG, { "image/jpeg", NULL }, },
> -};
> -
> -#define clipboard_format_count (sizeof(clipboard_format_templates)/sizeof(clipboard_format_templates[0]))
> -#endif
> -
> #define MAX_SCREENS 16
> /* Same as qxl_dev.h client_monitors_config.heads count */
> #define MONITOR_SIZE_COUNT 64
> @@ -83,36 +19,6 @@ struct monitor_size {
>
> struct vdagent_x11 {
> Display *display;
> -#ifndef WITH_GTK
> - struct clipboard_format_info clipboard_formats[clipboard_format_count];
> - Atom clipboard_atom;
> - Atom clipboard_primary_atom;
> - Atom targets_atom;
> - Atom incr_atom;
> - Atom multiple_atom;
> - Atom timestamp_atom;
> - Window selection_window;
> - int has_xfixes;
> - int xfixes_event_base;
> - int max_prop_size;
> - int expected_targets_notifies[256];
> - int clipboard_owner[256];
> - int clipboard_type_count[256];
> - uint32_t clipboard_agent_types[256][256];
> - Atom clipboard_x11_targets[256][256];
> - /* Data for conversion_req which is currently being processed */
> - struct vdagent_x11_conversion_request *conversion_req;
> - int expect_property_notify;
> - uint8_t *clipboard_data;
> - uint32_t clipboard_data_size;
> - uint32_t clipboard_data_space;
> - /* Data for selection_req which is currently being processed */
> - struct vdagent_x11_selection_request *selection_req;
> - uint8_t *selection_req_data;
> - uint32_t selection_req_data_pos;
> - uint32_t selection_req_data_size;
> - Atom selection_req_atom;
> -#endif
> Window root_window[MAX_SCREENS];
> struct udscs_connection *vdagentd;
> int debug;
> diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c
> index 0ea5668..a9ab699 100644
> --- a/src/vdagent/x11.c
> +++ b/src/vdagent/x11.c
> @@ -36,12 +36,10 @@
> #endif
>
> #include <glib.h>
> -#ifdef WITH_GTK
> #include <gdk/gdk.h>
> #ifdef GDK_WINDOWING_X11
> #include <gdk/gdkx.h>
> #endif
> -#endif
> #include <stdlib.h>
> #include <limits.h>
> #include <string.h>
> @@ -50,7 +48,6 @@
> #include <unistd.h>
> #include <X11/Xatom.h>
> #include <X11/Xlib.h>
> -#include <X11/extensions/Xfixes.h>
> #include "vdagentd-proto.h"
> #include "x11.h"
> #include "x11-priv.h"
> @@ -59,52 +56,12 @@
> int (*vdagent_x11_prev_error_handler)(Display *, XErrorEvent *);
> int vdagent_x11_caught_error;
>
> -#ifndef WITH_GTK
> -static void vdagent_x11_handle_selection_notify(struct vdagent_x11 *x11,
> - XEvent *event, int incr);
> -static void vdagent_x11_handle_selection_request(struct vdagent_x11 *x11);
> -static void vdagent_x11_handle_targets_notify(struct vdagent_x11 *x11,
> - XEvent *event);
> -static void vdagent_x11_handle_property_delete_notify(struct vdagent_x11 *x11,
> - XEvent *del_event);
> -static void vdagent_x11_send_selection_notify(struct vdagent_x11 *x11,
> - Atom prop, struct vdagent_x11_selection_request *request);
> -static void vdagent_x11_set_clipboard_owner(struct vdagent_x11 *x11,
> - uint8_t selection, int new_owner);
> -
> -static const char *vdagent_x11_sel_to_str(uint8_t selection) {
> - switch (selection) {
> - case VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD:
> - return "clipboard";
> - case VD_AGENT_CLIPBOARD_SELECTION_PRIMARY:
> - return "primary";
> - case VD_AGENT_CLIPBOARD_SELECTION_SECONDARY:
> - return "secondary";
> - default:
> - return "unknown";
> - }
> -}
> -#endif
> -
> static int vdagent_x11_debug_error_handler(
> Display *display, XErrorEvent *error)
> {
> abort();
> }
>
> -#ifndef WITH_GTK
> -/* With the clipboard we're sometimes dealing with Properties on another apps
> - Window. which can go away at any time. */
> -static int vdagent_x11_ignore_bad_window_handler(
> - Display *display, XErrorEvent *error)
> -{
> - if (error->error_code == BadWindow)
> - return 0;
> -
> - return vdagent_x11_prev_error_handler(display, error);
> -}
> -#endif
> -
> void vdagent_x11_set_error_handler(struct vdagent_x11 *x11,
> int (*handler)(Display *, XErrorEvent *))
> {
> @@ -125,77 +82,15 @@ int vdagent_x11_restore_error_handler(struct vdagent_x11 *x11)
> return error;
> }
>
> -static gchar *vdagent_x11_get_wm_name(struct vdagent_x11 *x11)
> +static const gchar *vdagent_x11_get_wm_name()
> {
> #ifdef GDK_WINDOWING_X11
> GdkDisplay *display = gdk_display_get_default();
> if (GDK_IS_X11_DISPLAY(display))
> - return g_strdup(gdk_x11_screen_get_window_manager_name(
> - gdk_display_get_default_screen(display)));
> - return g_strdup("unsupported");
> -#else
> - Atom type_ret;
> - int format_ret;
> - unsigned long len, remain;
> - unsigned char *data = NULL;
> - Window sup_window = None;
> - gchar *net_wm_name = NULL;
> -
> - /* XGetWindowProperty can throw a BadWindow error. One way we can trigger
> - this is when the display-manager (ie gdm) has set, and not cleared the
> - _NET_SUPPORTING_WM_CHECK property, and the window manager running in
> - the user session has not yet updated it to point to its window, so its
> - pointing to a nonexistent window. */
> - vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler);
> -
> - /* Get the window manager SUPPORTING_WM_CHECK window */
> - if (XGetWindowProperty(x11->display, x11->root_window[0],
> - XInternAtom(x11->display, "_NET_SUPPORTING_WM_CHECK", False), 0,
> - LONG_MAX, False, XA_WINDOW, &type_ret, &format_ret, &len,
> - &remain, &data) == Success) {
> - if (type_ret == XA_WINDOW)
> - sup_window = *((Window *)data);
> - XFree(data);
> - }
> - if (sup_window == None &&
> - XGetWindowProperty(x11->display, x11->root_window[0],
> - XInternAtom(x11->display, "_WIN_SUPPORTING_WM_CHECK", False), 0,
> - LONG_MAX, False, XA_CARDINAL, &type_ret, &format_ret, &len,
> - &remain, &data) == Success) {
> - if (type_ret == XA_CARDINAL)
> - sup_window = *((Window *)data);
> - XFree(data);
> - }
> - /* So that we can get the net_wm_name */
> - if (sup_window != None) {
> - Atom utf8 = XInternAtom(x11->display, "UTF8_STRING", False);
> - if (XGetWindowProperty(x11->display, sup_window,
> - XInternAtom(x11->display, "_NET_WM_NAME", False), 0,
> - LONG_MAX, False, utf8, &type_ret, &format_ret, &len,
> - &remain, &data) == Success) {
> - if (type_ret == utf8) {
> - net_wm_name = g_strndup((char *)data, (format_ret / 8) * len);
> - }
> - XFree(data);
> - }
> - if (net_wm_name == NULL &&
> - XGetWindowProperty(x11->display, sup_window,
> - XInternAtom(x11->display, "_NET_WM_NAME", False), 0,
> - LONG_MAX, False, XA_STRING, &type_ret, &format_ret, &len,
> - &remain, &data) == Success) {
> - if (type_ret == XA_STRING) {
> - net_wm_name = g_strndup((char *)data, (format_ret / 8) * len);
> - }
> - XFree(data);
> - }
> - }
> -
> - vdagent_x11_restore_error_handler(x11);
> -
> - if (net_wm_name == NULL)
> - return g_strdup("unknown");
> - return net_wm_name;
> + return gdk_x11_screen_get_window_manager_name(
> + gdk_display_get_default_screen(display));
> #endif
> + return "unsupported";
> }
>
> struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
> @@ -203,12 +98,8 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
> {
> struct vdagent_x11 *x11;
> XWindowAttributes attrib;
> -#ifdef WITH_GTK
> int i;
> -#else
> - int i, j, major, minor;
> -#endif
> - gchar *net_wm_name = NULL;
> + const gchar *net_wm_name;
>
> x11 = calloc(1, sizeof(*x11));
> if (!x11) {
> @@ -243,61 +134,9 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
> for (i = 0; i < x11->screen_count; i++)
> x11->root_window[i] = RootWindow(x11->display, i);
> x11->fd = ConnectionNumber(x11->display);
> -#ifndef WITH_GTK
> - x11->clipboard_atom = XInternAtom(x11->display, "CLIPBOARD", False);
> - x11->clipboard_primary_atom = XInternAtom(x11->display, "PRIMARY", False);
> - x11->targets_atom = XInternAtom(x11->display, "TARGETS", False);
> - x11->incr_atom = XInternAtom(x11->display, "INCR", False);
> - x11->multiple_atom = XInternAtom(x11->display, "MULTIPLE", False);
> - x11->timestamp_atom = XInternAtom(x11->display, "TIMESTAMP", False);
> - for(i = 0; i < clipboard_format_count; i++) {
> - x11->clipboard_formats[i].type = clipboard_format_templates[i].type;
> - for(j = 0; clipboard_format_templates[i].atom_names[j]; j++) {
> - x11->clipboard_formats[i].atoms[j] =
> - XInternAtom(x11->display,
> - clipboard_format_templates[i].atom_names[j],
> - False);
> - }
> - x11->clipboard_formats[i].atom_count = j;
> - }
> -
> - /* We should not store properties (for selections) on the root window */
> - x11->selection_window = XCreateSimpleWindow(x11->display, x11->root_window[0],
> - 0, 0, 1, 1, 0, 0, 0);
> - if (x11->debug)
> - syslog(LOG_DEBUG, "Selection window: %u", (int)x11->selection_window);
> -#endif
>
> vdagent_x11_randr_init(x11);
>
> -#ifndef WITH_GTK
> - if (XFixesQueryExtension(x11->display, &x11->xfixes_event_base, &i) &&
> - XFixesQueryVersion(x11->display, &major, &minor) && major >= 1) {
> - x11->has_xfixes = 1;
> - XFixesSelectSelectionInput(x11->display, x11->root_window[0],
> - x11->clipboard_atom,
> - XFixesSetSelectionOwnerNotifyMask|
> - XFixesSelectionWindowDestroyNotifyMask|
> - XFixesSelectionClientCloseNotifyMask);
> - XFixesSelectSelectionInput(x11->display, x11->root_window[0],
> - x11->clipboard_primary_atom,
> - XFixesSetSelectionOwnerNotifyMask|
> - XFixesSelectionWindowDestroyNotifyMask|
> - XFixesSelectionClientCloseNotifyMask);
> - } else
> - syslog(LOG_ERR, "no xfixes, no guest -> client copy paste support");
> -
> - x11->max_prop_size = XExtendedMaxRequestSize(x11->display);
> - if (x11->max_prop_size) {
> - x11->max_prop_size -= 100;
> - } else {
> - x11->max_prop_size = XMaxRequestSize(x11->display) - 100;
> - }
> - /* Be a good X11 citizen and maximize the amount of data we send at once */
> - if (x11->max_prop_size > 262144)
> - x11->max_prop_size = 262144;
> -#endif
> -
> for (i = 0; i < x11->screen_count; i++) {
> /* Catch resolution changes */
> XSelectInput(x11->display, x11->root_window[i], StructureNotifyMask);
> @@ -312,8 +151,7 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
> /* Since we are started at the same time as the wm,
> sometimes we need to wait a bit for the _NET_WM_NAME to show up. */
> for (i = 0; i < 9; i++) {
> - g_free(net_wm_name);
> - net_wm_name = vdagent_x11_get_wm_name(x11);
> + net_wm_name = vdagent_x11_get_wm_name();
> if (strcmp(net_wm_name, "unknown"))
> break;
> usleep(100000);
> @@ -321,7 +159,6 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
> if (x11->debug)
> syslog(LOG_DEBUG, "%s: net_wm_name=\"%s\", has icons=%d",
> __func__, net_wm_name, vdagent_x11_has_icons_on_desktop(x11));
> - g_free(net_wm_name);
>
> /* Flush output buffers and consume any pending events */
> vdagent_x11_do_read(x11);
> @@ -334,16 +171,6 @@ void vdagent_x11_destroy(struct vdagent_x11 *x11, int vdagentd_disconnected)
> if (!x11)
> return;
>
> -#ifndef WITH_GTK
> - if (vdagentd_disconnected)
> - x11->vdagentd = NULL;
> -
> - uint8_t sel;
> - for (sel = 0; sel < VD_AGENT_CLIPBOARD_SELECTION_SECONDARY; ++sel) {
> - vdagent_x11_set_clipboard_owner(x11, sel, owner_none);
> - }
> -#endif
> -
> XCloseDisplay(x11->display);
> free(x11->randr.failed_conf);
> free(x11);
> @@ -354,194 +181,9 @@ int vdagent_x11_get_fd(struct vdagent_x11 *x11)
> return x11->fd;
> }
>
> -#ifndef WITH_GTK
> -static void vdagent_x11_next_selection_request(struct vdagent_x11 *x11)
> -{
> - struct vdagent_x11_selection_request *selection_request;
> - selection_request = x11->selection_req;
> - x11->selection_req = selection_request->next;
> - free(selection_request);
> -}
> -
> -static void vdagent_x11_next_conversion_request(struct vdagent_x11 *x11)
> -{
> - struct vdagent_x11_conversion_request *conversion_req;
> - conversion_req = x11->conversion_req;
> - x11->conversion_req = conversion_req->next;
> - free(conversion_req);
> -}
> -
> -static void vdagent_x11_set_clipboard_owner(struct vdagent_x11 *x11,
> - uint8_t selection, int new_owner)
> -{
> - struct vdagent_x11_selection_request *prev_sel, *curr_sel, *next_sel;
> - struct vdagent_x11_conversion_request *prev_conv, *curr_conv, *next_conv;
> - int once;
> -
> - /* Clear pending requests and clipboard data */
> - once = 1;
> - prev_sel = NULL;
> - next_sel = x11->selection_req;
> - while (next_sel) {
> - curr_sel = next_sel;
> - next_sel = curr_sel->next;
> - if (curr_sel->selection == selection) {
> - if (once) {
> - SELPRINTF("selection requests pending on clipboard ownership "
> - "change, clearing");
> - once = 0;
> - }
> - vdagent_x11_send_selection_notify(x11, None, curr_sel);
> - if (curr_sel == x11->selection_req) {
> - x11->selection_req = next_sel;
> - free(x11->selection_req_data);
> - x11->selection_req_data = NULL;
> - x11->selection_req_data_pos = 0;
> - x11->selection_req_data_size = 0;
> - x11->selection_req_atom = None;
> - } else {
> - prev_sel->next = next_sel;
> - }
> - free(curr_sel);
> - } else {
> - prev_sel = curr_sel;
> - }
> - }
> -
> - once = 1;
> - prev_conv = NULL;
> - next_conv = x11->conversion_req;
> - while (next_conv) {
> - curr_conv = next_conv;
> - next_conv = curr_conv->next;
> - if (curr_conv->selection == selection) {
> - if (once) {
> - SELPRINTF("client clipboard request pending on clipboard "
> - "ownership change, clearing");
> - once = 0;
> - }
> - if (x11->vdagentd)
> - udscs_write(x11->vdagentd, VDAGENTD_CLIPBOARD_DATA, selection,
> - VD_AGENT_CLIPBOARD_NONE, NULL, 0);
> - if (curr_conv == x11->conversion_req) {
> - x11->conversion_req = next_conv;
> - x11->clipboard_data_size = 0;
> - x11->expect_property_notify = 0;
> - } else {
> - prev_conv->next = next_conv;
> - }
> - free(curr_conv);
> - } else {
> - prev_conv = curr_conv;
> - }
> - }
> -
> - if (new_owner == owner_none) {
> - /* When going from owner_guest to owner_none we need to send a
> - clipboard release message to the client */
> - if (x11->clipboard_owner[selection] == owner_guest && x11->vdagentd) {
> - udscs_write(x11->vdagentd, VDAGENTD_CLIPBOARD_RELEASE, selection,
> - 0, NULL, 0);
> - }
> - x11->clipboard_type_count[selection] = 0;
> - }
> - x11->clipboard_owner[selection] = new_owner;
> -}
> -
> -static int vdagent_x11_get_clipboard_atom(struct vdagent_x11 *x11, uint8_t selection, Atom* clipboard)
> -{
> - if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
> - *clipboard = x11->clipboard_atom;
> - } else if (selection == VD_AGENT_CLIPBOARD_SELECTION_PRIMARY) {
> - *clipboard = x11->clipboard_primary_atom;
> - } else {
> - syslog(LOG_ERR, "get_clipboard_atom: unknown selection");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -static int vdagent_x11_get_clipboard_selection(struct vdagent_x11 *x11,
> - XEvent *event, uint8_t *selection)
> -{
> - Atom atom;
> -
> - if (event->type == x11->xfixes_event_base) {
> - XFixesSelectionNotifyEvent *xfev = (XFixesSelectionNotifyEvent *)event;
> - atom = xfev->selection;
> - } else if (event->type == SelectionNotify) {
> - atom = event->xselection.selection;
> - } else if (event->type == SelectionRequest) {
> - atom = event->xselectionrequest.selection;
> - } else {
> - syslog(LOG_ERR, "get_clipboard_selection: unknown event type");
> - return -1;
> - }
> -
> - if (atom == x11->clipboard_atom) {
> - *selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
> - } else if (atom == x11->clipboard_primary_atom) {
> - *selection = VD_AGENT_CLIPBOARD_SELECTION_PRIMARY;
> - } else {
> - syslog(LOG_ERR, "get_clipboard_selection: unknown selection");
> - return -1;
> - }
> -
> - return 0;
> -}
> -#endif
> -
> static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event)
> {
> int i, handled = 0;
> -#ifndef WITH_GTK
> - uint8_t selection;
> -
> - if (event.type == x11->xfixes_event_base) {
> - union {
> - XEvent ev;
> - XFixesSelectionNotifyEvent xfev;
> - } ev;
> -
> - if (vdagent_x11_get_clipboard_selection(x11, &event, &selection)) {
> - return;
> - }
> -
> - ev.ev = event;
> - switch (ev.xfev.subtype) {
> - case XFixesSetSelectionOwnerNotify:
> - break;
> - /* Treat ... as a SelectionOwnerNotify None */
> - case XFixesSelectionWindowDestroyNotify:
> - case XFixesSelectionClientCloseNotify:
> - ev.xfev.owner = None;
> - break;
> - default:
> - VSELPRINTF("unexpected xfix event subtype %d window %d",
> - (int)ev.xfev.subtype, (int)event.xany.window);
> - return;
> - }
> - VSELPRINTF("New selection owner: %u", (unsigned int)ev.xfev.owner);
> -
> - /* Ignore becoming the owner ourselves */
> - if (ev.xfev.owner == x11->selection_window)
> - return;
> -
> - /* If the clipboard owner is changed we no longer own it */
> - vdagent_x11_set_clipboard_owner(x11, selection, owner_none);
> -
> - if (ev.xfev.owner == None)
> - return;
> -
> - /* Request the supported targets from the new owner */
> - XConvertSelection(x11->display, ev.xfev.selection, x11->targets_atom,
> - x11->targets_atom, x11->selection_window,
> - CurrentTime);
> - x11->expected_targets_notifies[selection]++;
> - return;
> - }
> -#endif
>
> if (vdagent_x11_randr_handle_event(x11, event))
> return;
> @@ -562,67 +204,6 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event)
> /* These are uninteresting */
> handled = 1;
> break;
> -#ifndef WITH_GTK
> - case SelectionNotify:
> - if (event.xselection.target == x11->targets_atom)
> - vdagent_x11_handle_targets_notify(x11, &event);
> - else
> - vdagent_x11_handle_selection_notify(x11, &event, 0);
> -
> - handled = 1;
> - break;
> - case PropertyNotify:
> - if (x11->expect_property_notify &&
> - event.xproperty.state == PropertyNewValue) {
> - vdagent_x11_handle_selection_notify(x11, &event, 1);
> - }
> - if (x11->selection_req_data &&
> - event.xproperty.state == PropertyDelete) {
> - vdagent_x11_handle_property_delete_notify(x11, &event);
> - }
> - /* Always mark as handled, since we cannot unselect input for property
> - notifications once we are done with handling the incr transfer. */
> - handled = 1;
> - break;
> - case SelectionClear:
> - /* Do nothing the clipboard ownership will get updated through
> - the XFixesSetSelectionOwnerNotify event */
> - handled = 1;
> - break;
> - case SelectionRequest: {
> - struct vdagent_x11_selection_request *req, *new_req;
> -
> - if (vdagent_x11_get_clipboard_selection(x11, &event, &selection)) {
> - return;
> - }
> -
> - new_req = malloc(sizeof(*new_req));
> - if (!new_req) {
> - SELPRINTF("out of memory on SelectionRequest, ignoring.");
> - break;
> - }
> -
> - handled = 1;
> -
> - new_req->event = event;
> - new_req->selection = selection;
> - new_req->next = NULL;
> -
> - if (!x11->selection_req) {
> - x11->selection_req = new_req;
> - vdagent_x11_handle_selection_request(x11);
> - break;
> - }
> -
> - /* maybe we should limit the selection_request stack depth ? */
> - req = x11->selection_req;
> - while (req->next)
> - req = req->next;
> -
> - req->next = new_req;
> - break;
> - }
> -#endif
> }
> if (!handled && x11->debug)
> syslog(LOG_DEBUG, "unhandled x11 event, type %d, window %d",
> @@ -639,749 +220,12 @@ void vdagent_x11_do_read(struct vdagent_x11 *x11)
> }
> }
>
> -#ifndef WITH_GTK
> -static const char *vdagent_x11_get_atom_name(struct vdagent_x11 *x11, Atom a)
> -{
> - if (a == None)
> - return "None";
> -
> - return XGetAtomName(x11->display, a);
> -}
> -
> -static int vdagent_x11_get_selection(struct vdagent_x11 *x11, XEvent *event,
> - uint8_t selection, Atom type, Atom prop, int format,
> - unsigned char **data_ret, int incr)
> -{
> - Bool del = incr ? True: False;
> - Atom type_ret;
> - int format_ret, ret_val = -1;
> - unsigned long len, remain;
> - unsigned char *data = NULL;
> -
> - *data_ret = NULL;
> -
> - if (!incr) {
> - if (event->xselection.property == None) {
> - VSELPRINTF("XConvertSelection refused by clipboard owner");
> - goto exit;
> - }
> -
> - if (event->xselection.requestor != x11->selection_window ||
> - event->xselection.property != prop) {
> - SELPRINTF("SelectionNotify parameters mismatch");
> - goto exit;
> - }
> - }
> -
> - if (XGetWindowProperty(x11->display, x11->selection_window, prop, 0,
> - LONG_MAX, del, type, &type_ret, &format_ret, &len,
> - &remain, &data) != Success) {
> - SELPRINTF("XGetWindowProperty failed");
> - goto exit;
> - }
> -
> - if (!incr && prop != x11->targets_atom) {
> - if (type_ret == x11->incr_atom) {
> - int prop_min_size = *(uint32_t*)data;
> -
> - if (x11->expect_property_notify) {
> - SELPRINTF("received an incr SelectionNotify while "
> - "still reading another incr property");
> - goto exit;
> - }
> -
> - if (x11->clipboard_data_space < prop_min_size) {
> - free(x11->clipboard_data);
> - x11->clipboard_data = malloc(prop_min_size);
> - if (!x11->clipboard_data) {
> - SELPRINTF("out of memory allocating clipboard buffer");
> - x11->clipboard_data_space = 0;
> - goto exit;
> - }
> - x11->clipboard_data_space = prop_min_size;
> - }
> - x11->expect_property_notify = 1;
> - XSelectInput(x11->display, x11->selection_window,
> - PropertyChangeMask);
> - XDeleteProperty(x11->display, x11->selection_window, prop);
> - XFree(data);
> - return 0; /* Wait for more data */
> - }
> - XDeleteProperty(x11->display, x11->selection_window, prop);
> - }
> -
> - if (type_ret != type) {
> - SELPRINTF("expected property type: %s, got: %s",
> - vdagent_x11_get_atom_name(x11, type),
> - vdagent_x11_get_atom_name(x11, type_ret));
> - goto exit;
> - }
> -
> - if (format_ret != format) {
> - SELPRINTF("expected %d bit format, got %d bits", format, format_ret);
> - goto exit;
> - }
> -
> - /* Convert len to bytes */
> - switch(format) {
> - case 8:
> - break;
> - case 16:
> - len *= sizeof(short);
> - break;
> - case 32:
> - len *= sizeof(long);
> - break;
> - }
> -
> - if (incr) {
> - if (len) {
> - if (x11->clipboard_data_size + len > x11->clipboard_data_space) {
> - void *old_clipboard_data = x11->clipboard_data;
> -
> - x11->clipboard_data_space = x11->clipboard_data_size + len;
> - x11->clipboard_data = realloc(x11->clipboard_data,
> - x11->clipboard_data_space);
> - if (!x11->clipboard_data) {
> - SELPRINTF("out of memory allocating clipboard buffer");
> - x11->clipboard_data_space = 0;
> - free(old_clipboard_data);
> - goto exit;
> - }
> - }
> - memcpy(x11->clipboard_data + x11->clipboard_data_size, data, len);
> - x11->clipboard_data_size += len;
> - VSELPRINTF("Appended %ld bytes to buffer", len);
> - XFree(data);
> - return 0; /* Wait for more data */
> - }
> - len = x11->clipboard_data_size;
> - *data_ret = x11->clipboard_data;
> - } else
> - *data_ret = data;
> -
> - if (len > 0) {
> - ret_val = len;
> - } else {
> - SELPRINTF("property contains no data (zero length)");
> - *data_ret = NULL;
> - }
> -
> -exit:
> - if ((incr || ret_val == -1) && data)
> - XFree(data);
> -
> - if (incr) {
> - x11->clipboard_data_size = 0;
> - x11->expect_property_notify = 0;
> - }
> -
> - return ret_val;
> -}
> -
> -static void vdagent_x11_get_selection_free(struct vdagent_x11 *x11,
> - unsigned char *data, int incr)
> -{
> - if (incr) {
> - /* If the clipboard has grown large return the memory to the system */
> - if (x11->clipboard_data_space > 512 * 1024) {
> - free(x11->clipboard_data);
> - x11->clipboard_data = NULL;
> - x11->clipboard_data_space = 0;
> - }
> - } else if (data)
> - XFree(data);
> -}
> -
> -static uint32_t vdagent_x11_target_to_type(struct vdagent_x11 *x11,
> - uint8_t selection, Atom target)
> -{
> - int i, j;
> -
> - for (i = 0; i < clipboard_format_count; i++) {
> - for (j = 0; j < x11->clipboard_formats[i].atom_count; j++) {
> - if (x11->clipboard_formats[i].atoms[j] == target) {
> - return x11->clipboard_formats[i].type;
> - }
> - }
> - }
> -
> - VSELPRINTF("unexpected selection type %s",
> - vdagent_x11_get_atom_name(x11, target));
> - return VD_AGENT_CLIPBOARD_NONE;
> -}
> -
> -static Atom vdagent_x11_type_to_target(struct vdagent_x11 *x11,
> - uint8_t selection, uint32_t type)
> -{
> - int i;
> -
> - for (i = 0; i < x11->clipboard_type_count[selection]; i++) {
> - if (x11->clipboard_agent_types[selection][i] == type) {
> - return x11->clipboard_x11_targets[selection][i];
> - }
> - }
> - SELPRINTF("client requested unavailable type %u", type);
> - return None;
> -}
> -
> -static void vdagent_x11_handle_conversion_request(struct vdagent_x11 *x11)
> -{
> - Atom clip = None;
> -
> - if (!x11->conversion_req) {
> - return;
> - }
> -
> - vdagent_x11_get_clipboard_atom(x11, x11->conversion_req->selection, &clip);
> - XConvertSelection(x11->display, clip, x11->conversion_req->target,
> - clip, x11->selection_window, CurrentTime);
> -}
> -
> -static void vdagent_x11_handle_selection_notify(struct vdagent_x11 *x11,
> - XEvent *event, int incr)
> -{
> - int len = 0;
> - unsigned char *data = NULL;
> - uint32_t type;
> - uint8_t selection = -1;
> - Atom clip = None;
> -
> - if (!x11->conversion_req) {
> - syslog(LOG_ERR, "SelectionNotify received without a target");
> - return;
> - }
> - vdagent_x11_get_clipboard_atom(x11, x11->conversion_req->selection, &clip);
> -
> - if (incr) {
> - if (event->xproperty.atom != clip ||
> - event->xproperty.window != x11->selection_window) {
> - return;
> - }
> - } else {
> - if (vdagent_x11_get_clipboard_selection(x11, event, &selection)) {
> - len = -1;
> - } else if (selection != x11->conversion_req->selection) {
> - SELPRINTF("Requested data for selection %d got %d",
> - (int)x11->conversion_req->selection, (int)selection);
> - len = -1;
> - }
> - if (event->xselection.target != x11->conversion_req->target &&
> - event->xselection.target != x11->incr_atom) {
> - SELPRINTF("Requested %s target got %s",
> - vdagent_x11_get_atom_name(x11, x11->conversion_req->target),
> - vdagent_x11_get_atom_name(x11, event->xselection.target));
> - len = -1;
> - }
> - }
> -
> - selection = x11->conversion_req->selection;
> - type = vdagent_x11_target_to_type(x11, selection,
> - x11->conversion_req->target);
> - if (type == VD_AGENT_CLIPBOARD_NONE)
> - SELPRINTF("internal error conversion_req has bad target %s",
> - vdagent_x11_get_atom_name(x11, x11->conversion_req->target));
> - if (len == 0) { /* No errors so far */
> - len = vdagent_x11_get_selection(x11, event, selection,
> - x11->conversion_req->target,
> - clip, 8, &data, incr);
> - if (len == 0) { /* waiting for more data? */
> - return;
> - }
> - }
> - if (len == -1) {
> - type = VD_AGENT_CLIPBOARD_NONE;
> - len = 0;
> - }
> -
> - udscs_write(x11->vdagentd, VDAGENTD_CLIPBOARD_DATA, selection, type,
> - data, len);
> - vdagent_x11_get_selection_free(x11, data, incr);
> -
> - vdagent_x11_next_conversion_request(x11);
> - vdagent_x11_handle_conversion_request(x11);
> -}
> -
> -static Atom atom_lists_overlap(Atom *atoms1, Atom *atoms2, int l1, int l2)
> -{
> - int i, j;
> -
> - for (i = 0; i < l1; i++)
> - for (j = 0; j < l2; j++)
> - if (atoms1[i] == atoms2[j])
> - return atoms1[i];
> -
> - return 0;
> -}
> -
> -static void vdagent_x11_print_targets(struct vdagent_x11 *x11,
> - uint8_t selection, const char *action, Atom *atoms, int c)
> -{
> - int i;
> - VSELPRINTF("%s %d targets:", action, c);
> - for (i = 0; i < c; i++)
> - VSELPRINTF("%s", vdagent_x11_get_atom_name(x11, atoms[i]));
> -}
> -
> -static void vdagent_x11_handle_targets_notify(struct vdagent_x11 *x11,
> - XEvent *event)
> -{
> - int i, len;
> - Atom atom, *atoms = NULL;
> - uint8_t selection;
> - int *type_count;
> -
> - if (vdagent_x11_get_clipboard_selection(x11, event, &selection)) {
> - return;
> - }
> -
> - if (!x11->expected_targets_notifies[selection]) {
> - SELPRINTF("unexpected selection notify TARGETS");
> - return;
> - }
> -
> - x11->expected_targets_notifies[selection]--;
> -
> - /* If we have more targets_notifies pending, ignore this one, we
> - are only interested in the targets list of the current owner
> - (which is the last one we've requested a targets list from) */
> - if (x11->expected_targets_notifies[selection]) {
> - return;
> - }
> -
> - len = vdagent_x11_get_selection(x11, event, selection,
> - XA_ATOM, x11->targets_atom, 32,
> - (unsigned char **)&atoms, 0);
> - if (len == 0 || len == -1) /* waiting for more data or error? */
> - return;
> -
> - /* bytes -> atoms */
> - len /= sizeof(Atom);
> - vdagent_x11_print_targets(x11, selection, "received", atoms, len);
> -
> - type_count = &x11->clipboard_type_count[selection];
> - *type_count = 0;
> - for (i = 0; i < clipboard_format_count; i++) {
> - atom = atom_lists_overlap(x11->clipboard_formats[i].atoms, atoms,
> - x11->clipboard_formats[i].atom_count, len);
> - if (atom) {
> - x11->clipboard_agent_types[selection][*type_count] =
> - x11->clipboard_formats[i].type;
> - x11->clipboard_x11_targets[selection][*type_count] = atom;
> - (*type_count)++;
> - if (*type_count ==
> - sizeof(x11->clipboard_agent_types[0])/sizeof(uint32_t)) {
> - SELPRINTF("handle_targets_notify: too many types");
> - break;
> - }
> - }
> - }
> -
> - if (*type_count) {
> - udscs_write(x11->vdagentd, VDAGENTD_CLIPBOARD_GRAB, selection, 0,
> - (uint8_t *)x11->clipboard_agent_types[selection],
> - *type_count * sizeof(uint32_t));
> - vdagent_x11_set_clipboard_owner(x11, selection, owner_guest);
> - }
> -
> - vdagent_x11_get_selection_free(x11, (unsigned char *)atoms, 0);
> -}
> -
> -static void vdagent_x11_send_selection_notify(struct vdagent_x11 *x11,
> - Atom prop, struct vdagent_x11_selection_request *request)
> -{
> - XEvent res, *event;
> -
> - if (request) {
> - event = &request->event;
> - } else {
> - event = &x11->selection_req->event;
> - }
> -
> - res.xselection.property = prop;
> - res.xselection.type = SelectionNotify;
> - res.xselection.display = event->xselectionrequest.display;
> - res.xselection.requestor = event->xselectionrequest.requestor;
> - res.xselection.selection = event->xselectionrequest.selection;
> - res.xselection.target = event->xselectionrequest.target;
> - res.xselection.time = event->xselectionrequest.time;
> -
> - vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler);
> - XSendEvent(x11->display, event->xselectionrequest.requestor, 0, 0, &res);
> - vdagent_x11_restore_error_handler(x11);
> -
> - if (!request) {
> - vdagent_x11_next_selection_request(x11);
> - vdagent_x11_handle_selection_request(x11);
> - }
> -}
> -
> -static void vdagent_x11_send_targets(struct vdagent_x11 *x11,
> - uint8_t selection, XEvent *event)
> -{
> - Atom prop, targets[256] = { x11->targets_atom, };
> - int i, j, k, target_count = 1;
> -
> - for (i = 0; i < x11->clipboard_type_count[selection]; i++) {
> - for (j = 0; j < clipboard_format_count; j++) {
> - if (x11->clipboard_formats[j].type !=
> - x11->clipboard_agent_types[selection][i])
> - continue;
> -
> - for (k = 0; k < x11->clipboard_formats[j].atom_count; k++) {
> - targets[target_count] = x11->clipboard_formats[j].atoms[k];
> - target_count++;
> - if (target_count == sizeof(targets)/sizeof(Atom)) {
> - SELPRINTF("send_targets: too many targets");
> - goto exit_loop;
> - }
> - }
> - }
> - }
> -exit_loop:
> -
> - prop = event->xselectionrequest.property;
> - if (prop == None)
> - prop = event->xselectionrequest.target;
> -
> - vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler);
> - XChangeProperty(x11->display, event->xselectionrequest.requestor, prop,
> - XA_ATOM, 32, PropModeReplace, (unsigned char *)&targets,
> - target_count);
> - if (vdagent_x11_restore_error_handler(x11) == 0) {
> - vdagent_x11_print_targets(x11, selection, "sent",
> - targets, target_count);
> - vdagent_x11_send_selection_notify(x11, prop, NULL);
> - } else
> - SELPRINTF("send_targets: Failed to sent, requestor window gone");
> -}
> -
> -static void vdagent_x11_handle_selection_request(struct vdagent_x11 *x11)
> -{
> - XEvent *event;
> - uint32_t type = VD_AGENT_CLIPBOARD_NONE;
> - uint8_t selection;
> -
> - if (!x11->selection_req)
> - return;
> -
> - event = &x11->selection_req->event;
> - selection = x11->selection_req->selection;
> -
> - if (x11->clipboard_owner[selection] != owner_client) {
> - SELPRINTF("received selection request event for target %s, "
> - "while not owning client clipboard",
> - vdagent_x11_get_atom_name(x11, event->xselectionrequest.target));
> - vdagent_x11_send_selection_notify(x11, None, NULL);
> - return;
> - }
> -
> - if (event->xselectionrequest.target == x11->multiple_atom) {
> - SELPRINTF("multiple target not supported");
> - vdagent_x11_send_selection_notify(x11, None, NULL);
> - return;
> - }
> -
> - if (event->xselectionrequest.target == x11->timestamp_atom) {
> - /* TODO: use more accurate selection time */
> - guint32 timestamp = event->xselectionrequest.time;
> -
> - XChangeProperty(x11->display, event->xselectionrequest.requestor,
> - event->xselectionrequest.property,
> - event->xselectionrequest.target, 32, PropModeReplace,
> - (guint8*)×tamp, 1);
> - vdagent_x11_send_selection_notify(x11,
> - event->xselectionrequest.property, NULL);
> - return;
> - }
> -
> -
> - if (event->xselectionrequest.target == x11->targets_atom) {
> - vdagent_x11_send_targets(x11, selection, event);
> - return;
> - }
> -
> - type = vdagent_x11_target_to_type(x11, selection,
> - event->xselectionrequest.target);
> - if (type == VD_AGENT_CLIPBOARD_NONE) {
> - VSELPRINTF("guest app requested a non-advertised target");
> - vdagent_x11_send_selection_notify(x11, None, NULL);
> - return;
> - }
> -
> - udscs_write(x11->vdagentd, VDAGENTD_CLIPBOARD_REQUEST, selection, type,
> - NULL, 0);
> -}
> -
> -static void vdagent_x11_handle_property_delete_notify(struct vdagent_x11 *x11,
> - XEvent *del_event)
> -{
> - XEvent *sel_event;
> - int len;
> - uint8_t selection;
> -
> - assert(x11->selection_req);
> - sel_event = &x11->selection_req->event;
> - selection = x11->selection_req->selection;
> - if (del_event->xproperty.window != sel_event->xselectionrequest.requestor
> - || del_event->xproperty.atom != x11->selection_req_atom) {
> - return;
> - }
> -
> - len = x11->selection_req_data_size - x11->selection_req_data_pos;
> - if (len > x11->max_prop_size) {
> - len = x11->max_prop_size;
> - }
> -
> - if (len) {
> - VSELPRINTF("Sending %d-%d/%d bytes of clipboard data",
> - x11->selection_req_data_pos,
> - x11->selection_req_data_pos + len - 1,
> - x11->selection_req_data_size);
> - } else {
> - VSELPRINTF("Ending incr send of clipboard data");
> - }
> - vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler);
> - XChangeProperty(x11->display, sel_event->xselectionrequest.requestor,
> - x11->selection_req_atom,
> - sel_event->xselectionrequest.target, 8, PropModeReplace,
> - x11->selection_req_data + x11->selection_req_data_pos,
> - len);
> - if (vdagent_x11_restore_error_handler(x11)) {
> - SELPRINTF("incr sent failed, requestor window gone");
> - len = 0;
> - }
> -
> - x11->selection_req_data_pos += len;
> -
> - /* Note we must explicitly send a 0 sized XChangeProperty to signal the
> - incr transfer is done. Hence we do not check if we've send all data
> - but instead check we've send the final 0 sized XChangeProperty. */
> - if (len == 0) {
> - free(x11->selection_req_data);
> - x11->selection_req_data = NULL;
> - x11->selection_req_data_pos = 0;
> - x11->selection_req_data_size = 0;
> - x11->selection_req_atom = None;
> - vdagent_x11_next_selection_request(x11);
> - vdagent_x11_handle_selection_request(x11);
> - }
> -}
> -
> -void vdagent_x11_clipboard_request(struct vdagent_x11 *x11,
> - uint8_t selection, uint32_t type)
> -{
> - Atom target, clip;
> - struct vdagent_x11_conversion_request *req, *new_req;
> -
> - /* We don't use clip here, but we call get_clipboard_atom to verify
> - selection is valid */
> - if (vdagent_x11_get_clipboard_atom(x11, selection, &clip)) {
> - goto none;
> - }
> -
> - if (x11->clipboard_owner[selection] != owner_guest) {
> - SELPRINTF("received clipboard req while not owning guest clipboard");
> - goto none;
> - }
> -
> - target = vdagent_x11_type_to_target(x11, selection, type);
> - if (target == None) {
> - goto none;
> - }
> -
> - new_req = malloc(sizeof(*new_req));
> - if (!new_req) {
> - SELPRINTF("out of memory on client clipboard request, ignoring.");
> - return;
> - }
> -
> - new_req->target = target;
> - new_req->selection = selection;
> - new_req->next = NULL;
> -
> - if (!x11->conversion_req) {
> - x11->conversion_req = new_req;
> - vdagent_x11_handle_conversion_request(x11);
> - /* Flush output buffers and consume any pending events */
> - vdagent_x11_do_read(x11);
> - return;
> - }
> -
> - /* maybe we should limit the conversion_request stack depth ? */
> - req = x11->conversion_req;
> - while (req->next)
> - req = req->next;
> -
> - req->next = new_req;
> - return;
> -
> -none:
> - udscs_write(x11->vdagentd, VDAGENTD_CLIPBOARD_DATA,
> - selection, VD_AGENT_CLIPBOARD_NONE, NULL, 0);
> -}
> -
> -void vdagent_x11_clipboard_grab(struct vdagent_x11 *x11, uint8_t selection,
> - uint32_t *types, uint32_t type_count)
> -{
> - Atom clip = None;
> -
> - if (vdagent_x11_get_clipboard_atom(x11, selection, &clip)) {
> - return;
> - }
> -
> - if (type_count > sizeof(x11->clipboard_agent_types[0])/sizeof(uint32_t)) {
> - SELPRINTF("x11_clipboard_grab: too many types");
> - type_count = sizeof(x11->clipboard_agent_types[0])/sizeof(uint32_t);
> - }
> -
> - memcpy(x11->clipboard_agent_types[selection], types,
> - type_count * sizeof(uint32_t));
> - x11->clipboard_type_count[selection] = type_count;
> -
> - XSetSelectionOwner(x11->display, clip,
> - x11->selection_window, CurrentTime);
> - vdagent_x11_set_clipboard_owner(x11, selection, owner_client);
> -
> - /* Flush output buffers and consume any pending events */
> - vdagent_x11_do_read(x11);
> -}
> -
> -void vdagent_x11_clipboard_data(struct vdagent_x11 *x11, uint8_t selection,
> - uint32_t type, uint8_t *data, uint32_t size)
> -{
> - Atom prop;
> - XEvent *event;
> - uint32_t type_from_event;
> -
> - if (x11->selection_req_data) {
> - if (type || size) {
> - SELPRINTF("received clipboard data while still sending"
> - " data from previous request, ignoring");
> - }
> - return;
> - }
> -
> - if (!x11->selection_req) {
> - if (type || size) {
> - SELPRINTF("received clipboard data without an "
> - "outstanding selection request, ignoring");
> - }
> - return;
> - }
> -
> - event = &x11->selection_req->event;
> - type_from_event = vdagent_x11_target_to_type(x11,
> - x11->selection_req->selection,
> - event->xselectionrequest.target);
> - if (type_from_event != type ||
> - selection != x11->selection_req->selection) {
> - if (selection != x11->selection_req->selection) {
> - SELPRINTF("expecting data for selection %d got %d",
> - (int)x11->selection_req->selection, (int)selection);
> - }
> - if (type_from_event != type) {
> - SELPRINTF("expecting type %u clipboard data got %u",
> - type_from_event, type);
> - }
> - vdagent_x11_send_selection_notify(x11, None, NULL);
> -
> - /* Flush output buffers and consume any pending events */
> - vdagent_x11_do_read(x11);
> - return;
> - }
> -
> - prop = event->xselectionrequest.property;
> - if (prop == None)
> - prop = event->xselectionrequest.target;
> -
> - if (size > x11->max_prop_size) {
> - unsigned long len = size;
> - VSELPRINTF("Starting incr send of clipboard data");
> -
> - vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler);
> - XSelectInput(x11->display, event->xselectionrequest.requestor,
> - PropertyChangeMask);
> - XChangeProperty(x11->display, event->xselectionrequest.requestor, prop,
> - x11->incr_atom, 32, PropModeReplace,
> - (unsigned char*)&len, 1);
> - if (vdagent_x11_restore_error_handler(x11) == 0) {
> - /* duplicate data */
> - x11->selection_req_data = malloc(size);
> - if (x11->selection_req_data != NULL) {
> - memcpy(x11->selection_req_data, data, size);
> - x11->selection_req_data_pos = 0;
> - x11->selection_req_data_size = size;
> - x11->selection_req_atom = prop;
> - vdagent_x11_send_selection_notify(x11, prop, x11->selection_req);
> - } else {
> - SELPRINTF("out of memory allocating selection buffer");
> - }
> - } else {
> - SELPRINTF("clipboard data sent failed, requestor window gone");
> - }
> - } else {
> - vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler);
> - XChangeProperty(x11->display, event->xselectionrequest.requestor, prop,
> - event->xselectionrequest.target, 8, PropModeReplace,
> - data, size);
> - if (vdagent_x11_restore_error_handler(x11) == 0)
> - vdagent_x11_send_selection_notify(x11, prop, NULL);
> - else
> - SELPRINTF("clipboard data sent failed, requestor window gone");
> - }
> -
> - /* Flush output buffers and consume any pending events */
> - vdagent_x11_do_read(x11);
> -}
> -
> -void vdagent_x11_clipboard_release(struct vdagent_x11 *x11, uint8_t selection)
> -{
> - XEvent event;
> - Atom clip = None;
> -
> - if (vdagent_x11_get_clipboard_atom(x11, selection, &clip)) {
> - return;
> - }
> -
> - if (x11->clipboard_owner[selection] != owner_client) {
> - VSELPRINTF("received release while not owning client clipboard");
> - return;
> - }
> -
> - XSetSelectionOwner(x11->display, clip, None, CurrentTime);
> - /* Make sure we process the XFixesSetSelectionOwnerNotify event caused
> - by this, so we don't end up changing the clipboard owner to none, after
> - it has already been re-owned because this event is still pending. */
> - XSync(x11->display, False);
> - while (XCheckTypedEvent(x11->display, x11->xfixes_event_base,
> - &event))
> - vdagent_x11_handle_event(x11, event);
> -
> - /* Note no need to do a set_clipboard_owner(owner_none) here, as that is
> - already done by processing the XFixesSetSelectionOwnerNotify event. */
> -
> - /* Flush output buffers and consume any pending events */
> - vdagent_x11_do_read(x11);
> -}
> -
> -void vdagent_x11_client_disconnected(struct vdagent_x11 *x11)
> -{
> - int sel;
> -
> - for (sel = 0; sel < VD_AGENT_CLIPBOARD_SELECTION_SECONDARY; sel++) {
> - if (x11->clipboard_owner[sel] == owner_client)
> - vdagent_x11_clipboard_release(x11, sel);
> - }
> -}
> -#endif
> -
> /* Function used to determine the default location to save file-xfers,
> xdg desktop dir or xdg download dir. We err on the safe side and use a
> whitelist approach, so any unknown desktop will end up with saving
> file-xfers to the xdg download dir, and opening the xdg download dir with
> xdg-open when the file-xfer completes. */
> -int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11)
> +int vdagent_x11_has_icons_on_desktop()
> {
> const char * const wms_with_icons_on_desktop[] = {
> "Metacity", /* GNOME-2 or GNOME-3 fallback */
> @@ -1390,15 +234,12 @@ int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11)
> "Metacity (Marco)", /* Mate, newer */
> NULL
> };
> - gchar *net_wm_name = vdagent_x11_get_wm_name(x11);
> + const gchar *net_wm_name = vdagent_x11_get_wm_name();
> int i;
>
> for (i = 0; wms_with_icons_on_desktop[i]; i++)
> - if (!strcmp(net_wm_name, wms_with_icons_on_desktop[i])) {
> - g_free(net_wm_name);
> + if (!strcmp(net_wm_name, wms_with_icons_on_desktop[i]))
> return 1;
> - }
>
> - g_free(net_wm_name);
> return 0;
> }
> diff --git a/src/vdagent/x11.h b/src/vdagent/x11.h
> index 1505f58..6ad09c2 100644
> --- a/src/vdagent/x11.h
> +++ b/src/vdagent/x11.h
> @@ -22,10 +22,6 @@
> #ifndef __VDAGENT_X11_H
> #define __VDAGENT_X11_H
>
> -#ifdef HAVE_CONFIG_H
> -# include <config.h>
> -#endif
> -
> #include <stdio.h>
> #include <spice/vd_agent.h>
> #include "udscs.h"
> @@ -42,18 +38,6 @@ void vdagent_x11_do_read(struct vdagent_x11 *x11);
> void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11,
> VDAgentMonitorsConfig *mon_config, int fallback);
>
> -#ifndef WITH_GTK
> -void vdagent_x11_clipboard_grab(struct vdagent_x11 *x11, uint8_t selection,
> - uint32_t *types, uint32_t type_count);
> -void vdagent_x11_clipboard_request(struct vdagent_x11 *x11,
> - uint8_t selection, uint32_t type);
> -void vdagent_x11_clipboard_data(struct vdagent_x11 *x11, uint8_t selection,
> - uint32_t type, uint8_t *data, uint32_t size);
> -void vdagent_x11_clipboard_release(struct vdagent_x11 *x11, uint8_t selection);
> -
> -void vdagent_x11_client_disconnected(struct vdagent_x11 *x11);
> -#endif
> -
> -int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11);
> +int vdagent_x11_has_icons_on_desktop();
>
> #endif
> --
> 2.17.0
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20180809/0036775b/attachment-0001.sig>
More information about the Spice-devel
mailing list