diff options
Diffstat (limited to 'plugins/xrandr/msd-xrandr-manager.c')
-rw-r--r-- | plugins/xrandr/msd-xrandr-manager.c | 179 |
1 files changed, 141 insertions, 38 deletions
diff --git a/plugins/xrandr/msd-xrandr-manager.c b/plugins/xrandr/msd-xrandr-manager.c index 0e157a8..78e538f 100644 --- a/plugins/xrandr/msd-xrandr-manager.c +++ b/plugins/xrandr/msd-xrandr-manager.c @@ -2,6 +2,7 @@ * * Copyright (C) 2007 William Jon McCann <[email protected]> * Copyright (C) 2007, 2008 Red Hat, Inc + * Copyright (C) 2012-2021 MATE Developers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +39,6 @@ #include <gdk/gdkx.h> #include <gtk/gtk.h> #include <gio/gio.h> -#include <dbus/dbus-glib.h> #define MATE_DESKTOP_USE_UNSTABLE_API #include <libmate-desktop/mate-rr-config.h> @@ -76,12 +76,30 @@ #define MSD_DBUS_PATH "/org/mate/SettingsDaemon" #define MSD_DBUS_NAME "org.mate.SettingsDaemon" -#define MSD_XRANDR_DBUS_PATH MSD_DBUS_PATH "/XRANDR" #define MSD_XRANDR_DBUS_NAME MSD_DBUS_NAME ".XRANDR" +#define MSD_XRANDR_DBUS_PATH MSD_DBUS_PATH "/XRANDR" + +static const gchar introspection_xml[] = +"<node>" +" <interface name='org.mate.SettingsDaemon.XRANDR'>" +" <method name='ApplyConfiguration'>" +" </method>" +" </interface>" +"" +" <interface name='org.mate.SettingsDaemon.XRANDR_2'>" +" <method name='ApplyConfiguration'>" +" <arg name='parent_window_id' type='x' direction='in'/>" +" <arg name='timestamp' type='x' direction='in'/>" +" </method>" +" </interface>" +"</node>"; struct MsdXrandrManagerPrivate { - DBusGConnection *dbus_connection; + GDBusConnection *connection; + GDBusNodeInfo *introspection_data; + GCancellable *bus_cancellable; + guint owner_id; /* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */ guint switch_video_mode_keycode; @@ -627,9 +645,6 @@ msd_xrandr_manager_2_apply_configuration (MsdXrandrManager *manager, return result; } -/* We include this after the definition of msd_xrandr_manager_apply_configuration() so the prototype will already exist */ -#include "msd-xrandr-manager-glue.h" - static gboolean is_laptop (MateRRScreen *screen, MateRROutputInfo *output) { @@ -785,7 +800,7 @@ find_best_mode (MateRROutput *output) MateRRMode *preferred; MateRRMode **modes; int best_size; - int best_width, best_height, best_rate; + int best_rate; int i; MateRRMode *best_mode; @@ -797,7 +812,7 @@ find_best_mode (MateRROutput *output) if (!modes) return NULL; - best_size = best_width = best_height = best_rate = 0; + best_size = best_rate = 0; best_mode = NULL; for (i = 0; modes[i] != NULL; i++) { @@ -812,8 +827,6 @@ find_best_mode (MateRROutput *output) if (size > best_size) { best_size = size; - best_width = w; - best_height = h; best_rate = r; best_mode = modes[i]; } else if (size == best_size) { @@ -1007,7 +1020,6 @@ sanitize (MsdXrandrManager *manager, GPtrArray *array) } } - /* Remove configurations that are duplicates of * configurations earlier in the cycle */ @@ -2050,11 +2062,10 @@ mirror_outputs_cb(GtkCheckMenuItem *item, gpointer data) struct MsdXrandrManagerPrivate *priv = manager->priv; MateRRScreen *screen = priv->rw_screen; - if (gtk_check_menu_item_get_active(item)){ - + if (gtk_check_menu_item_get_active (item)) { MateRRConfig *config; - config = make_clone_setup (screen); - if (!config || config == NULL){ + + if ((config = make_clone_setup (screen)) == NULL) { error_message (manager, _("Mirroring outputs not supported"), NULL, NULL); } @@ -2243,7 +2254,7 @@ add_menu_items_for_clone (MsdXrandrManager *manager) GtkWidget *item; gulong activate_id; - item = gtk_check_menu_item_new_with_label(_("Same output all monitors")); + item = gtk_check_menu_item_new_with_label(_("Same output on all monitors")); gtk_widget_set_tooltip_text(item, _("Mirror same output to all monitors and turn them on")); gtk_widget_show_all (item); gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); @@ -2656,11 +2667,18 @@ msd_xrandr_manager_stop (MsdXrandrManager *manager) manager->priv->rw_screen = NULL; } - if (manager->priv->dbus_connection != NULL) { - dbus_g_connection_unref (manager->priv->dbus_connection); - manager->priv->dbus_connection = NULL; + if (manager->priv->owner_id > 0) { + g_bus_unown_name (manager->priv->owner_id); + manager->priv->owner_id = 0; + } + + if (manager->priv->connection != NULL) { + g_object_unref (manager->priv->connection); + manager->priv->connection = NULL; } + + g_clear_pointer (&manager->priv->introspection_data, g_dbus_node_info_unref); status_icon_stop (manager); log_open (); @@ -2674,8 +2692,6 @@ msd_xrandr_manager_class_init (MsdXrandrManagerClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = msd_xrandr_manager_finalize; - - dbus_g_object_type_install_info (MSD_TYPE_XRANDR_MANAGER, &dbus_glib_msd_xrandr_manager_object_info); } static guint @@ -2717,24 +2733,114 @@ msd_xrandr_manager_finalize (GObject *object) G_OBJECT_CLASS (msd_xrandr_manager_parent_class)->finalize (object); } -static gboolean -register_manager_dbus (MsdXrandrManager *manager) +static void +handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - GError *error = NULL; + MsdXrandrManager *manager = (MsdXrandrManager *) user_data; + g_autoptr (GError) error = NULL; - manager->priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (manager->priv->dbus_connection == NULL) { - if (error != NULL) { - g_warning ("Error getting session bus: %s", error->message); - g_error_free (error); - } - return FALSE; + g_debug ("Calling method '%s' for xrandr", method_name); + + if (g_strcmp0 (method_name, "ApplyConfiguration") == 0) { + msd_xrandr_manager_apply_configuration(manager, &error); + if (error != NULL) + g_dbus_method_invocation_return_gerror (invocation, error); + else + g_dbus_method_invocation_return_value (invocation, NULL); } +} - /* Hmm, should we do this in msd_xrandr_manager_start()? */ - dbus_g_connection_register_g_object (manager->priv->dbus_connection, MSD_XRANDR_DBUS_PATH, G_OBJECT (manager)); +static void +handle_method_call2 (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + MsdXrandrManager *manager = (MsdXrandrManager *) user_data; + g_autoptr (GError) error = NULL; - return TRUE; + g_debug ("Calling method '%s' for xrandr", method_name); + + if (g_strcmp0 (method_name, "ApplyConfiguration") == 0) { + gint64 parent_window_id; + gint64 timestamp; + g_variant_get (parameters, "(xx)", &parent_window_id, ×tamp); + msd_xrandr_manager_2_apply_configuration (manager, parent_window_id, timestamp, &error); + if (error != NULL) + g_dbus_method_invocation_return_gerror (invocation, error); + else + g_dbus_method_invocation_return_value (invocation, NULL); + } +} + +static const GDBusInterfaceVTable interface_vtable = +{ + .method_call = handle_method_call, +}; + +static const GDBusInterfaceVTable interface_vtable2 = +{ + .method_call = handle_method_call2, +}; + +static void +on_bus_gotten (GObject *source_object, + GAsyncResult *res, + MsdXrandrManager *manager) +{ + GDBusConnection *connection; + GError *error = NULL; + + connection = g_bus_get_finish (res, &error); + if (connection == NULL) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Could not get session bus: %s", error->message); + g_error_free (error); + return; + } + manager->priv->connection = connection; + + g_dbus_connection_register_object (connection, + MSD_XRANDR_DBUS_PATH, + manager->priv->introspection_data->interfaces[0], + &interface_vtable, + manager, + NULL, + NULL); + g_dbus_connection_register_object (connection, + MSD_XRANDR_DBUS_PATH, + manager->priv->introspection_data->interfaces[1], + &interface_vtable2, + manager, + NULL, + NULL); + + manager->priv->owner_id = g_bus_own_name_on_connection (manager->priv->connection, + MSD_DBUS_NAME, + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, + NULL, NULL, NULL, NULL); +} + +static void +register_manager_dbus (MsdXrandrManager *manager) +{ + manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + manager->priv->bus_cancellable = g_cancellable_new (); + g_bus_get (G_BUS_TYPE_SESSION, + manager->priv->bus_cancellable, + (GAsyncReadyCallback) on_bus_gotten, + manager); } MsdXrandrManager * @@ -2747,10 +2853,7 @@ msd_xrandr_manager_new (void) g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); - if (!register_manager_dbus (manager_object)) { - g_object_unref (manager_object); - return NULL; - } + register_manager_dbus (manager_object); } return MSD_XRANDR_MANAGER (manager_object); |