diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/gpm-backlight-helper.c | 5 | ||||
-rw-r--r-- | src/gpm-backlight.c | 26 | ||||
-rw-r--r-- | src/gpm-button.c | 105 | ||||
-rw-r--r-- | src/gpm-button.h | 3 | ||||
-rw-r--r-- | src/gpm-common.c | 4 | ||||
-rw-r--r-- | src/gpm-common.h | 4 | ||||
-rw-r--r-- | src/gpm-control.c | 266 | ||||
-rw-r--r-- | src/gpm-graph-widget.c | 32 | ||||
-rw-r--r-- | src/gpm-kbd-backlight.c | 14 | ||||
-rw-r--r-- | src/gpm-main.c | 8 | ||||
-rw-r--r-- | src/gpm-manager.c | 56 | ||||
-rw-r--r-- | src/gpm-phone.h | 6 | ||||
-rw-r--r-- | src/gpm-prefs-core.c | 219 | ||||
-rw-r--r-- | src/gpm-statistics.c | 5 | ||||
-rw-r--r-- | src/gsd-media-keys-window.c | 551 | ||||
-rw-r--r-- | src/gsd-media-keys-window.h | 81 | ||||
-rw-r--r-- | src/msd-osd-window.c | 697 | ||||
-rw-r--r-- | src/msd-osd-window.h | 102 |
19 files changed, 1365 insertions, 823 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e518903..ddbb6ed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,6 +38,7 @@ AM_CPPFLAGS = \ -DEGG_LOGGING="\"GPM_LOGGING\"" \ -DEGG_CONSOLE="\"GPM_CONSOLE\"" \ -I$(top_srcdir) \ + $(DISABLE_DEPRECATED) \ $(NULL) bin_PROGRAMS = \ @@ -178,6 +179,8 @@ mate_power_manager_SOURCES = \ gpm-stock-icons.h \ gsd-media-keys-window.h \ gsd-media-keys-window.c \ + msd-osd-window.h \ + msd-osd-window.c \ gpm-engine.h \ gpm-engine.c \ $(NULL) @@ -195,7 +198,6 @@ mate_power_manager_LDADD = \ $(LIBNOTIFY_LIBS) \ $(GPM_EXTRA_LIBS) \ $(UPOWER_LIBS) \ - $(SYSTEMD_INHIBIT_LIBS) \ -lm mate_power_manager_CFLAGS = \ diff --git a/src/gpm-backlight-helper.c b/src/gpm-backlight-helper.c index a9c0fd4..07ad25f 100644 --- a/src/gpm-backlight-helper.c +++ b/src/gpm-backlight-helper.c @@ -53,9 +53,12 @@ gcm_backlight_helper_get_best_backlight () static const gchar *backlight_interfaces[] = { "nv_backlight", "nvidia_backlight", + "intel_backlight", + "dell_backlight", "asus_laptop", "toshiba", "eeepc", + "eeepc-wmi", "thinkpad_screen", "acpi_video1", "mbp_backlight", @@ -175,8 +178,10 @@ main (gint argc, gchar *argv[]) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); +#if !GLIB_CHECK_VERSION(2,36,0) /* setup type system */ g_type_init (); +#endif context = g_option_context_new (NULL); /* TRANSLATORS: tool that is used when copying profiles system-wide */ diff --git a/src/gpm-backlight.c b/src/gpm-backlight.c index c2d58e2..1f1d834 100644 --- a/src/gpm-backlight.c +++ b/src/gpm-backlight.c @@ -66,7 +66,7 @@ struct GpmBacklightPrivate GpmControl *control; GpmDpms *dpms; GpmIdle *idle; - EggConsoleKit *consolekit; + EggConsoleKit *console; gboolean can_dim; gboolean system_is_idle; GTimer *idle_timer; @@ -175,14 +175,14 @@ static void gpm_backlight_dialog_init (GpmBacklight *backlight) { if (backlight->priv->popup != NULL - && !gsd_media_keys_window_is_valid (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup))) { + && !msd_osd_window_is_valid (MSD_OSD_WINDOW (backlight->priv->popup))) { gtk_widget_destroy (backlight->priv->popup); backlight->priv->popup = NULL; } if (backlight->priv->popup == NULL) { - backlight->priv->popup= gsd_media_keys_window_new (); - gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), + backlight->priv->popup= msd_media_keys_window_new (); + msd_media_keys_window_set_action_custom (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), "gpm-brightness-lcd", TRUE); gtk_window_set_position (GTK_WINDOW (backlight->priv->popup), GTK_WIN_POS_NONE); @@ -351,7 +351,7 @@ gpm_backlight_brightness_evaluate_and_set (GpmBacklight *backlight, gboolean int /* only show dialog if interactive */ if (interactive) { gpm_backlight_dialog_init (backlight); - gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), + msd_media_keys_window_set_volume_level (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), round (brightness)); gpm_backlight_dialog_show (backlight); } @@ -439,7 +439,7 @@ gpm_backlight_button_pressed_cb (GpmButton *button, const gchar *type, GpmBackli if (ret) { gpm_brightness_get (backlight->priv->brightness, &percentage); gpm_backlight_dialog_init (backlight); - gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), + msd_media_keys_window_set_volume_level (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), percentage); gpm_backlight_dialog_show (backlight); /* save the new percentage */ @@ -458,7 +458,7 @@ gpm_backlight_button_pressed_cb (GpmButton *button, const gchar *type, GpmBackli if (ret) { gpm_brightness_get (backlight->priv->brightness, &percentage); gpm_backlight_dialog_init (backlight); - gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), + msd_media_keys_window_set_volume_level (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), percentage); gpm_backlight_dialog_show (backlight); /* save the new percentage */ @@ -554,8 +554,8 @@ idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmBacklight *backlight) if (gpm_button_is_lid_closed (backlight->priv->button)) return; - /* don't dim or undim the screen unless we are on the active console */ - if (!egg_console_kit_is_active (backlight->priv->consolekit)) { + /* don't dim or undim the screen unless ConsoleKit/systemd say we are on the active console */ + if (!LOGIND_RUNNING() && !egg_console_kit_is_active (backlight->priv->console)) { egg_debug ("ignoring as not on active console"); return; } @@ -677,7 +677,7 @@ gpm_backlight_finalize (GObject *object) g_object_unref (backlight->priv->button); g_object_unref (backlight->priv->idle); g_object_unref (backlight->priv->brightness); - g_object_unref (backlight->priv->consolekit); + g_object_unref (backlight->priv->console); g_return_if_fail (backlight->priv != NULL); G_OBJECT_CLASS (gpm_backlight_parent_class)->finalize (object); @@ -757,8 +757,8 @@ gpm_backlight_init (GpmBacklight *backlight) gpm_idle_set_timeout_dim (backlight->priv->idle, backlight->priv->idle_dim_timeout); /* use a visual widget */ - backlight->priv->popup = gsd_media_keys_window_new (); - gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), + backlight->priv->popup = msd_media_keys_window_new (); + msd_media_keys_window_set_action_custom (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), "gpm-brightness-lcd", TRUE); gtk_window_set_position (GTK_WINDOW (backlight->priv->popup), GTK_WIN_POS_NONE); @@ -772,7 +772,7 @@ gpm_backlight_init (GpmBacklight *backlight) G_CALLBACK (control_resume_cb), backlight); /* Don't do dimming on inactive console */ - backlight->priv->consolekit = egg_console_kit_new (); + backlight->priv->console = egg_console_kit_new (); /* sync at startup */ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE, TRUE); diff --git a/src/gpm-button.c b/src/gpm-button.c index 4f9f171..1e38173 100644 --- a/src/gpm-button.c +++ b/src/gpm-button.c @@ -249,65 +249,60 @@ gpm_button_class_init (GpmButtonClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); } -#ifdef WITH_SYSTEMD_SLEEP -gboolean gpm_button_get_lid_closed() -{ - - GDBusProxy *proxy; - GVariant *res, *inner; - gboolean lid; -GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - "org.freedesktop.UPower", - "/org/freedesktop/UPower", - "org.freedesktop.DBus.Properties", - NULL, - &error ); - if (proxy == NULL) { - egg_error("Error connecting to dbus - %s", error->message); - g_error_free (error); - return -1; - } - - res = g_dbus_proxy_call_sync (proxy, "Get", - g_variant_new( "(ss)", - "org.freedesktop.UPower", - "LidIsClosed"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error - ); - if (error == NULL && res != NULL) { - g_variant_get(res, "(v)", &inner ); - lid = g_variant_get_boolean(inner); - g_variant_unref (inner); - g_variant_unref (res); - return lid; - } else if (error != NULL ) { - egg_error ("Error in dbus - %s", error->message); - g_error_free (error); - } - g_object_unref(proxy); - - return FALSE; -} -#endif - /** * gpm_button_is_lid_closed: **/ gboolean gpm_button_is_lid_closed (GpmButton *button) { + GDBusProxy *proxy; + GVariant *res, *inner; + gboolean lid; + GError *error = NULL; + g_return_val_if_fail (GPM_IS_BUTTON (button), FALSE); -#ifdef WITH_SYSTEMD_SLEEP - return gpm_button_get_lid_closed(); -#else - return up_client_get_lid_is_closed (button->priv->client); -#endif + + if (LOGIND_RUNNING()) { + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.UPower", + "/org/freedesktop/UPower", + "org.freedesktop.DBus.Properties", + NULL, + &error ); + if (proxy == NULL) { + egg_error("Error connecting to dbus - %s", error->message); + g_error_free (error); + return -1; + } + + res = g_dbus_proxy_call_sync (proxy, "Get", + g_variant_new( "(ss)", + "org.freedesktop.UPower", + "LidIsClosed"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error + ); + if (error == NULL && res != NULL) { + g_variant_get(res, "(v)", &inner ); + lid = g_variant_get_boolean(inner); + g_variant_unref (inner); + g_variant_unref (res); + return lid; + } else if (error != NULL ) { + egg_error ("Error in dbus - %s", error->message); + g_error_free (error); + } + g_object_unref(proxy); + + return FALSE; + } + else { + return up_client_get_lid_is_closed (button->priv->client); + } } @@ -334,11 +329,7 @@ gpm_button_client_changed_cb (UpClient *client, GpmButton *button) gboolean lid_is_closed; /* get new state */ -#ifdef WITH_SYSTEMD_SLEEP - lid_is_closed = gpm_button_get_lid_closed(); -#else - lid_is_closed = up_client_get_lid_is_closed (button->priv->client); -#endif + lid_is_closed = gpm_button_is_lid_closed(button); /* same state */ if (button->priv->lid_is_closed == lid_is_closed) diff --git a/src/gpm-button.h b/src/gpm-button.h index 7d60334..8992007 100644 --- a/src/gpm-button.h +++ b/src/gpm-button.h @@ -66,9 +66,6 @@ typedef struct GType gpm_button_get_type (void); GpmButton *gpm_button_new (void); gboolean gpm_button_is_lid_closed (GpmButton *button); -#ifdef WITH_SYSTEMD_SLEEP -gboolean gpm_button_get_lid_closed (); -#endif gboolean gpm_button_reset_time (GpmButton *button); G_END_DECLS diff --git a/src/gpm-common.c b/src/gpm-common.c index e7d1d66..2c55d97 100644 --- a/src/gpm-common.c +++ b/src/gpm-common.c @@ -135,9 +135,9 @@ gpm_help_display (const gchar *link_id) gchar *uri; if (link_id != NULL) - uri = g_strconcat ("ghelp:mate-power-manager?", link_id, NULL); + uri = g_strconcat ("help:mate-power-manager?", link_id, NULL); else - uri = g_strdup ("ghelp:mate-power-manager"); + uri = g_strdup ("help:mate-power-manager"); gtk_show_uri (NULL, uri, GDK_CURRENT_TIME, &error); diff --git a/src/gpm-common.h b/src/gpm-common.h index 1c83268..ef20f88 100644 --- a/src/gpm-common.h +++ b/src/gpm-common.h @@ -24,8 +24,12 @@ #include <glib.h> +#include <unistd.h> + G_BEGIN_DECLS +#define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0) + #define GPM_DBUS_SERVICE "org.mate.PowerManager" #define GPM_DBUS_INTERFACE "org.mate.PowerManager" #define GPM_DBUS_INTERFACE_BACKLIGHT "org.mate.PowerManager.Backlight" diff --git a/src/gpm-control.c b/src/gpm-control.c index 71f857c..ec50136 100644 --- a/src/gpm-control.c +++ b/src/gpm-control.c @@ -39,10 +39,11 @@ #include <glib/gi18n.h> #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> +#define UPOWER_ENABLE_DEPRECATED #include <libupower-glib/upower.h> #ifdef WITH_KEYRING -#include <mate-keyring.h> +#include <gnome-keyring.h> #endif /* WITH_KEYRING */ #include "egg-debug.h" @@ -86,6 +87,50 @@ gpm_control_error_quark (void) } /** + * gpm_manager_systemd_shutdown: + * + * Shutdown the system using systemd-logind. + * + * Return value: fd, -1 on error + **/ +static gboolean +gpm_control_systemd_shutdown (void) { + GError *error = NULL; + GDBusProxy *proxy; + + egg_debug ("Requesting systemd to shutdown"); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + NULL, + &error ); + //append all our arguments + if (proxy == NULL) { + egg_error("Error connecting to dbus - %s", error->message); + g_error_free (error); + return FALSE; + } + + g_dbus_proxy_call_sync (proxy, "PowerOff", + g_variant_new( "(b)", FALSE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error + ); + if (error != NULL) { + egg_error ("Error in dbus - %s", error->message); + g_error_free (error); + return FALSE; + } + + return TRUE; +} + +/** * gpm_control_shutdown: * @control: This class instance * @@ -96,9 +141,14 @@ gpm_control_shutdown (GpmControl *control, GError **error) { gboolean ret; EggConsoleKit *console; - console = egg_console_kit_new (); - ret = egg_console_kit_stop (console, error); - g_object_unref (console); + + if (LOGIND_RUNNING()) { + ret = gpm_control_systemd_shutdown (); + } else { + console = egg_console_kit_new (); + ret = egg_console_kit_stop (console, error); + g_object_unref (console); + } return ret; } @@ -163,33 +213,32 @@ gpm_control_suspend (GpmControl *control, GError **error) GpmScreensaver *screensaver; guint32 throttle_cookie = 0; #ifdef WITH_KEYRING - gboolean lock_mate_keyring; - MateKeyringResult keyres; + gboolean lock_gnome_keyring; + GnomeKeyringResult keyres; #endif /* WITH_KEYRING */ -#ifdef WITH_SYSTEMD_SLEEP + GError *dbus_error = NULL; - DBusGProxy *proxy; - GVariant *res; -#endif + GDBusProxy *proxy; screensaver = gpm_screensaver_new (); -#ifndef WITH_SYSTEMD_SLEEP - g_object_get (control->priv->client, - "can-suspend", &allowed, - NULL); - if (!allowed) { - egg_debug ("cannot suspend as not allowed from policy"); - g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot suspend"); - goto out; + + if (!LOGIND_RUNNING()) { + g_object_get (control->priv->client, + "can-suspend", &allowed, + NULL); + if (!allowed) { + egg_debug ("cannot suspend as not allowed from policy"); + g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot suspend"); + goto out; + } } -#endif #ifdef WITH_KEYRING /* we should perhaps lock keyrings when sleeping #375681 */ - lock_mate_keyring = g_settings_get_boolean (control->priv->settings, GPM_SETTINGS_LOCK_KEYRING_SUSPEND); - if (lock_mate_keyring) { - keyres = mate_keyring_lock_all_sync (); - if (keyres != MATE_KEYRING_RESULT_OK) + lock_gnome_keyring = g_settings_get_boolean (control->priv->settings, GPM_SETTINGS_LOCK_KEYRING_SUSPEND); + if (lock_gnome_keyring) { + keyres = gnome_keyring_lock_all_sync (); + if (keyres != GNOME_KEYRING_RESULT_OK) egg_warning ("could not lock keyring"); } #endif /* WITH_KEYRING */ @@ -208,40 +257,41 @@ gpm_control_suspend (GpmControl *control, GError **error) egg_debug ("emitting sleep"); g_signal_emit (control, signals [SLEEP], 0, GPM_CONTROL_ACTION_SUSPEND); -#ifdef WITH_SYSTEMD_SLEEP - /* sleep via logind */ - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - NULL, - &dbus_error ); - if (proxy == NULL) { - egg_error("Error connecting to dbus - %s", dbus_error->message); - g_error_free (dbus_error); - return -1; - } - g_dbus_proxy_call_sync (proxy, "Suspend", - g_variant_new( "(b)",FALSE), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &dbus_error - ); - if (dbus_error != NULL ) { - egg_debug ("Error in dbus - %s", dbus_error->message); - g_error_free (dbus_error); - ret = TRUE; - } - else { - ret = TRUE; - } - g_object_unref(proxy); -#else - ret = up_client_suspend_sync (control->priv->client, NULL, error); -#endif + if (LOGIND_RUNNING()) { + /* sleep via logind */ + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + NULL, + &dbus_error ); + if (proxy == NULL) { + egg_error("Error connecting to dbus - %s", dbus_error->message); + g_error_free (dbus_error); + return -1; + } + g_dbus_proxy_call_sync (proxy, "Suspend", + g_variant_new( "(b)",FALSE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &dbus_error + ); + if (dbus_error != NULL ) { + egg_debug ("Error in dbus - %s", dbus_error->message); + g_error_free (dbus_error); + ret = TRUE; + } + else { + ret = TRUE; + } + g_object_unref(proxy); + } + else { + ret = up_client_suspend_sync (control->priv->client, NULL, error); + } egg_debug ("emitting resume"); g_signal_emit (control, signals [RESUME], 0, GPM_CONTROL_ACTION_SUSPEND); @@ -274,34 +324,32 @@ gpm_control_hibernate (GpmControl *control, GError **error) GpmScreensaver *screensaver; guint32 throttle_cookie = 0; #ifdef WITH_KEYRING - gboolean lock_mate_keyring; - MateKeyringResult keyres; + gboolean lock_gnome_keyring; + GnomeKeyringResult keyres; #endif /* WITH_KEYRING */ -#ifdef WITH_SYSTEMD_SLEEP GError *dbus_error = NULL; - DBusGProxy *proxy; -#endif + GDBusProxy *proxy; screensaver = gpm_screensaver_new (); -#ifndef WITH_SYSTEMD_SLEEP - g_object_get (control->priv->client, - "can-hibernate", &allowed, - NULL); - if (!allowed) { - egg_debug ("cannot hibernate as not allowed from policy"); - g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot hibernate"); - goto out; + if (!LOGIND_RUNNING()) { + g_object_get (control->priv->client, + "can-hibernate", &allowed, + NULL); + if (!allowed) { + egg_debug ("cannot hibernate as not allowed from policy"); + g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot hibernate"); + goto out; + } } -#endif #ifdef WITH_KEYRING /* we should perhaps lock keyrings when sleeping #375681 */ - lock_mate_keyring = g_settings_get_boolean (control->priv->settings, GPM_SETTINGS_LOCK_KEYRING_HIBERNATE); - if (lock_mate_keyring) { - keyres = mate_keyring_lock_all_sync (); - if (keyres != MATE_KEYRING_RESULT_OK) { + lock_gnome_keyring = g_settings_get_boolean (control->priv->settings, GPM_SETTINGS_LOCK_KEYRING_HIBERNATE); + if (lock_gnome_keyring) { + keyres = gnome_keyring_lock_all_sync (); + if (keyres != GNOME_KEYRING_RESULT_OK) { egg_warning ("could not lock keyring"); } } @@ -320,39 +368,41 @@ gpm_control_hibernate (GpmControl *control, GError **error) egg_debug ("emitting sleep"); g_signal_emit (control, signals [SLEEP], 0, GPM_CONTROL_ACTION_HIBERNATE); -#ifdef WITH_SYSTEMD_SLEEP - /* sleep via logind */ - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - NULL, - &dbus_error ); - if (proxy == NULL) { - egg_error("Error connecting to dbus - %s", dbus_error->message); - g_error_free (dbus_error); - return -1; - } - g_dbus_proxy_call_sync (proxy, "Hibernate", - g_variant_new( "(b)",FALSE), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &dbus_error - ); - if (dbus_error != NULL ) { - egg_debug ("Error in dbus - %s", dbus_error->message); - g_error_free (dbus_error); - ret = TRUE; - } - else { - ret = TRUE; - } -#else - ret = up_client_hibernate_sync (control->priv->client, NULL, error); -#endif + if (LOGIND_RUNNING()) { + /* sleep via logind */ + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + NULL, + &dbus_error ); + if (proxy == NULL) { + egg_error("Error connecting to dbus - %s", dbus_error->message); + g_error_free (dbus_error); + return -1; + } + g_dbus_proxy_call_sync (proxy, "Hibernate", + g_variant_new( "(b)",FALSE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &dbus_error + ); + if (dbus_error != NULL ) { + egg_debug ("Error in dbus - %s", dbus_error->message); + g_error_free (dbus_error); + ret = TRUE; + } + else { + ret = TRUE; + } + } + else { + ret = up_client_hibernate_sync (control->priv->client, NULL, error); + } + egg_debug ("emitting resume"); g_signal_emit (control, signals [RESUME], 0, GPM_CONTROL_ACTION_HIBERNATE); diff --git a/src/gpm-graph-widget.c b/src/gpm-graph-widget.c index 5d74dce..44ca047 100644 --- a/src/gpm-graph-widget.c +++ b/src/gpm-graph-widget.c @@ -33,6 +33,10 @@ #include "egg-color.h" #include "egg-precision.h" +#if GTK_CHECK_VERSION (3, 0, 0) +#include <math.h> +#endif + G_DEFINE_TYPE (GpmGraphWidget, gpm_graph_widget, GTK_TYPE_DRAWING_AREA); #define GPM_GRAPH_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_GRAPH_WIDGET, GpmGraphWidgetPrivate)) #define GPM_GRAPH_WIDGET_FONT "Sans 8" @@ -69,7 +73,11 @@ struct GpmGraphWidgetPrivate GPtrArray *plot_list; }; +#if GTK_CHECK_VERSION (3, 0, 0) +static gboolean gpm_graph_widget_draw (GtkWidget *graph, cairo_t *cr); +#else static gboolean gpm_graph_widget_expose (GtkWidget *graph, GdkEventExpose *event); +#endif static void gpm_graph_widget_finalize (GObject *object); enum @@ -233,7 +241,11 @@ gpm_graph_widget_class_init (GpmGraphWidgetClass *class) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); GObjectClass *object_class = G_OBJECT_CLASS (class); +#if GTK_CHECK_VERSION (3, 0, 0) + widget_class->draw = gpm_graph_widget_draw; +#else widget_class->expose_event = gpm_graph_widget_expose; +#endif object_class->get_property = up_graph_get_property; object_class->set_property = up_graph_set_property; object_class->finalize = gpm_graph_widget_finalize; @@ -1140,8 +1152,25 @@ gpm_graph_widget_draw_graph (GtkWidget *graph_widget, cairo_t *cr) * Just repaint the entire graph widget on expose. **/ static gboolean +#if GTK_CHECK_VERSION (3, 0, 0) +gpm_graph_widget_draw (GtkWidget *graph, cairo_t *cr) +#else gpm_graph_widget_expose (GtkWidget *graph, GdkEventExpose *event) +#endif { +#if GTK_CHECK_VERSION (3, 0, 0) + GdkRectangle area; + gdouble x1, y1, x2, y2; + + cairo_clip_extents (cr, &x1, &y1, &x2, &y2); + area.x = floor (x1); + area.y = floor (y1); + area.width = ceil (x2) - area.x; + area.height = ceil (y2) - area.y; + cairo_rectangle (cr, + area.x, area.y, + area.width, area.height); +#else cairo_t *cr; /* get a cairo_t */ @@ -1149,12 +1178,15 @@ gpm_graph_widget_expose (GtkWidget *graph, GdkEventExpose *event) cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height); +#endif cairo_clip (cr); ((GpmGraphWidget *)graph)->priv->cr = cr; gpm_graph_widget_draw_graph (graph, cr); +#if GTK_CHECK_VERSION (3, 0, 0) cairo_destroy (cr); +#endif return FALSE; } diff --git a/src/gpm-kbd-backlight.c b/src/gpm-kbd-backlight.c index 5bb8ae2..0ac6801 100644 --- a/src/gpm-kbd-backlight.c +++ b/src/gpm-kbd-backlight.c @@ -144,14 +144,14 @@ static void gpm_kbd_backlight_dialog_init (GpmKbdBacklight *backlight) { if (backlight->priv->popup != NULL - && !gsd_media_keys_window_is_valid (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup))) { + && !msd_osd_window_is_valid (MSD_OSD_WINDOW (backlight->priv->popup))) { gtk_widget_destroy (backlight->priv->popup); backlight->priv->popup = NULL; } if (backlight->priv->popup == NULL) { - backlight->priv->popup= gsd_media_keys_window_new (); - gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), + backlight->priv->popup= msd_media_keys_window_new (); + msd_media_keys_window_set_action_custom (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), "gpm-brightness-kbd", TRUE); gtk_window_set_position (GTK_WINDOW (backlight->priv->popup), GTK_WIN_POS_NONE); @@ -510,7 +510,7 @@ gpm_kbd_backlight_button_pressed_cb (GpmButton *button, if (ret) { egg_debug("Going to display OSD"); gpm_kbd_backlight_dialog_init (backlight); - gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), backlight->priv->brightness_percent); + msd_media_keys_window_set_volume_level (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), backlight->priv->brightness_percent); gpm_kbd_backlight_dialog_show (backlight); } @@ -520,7 +520,7 @@ gpm_kbd_backlight_button_pressed_cb (GpmButton *button, if (ret) { egg_debug("Going to display OSD"); gpm_kbd_backlight_dialog_init (backlight); - gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), backlight->priv->brightness_percent); + msd_media_keys_window_set_volume_level (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), backlight->priv->brightness_percent); gpm_kbd_backlight_dialog_show (backlight); } @@ -770,8 +770,8 @@ noerr: G_CALLBACK (gpm_kbd_backlight_idle_changed_cb), backlight); /* use a visual widget */ - backlight->priv->popup = gsd_media_keys_window_new (); - gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), + backlight->priv->popup = msd_media_keys_window_new (); + msd_media_keys_window_set_action_custom (MSD_MEDIA_KEYS_WINDOW (backlight->priv->popup), "gpm-brightness-kbd", TRUE); gtk_window_set_position (GTK_WINDOW (backlight->priv->popup), GTK_WIN_POS_NONE); diff --git a/src/gpm-main.c b/src/gpm-main.c index 064ccf3..054cf3b 100644 --- a/src/gpm-main.c +++ b/src/gpm-main.c @@ -183,13 +183,14 @@ main (int argc, char *argv[]) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); -#if GLIB_CHECK_VERSION(2,32,0) -#else +#if !GLIB_CHECK_VERSION(2,32,0) if (! g_thread_supported ()) g_thread_init (NULL); #endif dbus_g_thread_init (); +#if !GLIB_CHECK_VERSION(2,36,0) g_type_init (); +#endif context = g_option_context_new (N_("MATE Power Manager")); /* TRANSLATORS: program name, a simple app to view pending updates */ @@ -203,8 +204,7 @@ main (int argc, char *argv[]) goto unref_program; } -#if GLIB_CHECK_VERSION(2,32,0) -#else +#if !GLIB_CHECK_VERSION(2,32,0) if (!g_thread_supported ()) g_thread_init (NULL); #endif diff --git a/src/gpm-manager.c b/src/gpm-manager.c index 6f403a9..6ca9dea 100644 --- a/src/gpm-manager.c +++ b/src/gpm-manager.c @@ -33,11 +33,9 @@ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ -#ifdef WITH_SYSTEMD_INHIBIT -#include <systemd/sd-daemon.h> -#endif /* WITH_SYSTEMD_INHIBIT */ #include <glib/gi18n.h> +#include <gio/gunixfdlist.h> #include <gtk/gtk.h> #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> @@ -104,10 +102,8 @@ struct GpmManagerPrivate NotifyNotification *notification_warning_low; NotifyNotification *notification_discharging; NotifyNotification *notification_fully_charged; -#ifdef WITH_SYSTEMD_INHIBIT gint32 systemd_inhibit; GDBusProxy *systemd_inhibit_proxy; -#endif }; typedef enum { @@ -780,8 +776,8 @@ gpm_manager_idle_do_sleep (GpmManager *manager) static void gpm_manager_idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmManager *manager) { - /* ConsoleKit says we are not on active console */ - if (!egg_console_kit_is_active (manager->priv->console)) { + /* ConsoleKit/systemd say we are not on active console */ + if (!LOGIND_RUNNING() && !egg_console_kit_is_active (manager->priv->console)) { egg_debug ("ignoring as not on active console"); return; } @@ -909,8 +905,8 @@ gpm_manager_button_pressed_cb (GpmButton *button, const gchar *type, GpmManager gchar *message; egg_debug ("Button press event type=%s", type); - /* ConsoleKit says we are not on active console */ - if (!egg_console_kit_is_active (manager->priv->console)) { + /* ConsoleKit/systemd say we are not on active console */ + if (!LOGIND_RUNNING() && !egg_console_kit_is_active (manager->priv->console)) { egg_debug ("ignoring as not on active console"); return; } @@ -1009,8 +1005,8 @@ gpm_manager_client_changed_cb (UpClient *client, GpmManager *manager) /* save in local cache */ manager->priv->on_battery = on_battery; - /* ConsoleKit says we are not on active console */ - if (!egg_console_kit_is_active (manager->priv->console)) { + /* ConsoleKit/systemd say we are not on active console */ + if (!LOGIND_RUNNING() && !egg_console_kit_is_active (manager->priv->console)) { egg_debug ("ignoring as not on active console"); return; } @@ -1848,9 +1844,8 @@ gpm_manager_control_resume_cb (GpmControl *control, GpmControlAction action, Gpm g_timeout_add_seconds (1, gpm_manager_reset_just_resumed_cb, manager); } -#ifdef WITH_SYSTEMD_INHIBIT /** - * gpm_main_system_inhibit: + * gpm_main_systemd_inhibit: * * Return a fd to the to the inhibitor, that we can close on exit. * @@ -1918,7 +1913,6 @@ gpm_manager_systemd_inhibit (GDBusProxy *proxy) { egg_debug ("Inhibiting systemd sleep - success"); return r; } -#endif /** * gpm_manager_init: @@ -1930,20 +1924,17 @@ gpm_manager_init (GpmManager *manager) gboolean check_type_cpu; gint timeout; DBusGConnection *connection; - GDBusConnection *g_connection; + GDBusConnection *g_connection; GError *error = NULL; manager->priv = GPM_MANAGER_GET_PRIVATE (manager); connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - g_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - -#ifdef WITH_SYSTEMD_INHIBIT - /* We want to inhibit the systemd suspend options, and take care of them ourselves */ - if (sd_booted() > 0) { - manager->priv->systemd_inhibit = gpm_manager_systemd_inhibit (manager->priv->systemd_inhibit_proxy); - } + g_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); -#endif + /* We want to inhibit the systemd suspend options, and take care of them ourselves */ + if (LOGIND_RUNNING()) { + manager->priv->systemd_inhibit = gpm_manager_systemd_inhibit (manager->priv->systemd_inhibit_proxy); + } /* init to unthrottled */ manager->priv->screensaver_ac_throttle_id = 0; @@ -2104,16 +2095,15 @@ gpm_manager_finalize (GObject *object) g_object_unref (manager->priv->client); g_object_unref (manager->priv->status_icon); -#ifdef WITH_SYSTEMD_INHIBIT - /* Let systemd take over again ... */ - if (manager->priv->systemd_inhibit > 0) { - close(manager->priv->systemd_inhibit); - } - if (manager->priv->systemd_inhibit_proxy != NULL) { - g_object_unref (manager->priv->systemd_inhibit_proxy); - } - //g_object_unref (manager->priv->systemd_inhibit); -#endif + if (LOGIND_RUNNING()) { + /* Let systemd take over again ... */ + if (manager->priv->systemd_inhibit > 0) { + close(manager->priv->systemd_inhibit); + } + if (manager->priv->systemd_inhibit_proxy != NULL) { + g_object_unref (manager->priv->systemd_inhibit_proxy); + } + } G_OBJECT_CLASS (gpm_manager_parent_class)->finalize (object); } diff --git a/src/gpm-phone.h b/src/gpm-phone.h index 1d7c3fd..b540539 100644 --- a/src/gpm-phone.h +++ b/src/gpm-phone.h @@ -33,9 +33,9 @@ G_BEGIN_DECLS #define GPM_IS_PHONE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_PHONE)) #define GPM_PHONE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_PHONE, GpmPhoneClass)) -#define MATE_PHONE_MANAGER_DBUS_SERVICE "org.mate.phone" -#define MATE_PHONE_MANAGER_DBUS_PATH "/org/mate/phone/Manager" -#define MATE_PHONE_MANAGER_DBUS_INTERFACE "org.mate.phone.Manager" +#define MATE_PHONE_MANAGER_DBUS_SERVICE "org.gnome.phone" +#define MATE_PHONE_MANAGER_DBUS_PATH "/org/gnome/phone/Manager" +#define MATE_PHONE_MANAGER_DBUS_INTERFACE "org.gnome.phone.Manager" typedef struct GpmPhonePrivate GpmPhonePrivate; diff --git a/src/gpm-prefs-core.c b/src/gpm-prefs-core.c index e84d0b1..7a2662d 100644 --- a/src/gpm-prefs-core.c +++ b/src/gpm-prefs-core.c @@ -30,6 +30,7 @@ #include <dbus/dbus-glib.h> #include <math.h> #include <string.h> +#define UPOWER_ENABLE_DEPRECATED #include <libupower-glib/upower.h> #include "egg-debug.h" @@ -812,11 +813,10 @@ gpm_prefs_init (GpmPrefs *prefs) GpmBrightness *brightness; gboolean ret; guint i; -#ifdef WITH_SYSTEMD_SLEEP + GDBusProxy *proxy; GVariant *res, *inner; gchar * r; -#endif prefs->priv = GPM_PREFS_GET_PRIVATE (prefs); @@ -824,108 +824,129 @@ gpm_prefs_init (GpmPrefs *prefs) prefs->priv->console = egg_console_kit_new (); prefs->priv->settings = g_settings_new (GPM_SETTINGS_SCHEMA); - /* are we allowed to shutdown? */ - prefs->priv->can_shutdown = TRUE; - egg_console_kit_can_stop (prefs->priv->console, &prefs->priv->can_shutdown, NULL); - -#ifdef WITH_SYSTEMD_SLEEP - /* get values from logind */ - + prefs->priv->can_shutdown = FALSE; prefs->priv->can_suspend = FALSE; prefs->priv->can_hibernate = FALSE; - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - NULL, - &error ); - if (proxy == NULL) { - egg_error("Error connecting to dbus - %s", error->message); - g_error_free (error); - return -1; - } - res = g_dbus_proxy_call_sync (proxy, "CanSuspend", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error - ); - if (error == NULL && res != NULL) { - g_variant_get(res,"(s)", &r); - prefs->priv->can_suspend = g_strcmp0(r,"yes")==0?TRUE:FALSE; - g_variant_unref (res); - } else if (error != NULL ) { - egg_error ("Error in dbus - %s", error->message); - g_error_free (error); - } - - res = g_dbus_proxy_call_sync (proxy, "CanHibernate", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error - ); - if (error == NULL && res != NULL) { - g_variant_get(res,"(s)", &r); - prefs->priv->can_hibernate = g_strcmp0(r,"yes")==0?TRUE:FALSE; - g_variant_unref (res); - } else if (error != NULL ) { - egg_error ("Error in dbus - %s", error->message); - g_error_free (error); - } - g_object_unref(proxy); -#else - /* get values from UpClient */ - prefs->priv->can_suspend = up_client_get_can_suspend (prefs->priv->client); - prefs->priv->can_hibernate = up_client_get_can_hibernate (prefs->priv->client); -#endif -#ifdef WITH_SYSTEMD_SLEEP - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - NULL, - "org.freedesktop.UPower", - "/org/freedesktop/UPower", - "org.freedesktop.DBus.Properties", - NULL, - &error ); - if (proxy == NULL) { - egg_error("Error connecting to dbus - %s", error->message); - g_error_free (error); - return -1; - } - - res = g_dbus_proxy_call_sync (proxy, "Get", - g_variant_new( "(ss)", - "org.freedesktop.UPower", - "LidIsPresent"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error - ); - if (error == NULL && res != NULL) { - g_variant_get(res, "(v)", &inner ); - prefs->priv->has_button_lid = g_variant_get_boolean(inner); - g_variant_unref (inner); - g_variant_unref (res); - } else if (error != NULL ) { - egg_error ("Error in dbus - %s", error->message); - g_error_free (error); - } - g_object_unref(proxy); -#else + + if (LOGIND_RUNNING()) { + /* get values from logind */ + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + NULL, + &error ); + if (proxy == NULL) { + egg_error("Error connecting to dbus - %s", error->message); + g_error_free (error); + return; + } + + res = g_dbus_proxy_call_sync (proxy, "CanPowerOff", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error + ); + if (error == NULL && res != NULL) { + g_variant_get(res,"(s)", &r); + prefs->priv->can_shutdown = g_strcmp0(r,"yes")==0?TRUE:FALSE; + g_variant_unref (res); + } else if (error != NULL ) { + egg_error ("Error in dbus - %s", error->message); + g_error_free (error); + } + + res = g_dbus_proxy_call_sync (proxy, "CanSuspend", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error + ); + if (error == NULL && res != NULL) { + g_variant_get(res,"(s)", &r); + prefs->priv->can_suspend = g_strcmp0(r,"yes")==0?TRUE:FALSE; + g_variant_unref (res); + } else if (error != NULL ) { + egg_error ("Error in dbus - %s", error->message); + g_error_free (error); + } + + res = g_dbus_proxy_call_sync (proxy, "CanHibernate", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error + ); + if (error == NULL && res != NULL) { + g_variant_get(res,"(s)", &r); + prefs->priv->can_hibernate = g_strcmp0(r,"yes")==0?TRUE:FALSE; + g_variant_unref (res); + } else if (error != NULL ) { + egg_error ("Error in dbus - %s", error->message); + g_error_free (error); + } + g_object_unref(proxy); + } + else { + /* are we allowed to shutdown? */ + egg_console_kit_can_stop (prefs->priv->console, &prefs->priv->can_shutdown, NULL); + /* get values from UpClient */ + prefs->priv->can_suspend = up_client_get_can_suspend (prefs->priv->client); + prefs->priv->can_hibernate = up_client_get_can_hibernate (prefs->priv->client); + } + + if (LOGIND_RUNNING()) { + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.UPower", + "/org/freedesktop/UPower", + "org.freedesktop.DBus.Properties", + NULL, + &error ); + if (proxy == NULL) { + egg_error("Error connecting to dbus - %s", error->message); + g_error_free (error); + return; + } + + res = g_dbus_proxy_call_sync (proxy, "Get", + g_variant_new( "(ss)", + "org.freedesktop.UPower", + "LidIsPresent"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error + ); + if (error == NULL && res != NULL) { + g_variant_get(res, "(v)", &inner ); + prefs->priv->has_button_lid = g_variant_get_boolean(inner); + g_variant_unref (inner); + g_variant_unref (res); + } else if (error != NULL ) { + egg_error ("Error in dbus - %s", error->message); + g_error_free (error); + } + g_object_unref(proxy); + } + else { #if UP_CHECK_VERSION(0,9,2) - prefs->priv->has_button_lid = up_client_get_lid_is_present (prefs->priv->client); + prefs->priv->has_button_lid = up_client_get_lid_is_present (prefs->priv->client); #else - g_object_get (prefs->priv->client, - "lid-is-present", &prefs->priv->has_button_lid, - NULL); -#endif + g_object_get (prefs->priv->client, + "lid-is-present", &prefs->priv->has_button_lid, + NULL); #endif + } + prefs->priv->has_button_suspend = TRUE; /* find if we have brightness hardware */ diff --git a/src/gpm-statistics.c b/src/gpm-statistics.c index 4813d1f..98b5632 100644 --- a/src/gpm-statistics.c +++ b/src/gpm-statistics.c @@ -1564,13 +1564,14 @@ main (int argc, char *argv[]) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); -#if GLIB_CHECK_VERSION(2,32,0) -#else +#if !GLIB_CHECK_VERSION(2,32,0) if (! g_thread_supported ()) g_thread_init (NULL); #endif dbus_g_thread_init (); +#if !GLIB_CHECK_VERSION(2,36,0) g_type_init (); +#endif context = g_option_context_new (NULL); /* TRANSLATORS: the program name */ diff --git a/src/gsd-media-keys-window.c b/src/gsd-media-keys-window.c index fdc1ea1..67d2402 100644 --- a/src/gsd-media-keys-window.c +++ b/src/gsd-media-keys-window.c @@ -2,19 +2,22 @@ * * Copyright (C) 2006-2007 William Jon McCann <[email protected]> * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2, or (at your option) any later version. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. * */ @@ -29,22 +32,11 @@ #include "gsd-media-keys-window.h" -#define DIALOG_TIMEOUT 2000 /* dialog timeout in ms */ -#define DIALOG_FADE_TIMEOUT 1500 /* timeout before fade starts */ -#define FADE_TIMEOUT 10 /* timeout in ms between each frame of the fade */ - -#define BG_ALPHA 0.75 -#define FG_ALPHA 1.00 +#define MSD_MEDIA_KEYS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MSD_TYPE_MEDIA_KEYS_WINDOW, MsdMediaKeysWindowPrivate)) -#define GSD_MEDIA_KEYS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowPrivate)) - -struct GsdMediaKeysWindowPrivate +struct MsdMediaKeysWindowPrivate { - guint is_composited : 1; - guint hide_timeout_id; - guint fade_timeout_id; - double fade_out_alpha; - GsdMediaKeysWindowAction action; + MsdMediaKeysWindowAction action; char *icon_name; gboolean show_level; @@ -55,97 +47,10 @@ struct GsdMediaKeysWindowPrivate GtkWidget *progress; }; -G_DEFINE_TYPE (GsdMediaKeysWindow, gsd_media_keys_window, GTK_TYPE_WINDOW) - -static gboolean -fade_timeout (GsdMediaKeysWindow *window) -{ - if (window->priv->fade_out_alpha <= 0.0) { - gtk_widget_hide (GTK_WIDGET (window)); - - /* Reset it for the next time */ - window->priv->fade_out_alpha = 1.0; - window->priv->fade_timeout_id = 0; - - return FALSE; - } else { - GdkRectangle rect; - GtkWidget *win = GTK_WIDGET (window); - GtkAllocation allocation; - - window->priv->fade_out_alpha -= 0.10; - - rect.x = 0; - rect.y = 0; - gtk_widget_get_allocation (win, &allocation); - rect.width = allocation.width; - rect.height = allocation.height; - - gtk_widget_realize (win); - gdk_window_invalidate_rect (gtk_widget_get_window (win), &rect, FALSE); - } - - return TRUE; -} - -static gboolean -hide_timeout (GsdMediaKeysWindow *window) -{ - if (window->priv->is_composited) { - window->priv->hide_timeout_id = 0; - window->priv->fade_timeout_id = g_timeout_add (FADE_TIMEOUT, - (GSourceFunc) fade_timeout, - window); - } else { - gtk_widget_hide (GTK_WIDGET (window)); - } - - return FALSE; -} - -static void -remove_hide_timeout (GsdMediaKeysWindow *window) -{ - if (window->priv->hide_timeout_id != 0) { - g_source_remove (window->priv->hide_timeout_id); - window->priv->hide_timeout_id = 0; - } - - if (window->priv->fade_timeout_id != 0) { - g_source_remove (window->priv->fade_timeout_id); - window->priv->fade_timeout_id = 0; - window->priv->fade_out_alpha = 1.0; - } -} - -static void -add_hide_timeout (GsdMediaKeysWindow *window) -{ - int timeout; - - if (window->priv->is_composited) { - timeout = DIALOG_FADE_TIMEOUT; - } else { - timeout = DIALOG_TIMEOUT; - } - window->priv->hide_timeout_id = g_timeout_add (timeout, - (GSourceFunc) hide_timeout, - window); -} +G_DEFINE_TYPE (MsdMediaKeysWindow, msd_media_keys_window, MSD_TYPE_OSD_WINDOW) static void -update_window (GsdMediaKeysWindow *window) -{ - remove_hide_timeout (window); - add_hide_timeout (window); - - if (window->priv->is_composited) { - gtk_widget_queue_draw (GTK_WIDGET (window)); - } -} - -static void -volume_controls_set_visible (GsdMediaKeysWindow *window, +volume_controls_set_visible (MsdMediaKeysWindow *window, gboolean visible) { if (window->priv->progress == NULL) @@ -159,7 +64,7 @@ volume_controls_set_visible (GsdMediaKeysWindow *window, } static void -window_set_icon_name (GsdMediaKeysWindow *window, +window_set_icon_name (MsdMediaKeysWindow *window, const char *name) { if (window->priv->image == NULL) @@ -170,11 +75,11 @@ window_set_icon_name (GsdMediaKeysWindow *window, } static void -action_changed (GsdMediaKeysWindow *window) +action_changed (MsdMediaKeysWindow *window) { - if (! window->priv->is_composited) { + if (!msd_osd_window_is_composited (MSD_OSD_WINDOW (window))) { switch (window->priv->action) { - case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME: + case MSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME: volume_controls_set_visible (window, TRUE); if (window->priv->volume_muted) { @@ -184,7 +89,7 @@ action_changed (GsdMediaKeysWindow *window) } break; - case GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM: + case MSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM: volume_controls_set_visible (window, window->priv->show_level); window_set_icon_name (window, window->priv->icon_name); break; @@ -194,15 +99,15 @@ action_changed (GsdMediaKeysWindow *window) } } - update_window (window); + msd_osd_window_update_and_hide (MSD_OSD_WINDOW (window)); } static void -volume_level_changed (GsdMediaKeysWindow *window) +volume_level_changed (MsdMediaKeysWindow *window) { - update_window (window); + msd_osd_window_update_and_hide (MSD_OSD_WINDOW (window)); - if (!window->priv->is_composited && window->priv->progress != NULL) { + if (!msd_osd_window_is_composited (MSD_OSD_WINDOW (window)) && window->priv->progress != NULL) { double fraction; fraction = (double) window->priv->volume_level / 100.0; @@ -213,11 +118,11 @@ volume_level_changed (GsdMediaKeysWindow *window) } static void -volume_muted_changed (GsdMediaKeysWindow *window) +volume_muted_changed (MsdMediaKeysWindow *window) { - update_window (window); + msd_osd_window_update_and_hide (MSD_OSD_WINDOW (window)); - if (! window->priv->is_composited) { + if (!msd_osd_window_is_composited (MSD_OSD_WINDOW (window))) { if (window->priv->volume_muted) { window_set_icon_name (window, "audio-volume-muted"); } else { @@ -227,46 +132,46 @@ volume_muted_changed (GsdMediaKeysWindow *window) } void -gsd_media_keys_window_set_action (GsdMediaKeysWindow *window, - GsdMediaKeysWindowAction action) +msd_media_keys_window_set_action (MsdMediaKeysWindow *window, + MsdMediaKeysWindowAction action) { - g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); - g_return_if_fail (action == GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); + g_return_if_fail (MSD_IS_MEDIA_KEYS_WINDOW (window)); + g_return_if_fail (action == MSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); if (window->priv->action != action) { window->priv->action = action; action_changed (window); } else { - update_window (window); + msd_osd_window_update_and_hide (MSD_OSD_WINDOW (window)); } } void -gsd_media_keys_window_set_action_custom (GsdMediaKeysWindow *window, +msd_media_keys_window_set_action_custom (MsdMediaKeysWindow *window, const char *icon_name, gboolean show_level) { - g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); + g_return_if_fail (MSD_IS_MEDIA_KEYS_WINDOW (window)); g_return_if_fail (icon_name != NULL); - if (window->priv->action != GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM || + if (window->priv->action != MSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM || g_strcmp0 (window->priv->icon_name, icon_name) != 0 || window->priv->show_level != show_level) { - window->priv->action = GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM; + window->priv->action = MSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM; g_free (window->priv->icon_name); window->priv->icon_name = g_strdup (icon_name); window->priv->show_level = show_level; action_changed (window); } else { - update_window (window); + msd_osd_window_update_and_hide (MSD_OSD_WINDOW (window)); } } void -gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window, +msd_media_keys_window_set_volume_muted (MsdMediaKeysWindow *window, gboolean muted) { - g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); + g_return_if_fail (MSD_IS_MEDIA_KEYS_WINDOW (window)); if (window->priv->volume_muted != muted) { window->priv->volume_muted = muted; @@ -275,10 +180,10 @@ gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window, } void -gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window, +msd_media_keys_window_set_volume_level (MsdMediaKeysWindow *window, int level) { - g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); + g_return_if_fail (MSD_IS_MEDIA_KEYS_WINDOW (window)); if (window->priv->volume_level != level) { window->priv->volume_level = level; @@ -286,60 +191,8 @@ gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window, } } -static void -rounded_rectangle (cairo_t* cr, - gdouble aspect, - gdouble x, - gdouble y, - gdouble corner_radius, - gdouble width, - gdouble height) -{ - gdouble radius = corner_radius / aspect; - - cairo_move_to (cr, x + radius, y); - - cairo_line_to (cr, - x + width - radius, - y); - cairo_arc (cr, - x + width - radius, - y + radius, - radius, - -90.0f * G_PI / 180.0f, - 0.0f * G_PI / 180.0f); - cairo_line_to (cr, - x + width, - y + height - radius); - cairo_arc (cr, - x + width - radius, - y + height - radius, - radius, - 0.0f * G_PI / 180.0f, - 90.0f * G_PI / 180.0f); - cairo_line_to (cr, - x + radius, - y + height); - cairo_arc (cr, - x + radius, - y + height - radius, - radius, - 90.0f * G_PI / 180.0f, - 180.0f * G_PI / 180.0f); - cairo_line_to (cr, - x, - y + radius); - cairo_arc (cr, - x + radius, - y + radius, - radius, - 180.0f * G_PI / 180.0f, - 270.0f * G_PI / 180.0f); - cairo_close_path (cr); -} - static GdkPixbuf * -load_pixbuf (GsdMediaKeysWindow *window, +load_pixbuf (MsdMediaKeysWindow *window, const char *name, int icon_size) { @@ -355,22 +208,9 @@ load_pixbuf (GsdMediaKeysWindow *window, pixbuf = gtk_icon_theme_load_icon (theme, name, icon_size, - GTK_ICON_LOOKUP_FORCE_SVG, + GTK_ICON_LOOKUP_FORCE_SIZE, NULL); - /* make sure the pixbuf is close to the requested size - * this is necessary because GTK_ICON_LOOKUP_FORCE_SVG - * seems to be broken */ - if (pixbuf != NULL) { - int width; - - width = gdk_pixbuf_get_width (pixbuf); - if (width < (float)icon_size * 0.75) { - g_object_unref (pixbuf); - pixbuf = NULL; - } - } - return pixbuf; } @@ -396,10 +236,10 @@ draw_eject (cairo_t *cr, cairo_rel_line_to (cr, -width / 2, -tri_height); cairo_rel_line_to (cr, -width / 2, tri_height); cairo_close_path (cr); - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, MSD_OSD_WINDOW_FG_ALPHA); cairo_fill_preserve (cr); - cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2); + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, MSD_OSD_WINDOW_FG_ALPHA / 2); cairo_set_line_width (cr, 2); cairo_stroke (cr); } @@ -458,12 +298,12 @@ draw_cross (cairo_t *cr, cairo_move_to (cr, cx, cy + size/2.0); cairo_rel_line_to (cr, size, -size); - cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2); + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, MSD_OSD_WINDOW_FG_ALPHA / 2); cairo_set_line_width (cr, 14); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, MSD_OSD_WINDOW_FG_ALPHA); cairo_set_line_width (cr, 10); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_stroke (cr); @@ -497,16 +337,16 @@ draw_speaker (cairo_t *cr, cairo_line_to (cr, _x0, _y0); cairo_close_path (cr); - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, MSD_OSD_WINDOW_FG_ALPHA); cairo_fill_preserve (cr); - cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2); + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, MSD_OSD_WINDOW_FG_ALPHA / 2); cairo_set_line_width (cr, 2); cairo_stroke (cr); } static gboolean -render_speaker (GsdMediaKeysWindow *window, +render_speaker (MsdMediaKeysWindow *window, cairo_t *cr, double _x0, double _y0, @@ -545,7 +385,7 @@ render_speaker (GsdMediaKeysWindow *window, } gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0); - cairo_paint_with_alpha (cr, FG_ALPHA); + cairo_paint_with_alpha (cr, MSD_OSD_WINDOW_FG_ALPHA); g_object_unref (pixbuf); @@ -553,37 +393,7 @@ render_speaker (GsdMediaKeysWindow *window, } static void -color_reverse (const GdkColor *a, - GdkColor *b) -{ - gdouble red; - gdouble green; - gdouble blue; - gdouble h; - gdouble s; - gdouble v; - - red = (gdouble) a->red / 65535.0; - green = (gdouble) a->green / 65535.0; - blue = (gdouble) a->blue / 65535.0; - - gtk_rgb_to_hsv (red, green, blue, &h, &s, &v); - - v = 0.5 + (0.5 - v); - if (v > 1.0) - v = 1.0; - else if (v < 0.0) - v = 0.0; - - gtk_hsv_to_rgb (h, s, v, &red, &green, &blue); - - b->red = red * 65535.0; - b->green = green * 65535.0; - b->blue = blue * 65535.0; -} - -static void -draw_volume_boxes (GsdMediaKeysWindow *window, +draw_volume_boxes (MsdMediaKeysWindow *window, cairo_t *cr, double percentage, double _x0, @@ -604,20 +414,20 @@ draw_volume_boxes (GsdMediaKeysWindow *window, style = gtk_widget_get_style (GTK_WIDGET (window)); /* bar background */ - color_reverse (&style->dark[GTK_STATE_NORMAL], &color); + msd_osd_window_color_reverse (&style->dark[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; - rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height); - cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2); + msd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height); + cairo_set_source_rgba (cr, r, g, b, MSD_OSD_WINDOW_FG_ALPHA / 2); cairo_fill_preserve (cr); /* bar border */ - color_reverse (&style->light[GTK_STATE_NORMAL], &color); + msd_osd_window_color_reverse (&style->light[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; - cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2); + cairo_set_source_rgba (cr, r, g, b, MSD_OSD_WINDOW_FG_ALPHA / 2); cairo_set_line_width (cr, 1); cairo_stroke (cr); @@ -628,13 +438,13 @@ draw_volume_boxes (GsdMediaKeysWindow *window, r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; - rounded_rectangle (cr, 1.0, _x0 + 0.5, _y0 + 0.5, height / 6 - 0.5, x1, height - 1); - cairo_set_source_rgba (cr, r, g, b, FG_ALPHA); + msd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0 + 0.5, _y0 + 0.5, height / 6 - 0.5, x1, height - 1); + cairo_set_source_rgba (cr, r, g, b, MSD_OSD_WINDOW_FG_ALPHA); cairo_fill (cr); } static void -draw_action_volume (GsdMediaKeysWindow *window, +draw_action_volume (MsdMediaKeysWindow *window, cairo_t *cr) { int window_width; @@ -736,7 +546,7 @@ draw_action_volume (GsdMediaKeysWindow *window, } static gboolean -render_custom (GsdMediaKeysWindow *window, +render_custom (MsdMediaKeysWindow *window, cairo_t *cr, double _x0, double _y0, @@ -763,7 +573,7 @@ render_custom (GsdMediaKeysWindow *window, } gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0); - cairo_paint_with_alpha (cr, FG_ALPHA); + cairo_paint_with_alpha (cr, MSD_OSD_WINDOW_FG_ALPHA); g_object_unref (pixbuf); @@ -771,7 +581,7 @@ render_custom (GsdMediaKeysWindow *window, } static void -draw_action_custom (GsdMediaKeysWindow *window, +draw_action_custom (MsdMediaKeysWindow *window, cairo_t *cr) { int window_width; @@ -835,14 +645,20 @@ draw_action_custom (GsdMediaKeysWindow *window, } static void -draw_action (GsdMediaKeysWindow *window, - cairo_t *cr) +#if GTK_CHECK_VERSION (3, 0, 0) +msd_media_keys_window_draw_when_composited (MsdOsdWindow *osd_window, +#else +msd_media_keys_window_expose_when_composited (MsdOsdWindow *osd_window, +#endif + cairo_t *cr) { + MsdMediaKeysWindow *window = MSD_MEDIA_KEYS_WINDOW (osd_window); + switch (window->priv->action) { - case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME: + case MSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME: draw_action_volume (window, cr); break; - case GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM: + case MSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM: draw_action_custom (window, cr); break; default: @@ -850,195 +666,33 @@ draw_action (GsdMediaKeysWindow *window, } } -static gboolean -on_expose_event (GtkWidget *widget, - GdkEventExpose *event, - GsdMediaKeysWindow *window) -{ - cairo_t *context; - cairo_t *cr; - cairo_surface_t *surface; - int width; - int height; - GtkStyle *style; - GdkColor color; - double r, g, b; - - context = gdk_cairo_create (gtk_widget_get_window (widget)); - - style = gtk_widget_get_style (widget); - cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); - gtk_window_get_size (GTK_WINDOW (widget), &width, &height); - - surface = cairo_surface_create_similar (cairo_get_target (context), - CAIRO_CONTENT_COLOR_ALPHA, - width, - height); - - if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { - goto done; - } - - cr = cairo_create (surface); - if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { - goto done; - } - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_paint (cr); - - /* draw a box */ - rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); - color_reverse (&style->bg[GTK_STATE_NORMAL], &color); - r = (float)color.red / 65535.0; - g = (float)color.green / 65535.0; - b = (float)color.blue / 65535.0; - cairo_set_source_rgba (cr, r, g, b, BG_ALPHA); - cairo_fill_preserve (cr); - - color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color); - r = (float)color.red / 65535.0; - g = (float)color.green / 65535.0; - b = (float)color.blue / 65535.0; - cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2); - cairo_set_line_width (cr, 1); - cairo_stroke (cr); - - /* draw action */ - draw_action (window, cr); - - cairo_destroy (cr); - - /* Make sure we have a transparent background */ - cairo_rectangle (context, 0, 0, width, height); - cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); - cairo_fill (context); - - cairo_set_source_surface (context, surface, 0, 0); - cairo_paint_with_alpha (context, window->priv->fade_out_alpha); - - done: - if (surface != NULL) { - cairo_surface_destroy (surface); - } - cairo_destroy (context); - - return FALSE; -} - -static void -gsd_media_keys_window_real_show (GtkWidget *widget) -{ - GsdMediaKeysWindow *window; - - if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->show) { - GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->show (widget); - } - - window = GSD_MEDIA_KEYS_WINDOW (widget); - remove_hide_timeout (window); - add_hide_timeout (window); -} - -static void -gsd_media_keys_window_real_hide (GtkWidget *widget) -{ - GsdMediaKeysWindow *window; - - if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->hide) { - GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->hide (widget); - } - - window = GSD_MEDIA_KEYS_WINDOW (widget); - remove_hide_timeout (window); -} - -static void -gsd_media_keys_window_real_realize (GtkWidget *widget) -{ - GdkColormap *colormap; - GtkAllocation allocation; - GdkBitmap *mask; - cairo_t *cr; - - colormap = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)); - - if (colormap != NULL) { - gtk_widget_set_colormap (widget, colormap); - } - - if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize) { - GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize (widget); - } - - gtk_widget_get_allocation (widget, &allocation); - mask = gdk_pixmap_new (gtk_widget_get_window (widget), - allocation.width, - allocation.height, - 1); - cr = gdk_cairo_create (mask); - - cairo_set_source_rgba (cr, 1., 1., 1., 0.); - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_paint (cr); - - /* make the whole window ignore events */ - gdk_window_input_shape_combine_mask (gtk_widget_get_window (widget), mask, 0, 0); - g_object_unref (mask); - cairo_destroy (cr); -} - static void -gsd_media_keys_window_class_init (GsdMediaKeysWindowClass *klass) +msd_media_keys_window_class_init (MsdMediaKeysWindowClass *klass) { - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - widget_class->show = gsd_media_keys_window_real_show; - widget_class->hide = gsd_media_keys_window_real_hide; - widget_class->realize = gsd_media_keys_window_real_realize; + MsdOsdWindowClass *osd_window_class = MSD_OSD_WINDOW_CLASS (klass); - g_type_class_add_private (klass, sizeof (GsdMediaKeysWindowPrivate)); -} +#if GTK_CHECK_VERSION (3, 0, 0) + osd_window_class->draw_when_composited = msd_media_keys_window_draw_when_composited; +#else + osd_window_class->expose_when_composited = msd_media_keys_window_expose_when_composited; +#endif -gboolean -gsd_media_keys_window_is_valid (GsdMediaKeysWindow *window) -{ - GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window)); - return gdk_screen_is_composited (screen) == window->priv->is_composited; + g_type_class_add_private (klass, sizeof (MsdMediaKeysWindowPrivate)); } static void -gsd_media_keys_window_init (GsdMediaKeysWindow *window) +msd_media_keys_window_init (MsdMediaKeysWindow *window) { GdkScreen *screen; - window->priv = GSD_MEDIA_KEYS_WINDOW_GET_PRIVATE (window); + window->priv = MSD_MEDIA_KEYS_WINDOW_GET_PRIVATE (window); screen = gtk_widget_get_screen (GTK_WIDGET (window)); - window->priv->is_composited = gdk_screen_is_composited (screen); - - if (window->priv->is_composited) { - gdouble scalew, scaleh, scale; - gint size; - - gtk_window_set_decorated (GTK_WINDOW (window), FALSE); - gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); - - /* assume 130x130 on a 640x480 display and scale from there */ - scalew = gdk_screen_get_width (screen) / 640.0; - scaleh = gdk_screen_get_height (screen) / 480.0; - scale = MIN (scalew, scaleh); - size = 130 * MAX (1, scale); - - gtk_window_set_default_size (GTK_WINDOW (window), size, size); - g_signal_connect (window, "expose-event", G_CALLBACK (on_expose_event), window); - - window->priv->fade_out_alpha = 1.0; - } else { + if (!msd_osd_window_is_composited (MSD_OSD_WINDOW (window))) { GtkBuilder *builder; - const gchar *objects[] = {"acme_frame", NULL}; - GtkWidget *frame; + const gchar *objects[] = {"acme_box", NULL}; + GtkWidget *box; builder = gtk_builder_new (); gtk_builder_add_objects_from_file (builder, @@ -1048,32 +702,21 @@ gsd_media_keys_window_init (GsdMediaKeysWindow *window) window->priv->image = GTK_IMAGE (gtk_builder_get_object (builder, "acme_image")); window->priv->progress = GTK_WIDGET (gtk_builder_get_object (builder, "acme_volume_progressbar")); - frame = GTK_WIDGET (gtk_builder_get_object (builder, - "acme_frame")); + box = GTK_WIDGET (gtk_builder_get_object (builder, "acme_box")); - if (frame != NULL) { - gtk_container_add (GTK_CONTAINER (window), frame); - gtk_widget_show_all (frame); + if (box != NULL) { + gtk_container_add (GTK_CONTAINER (window), box); + gtk_widget_show_all (box); } /* The builder needs to stay alive until the window - takes ownership of the frame (and its children) */ + takes ownership of the box (and its children) */ g_object_unref (builder); } } GtkWidget * -gsd_media_keys_window_new (void) +msd_media_keys_window_new (void) { - GObject *object; - - object = g_object_new (GSD_TYPE_MEDIA_KEYS_WINDOW, - "type", GTK_WINDOW_POPUP, - "type-hint", GDK_WINDOW_TYPE_HINT_NOTIFICATION, - "skip-taskbar-hint", TRUE, - "skip-pager-hint", TRUE, - "focus-on-map", FALSE, - NULL); - - return GTK_WIDGET (object); + return g_object_new (MSD_TYPE_MEDIA_KEYS_WINDOW, NULL); } diff --git a/src/gsd-media-keys-window.h b/src/gsd-media-keys-window.h index 9abd535..0a3fd01 100644 --- a/src/gsd-media-keys-window.h +++ b/src/gsd-media-keys-window.h @@ -3,69 +3,76 @@ * Copyright (C) 2006 William Jon McCann <[email protected]> * * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more + * details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the + * You should have received a copy of the GNU Lesser General + * Public License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. * */ -#ifndef GSD_MEDIA_KEYS_WINDOW_H -#define GSD_MEDIA_KEYS_WINDOW_H +#ifndef MSD_MEDIA_KEYS_WINDOW_H +#define MSD_MEDIA_KEYS_WINDOW_H #include <glib-object.h> #include <gtk/gtk.h> -G_BEGIN_DECLS +#include "msd-osd-window.h" -#define GSD_TYPE_MEDIA_KEYS_WINDOW (gsd_media_keys_window_get_type ()) -#define GSD_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindow)) -#define GSD_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowClass)) -#define GSD_IS_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_MEDIA_KEYS_WINDOW)) -#define GSD_IS_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), GSD_TYPE_MEDIA_KEYS_WINDOW)) +#ifdef __cplusplus +extern "C" { +#endif + +#define MSD_TYPE_MEDIA_KEYS_WINDOW (msd_media_keys_window_get_type ()) +#define MSD_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MSD_TYPE_MEDIA_KEYS_WINDOW, MsdMediaKeysWindow)) +#define MSD_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MSD_TYPE_MEDIA_KEYS_WINDOW, MsdMediaKeysWindowClass)) +#define MSD_IS_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MSD_TYPE_MEDIA_KEYS_WINDOW)) +#define MSD_IS_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), MSD_TYPE_MEDIA_KEYS_WINDOW)) -typedef struct GsdMediaKeysWindow GsdMediaKeysWindow; -typedef struct GsdMediaKeysWindowClass GsdMediaKeysWindowClass; -typedef struct GsdMediaKeysWindowPrivate GsdMediaKeysWindowPrivate; +typedef struct MsdMediaKeysWindow MsdMediaKeysWindow; +typedef struct MsdMediaKeysWindowClass MsdMediaKeysWindowClass; +typedef struct MsdMediaKeysWindowPrivate MsdMediaKeysWindowPrivate; -struct GsdMediaKeysWindow { - GtkWindow parent; +struct MsdMediaKeysWindow { + MsdOsdWindow parent; - GsdMediaKeysWindowPrivate *priv; + MsdMediaKeysWindowPrivate *priv; }; -struct GsdMediaKeysWindowClass { - GtkWindowClass parent_class; +struct MsdMediaKeysWindowClass { + MsdOsdWindowClass parent_class; }; typedef enum { - GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME, - GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM -} GsdMediaKeysWindowAction; + MSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME, + MSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM +} MsdMediaKeysWindowAction; -GType gsd_media_keys_window_get_type (void); +GType msd_media_keys_window_get_type (void); -GtkWidget * gsd_media_keys_window_new (void); -void gsd_media_keys_window_set_action (GsdMediaKeysWindow *window, - GsdMediaKeysWindowAction action); -void gsd_media_keys_window_set_action_custom (GsdMediaKeysWindow *window, +GtkWidget * msd_media_keys_window_new (void); +void msd_media_keys_window_set_action (MsdMediaKeysWindow *window, + MsdMediaKeysWindowAction action); +void msd_media_keys_window_set_action_custom (MsdMediaKeysWindow *window, const char *icon_name, gboolean show_level); -void gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window, +void msd_media_keys_window_set_volume_muted (MsdMediaKeysWindow *window, gboolean muted); -void gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window, +void msd_media_keys_window_set_volume_level (MsdMediaKeysWindow *window, int level); -gboolean gsd_media_keys_window_is_valid (GsdMediaKeysWindow *window); +gboolean msd_media_keys_window_is_valid (MsdMediaKeysWindow *window); -G_END_DECLS +#ifdef __cplusplus +} +#endif #endif diff --git a/src/msd-osd-window.c b/src/msd-osd-window.c new file mode 100644 index 0000000..46dfebd --- /dev/null +++ b/src/msd-osd-window.c @@ -0,0 +1,697 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * On-screen-display (OSD) window for mate-settings-daemon's plugins + * + * Copyright (C) 2006-2007 William Jon McCann <[email protected]> + * Copyright (C) 2009 Novell, Inc + * + * Authors: + * William Jon McCann <[email protected]> + * Federico Mena-Quintero <[email protected]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include "msd-osd-window.h" + +#define DIALOG_TIMEOUT 2000 /* dialog timeout in ms */ +#define DIALOG_FADE_TIMEOUT 1500 /* timeout before fade starts */ +#define FADE_TIMEOUT 10 /* timeout in ms between each frame of the fade */ + +#define BG_ALPHA 0.75 + +#define MSD_OSD_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MSD_TYPE_OSD_WINDOW, MsdOsdWindowPrivate)) + +struct MsdOsdWindowPrivate +{ + guint is_composited : 1; + guint hide_timeout_id; + guint fade_timeout_id; + double fade_out_alpha; +}; + +enum { + EXPOSE_WHEN_COMPOSITED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (MsdOsdWindow, msd_osd_window, GTK_TYPE_WINDOW) + +static gboolean +fade_timeout (MsdOsdWindow *window) +{ + if (window->priv->fade_out_alpha <= 0.0) { + gtk_widget_hide (GTK_WIDGET (window)); + + /* Reset it for the next time */ + window->priv->fade_out_alpha = 1.0; + window->priv->fade_timeout_id = 0; + + return FALSE; + } else { + GdkRectangle rect; + GtkWidget *win = GTK_WIDGET (window); + GtkAllocation allocation; + + window->priv->fade_out_alpha -= 0.10; + + rect.x = 0; + rect.y = 0; + gtk_widget_get_allocation (win, &allocation); + rect.width = allocation.width; + rect.height = allocation.height; + + gtk_widget_realize (win); + gdk_window_invalidate_rect (gtk_widget_get_window (win), &rect, FALSE); + } + + return TRUE; +} + +static gboolean +hide_timeout (MsdOsdWindow *window) +{ + if (window->priv->is_composited) { + window->priv->hide_timeout_id = 0; + window->priv->fade_timeout_id = g_timeout_add (FADE_TIMEOUT, + (GSourceFunc) fade_timeout, + window); + } else { + gtk_widget_hide (GTK_WIDGET (window)); + } + + return FALSE; +} + +static void +remove_hide_timeout (MsdOsdWindow *window) +{ + if (window->priv->hide_timeout_id != 0) { + g_source_remove (window->priv->hide_timeout_id); + window->priv->hide_timeout_id = 0; + } + + if (window->priv->fade_timeout_id != 0) { + g_source_remove (window->priv->fade_timeout_id); + window->priv->fade_timeout_id = 0; + window->priv->fade_out_alpha = 1.0; + } +} + +static void +add_hide_timeout (MsdOsdWindow *window) +{ + int timeout; + + if (window->priv->is_composited) { + timeout = DIALOG_FADE_TIMEOUT; + } else { + timeout = DIALOG_TIMEOUT; + } + window->priv->hide_timeout_id = g_timeout_add (timeout, + (GSourceFunc) hide_timeout, + window); +} + +void +msd_osd_window_draw_rounded_rectangle (cairo_t* cr, + gdouble aspect, + gdouble x, + gdouble y, + gdouble corner_radius, + gdouble width, + gdouble height) +{ + gdouble radius = corner_radius / aspect; + + cairo_move_to (cr, x + radius, y); + + cairo_line_to (cr, + x + width - radius, + y); + cairo_arc (cr, + x + width - radius, + y + radius, + radius, + -90.0f * G_PI / 180.0f, + 0.0f * G_PI / 180.0f); + cairo_line_to (cr, + x + width, + y + height - radius); + cairo_arc (cr, + x + width - radius, + y + height - radius, + radius, + 0.0f * G_PI / 180.0f, + 90.0f * G_PI / 180.0f); + cairo_line_to (cr, + x + radius, + y + height); + cairo_arc (cr, + x + radius, + y + height - radius, + radius, + 90.0f * G_PI / 180.0f, + 180.0f * G_PI / 180.0f); + cairo_line_to (cr, + x, + y + radius); + cairo_arc (cr, + x + radius, + y + radius, + radius, + 180.0f * G_PI / 180.0f, + 270.0f * G_PI / 180.0f); + cairo_close_path (cr); +} + +void +msd_osd_window_color_reverse (const GdkColor *a, + GdkColor *b) +{ + gdouble red; + gdouble green; + gdouble blue; + gdouble h; + gdouble s; + gdouble v; + + red = (gdouble) a->red / 65535.0; + green = (gdouble) a->green / 65535.0; + blue = (gdouble) a->blue / 65535.0; + + gtk_rgb_to_hsv (red, green, blue, &h, &s, &v); + + v = 0.5 + (0.5 - v); + if (v > 1.0) + v = 1.0; + else if (v < 0.0) + v = 0.0; + + gtk_hsv_to_rgb (h, s, v, &red, &green, &blue); + + b->red = red * 65535.0; + b->green = green * 65535.0; + b->blue = blue * 65535.0; +} + +/* This is our expose-event handler when the window is in a compositing manager. + * We draw everything by hand, using Cairo, so that we can have a nice + * transparent/rounded look. + */ +static void +#if GTK_CHECK_VERSION (3, 0, 0) +draw_when_composited (GtkWidget *widget, cairo_t *context) +#else +expose_when_composited (GtkWidget *widget, GdkEventExpose *event) +#endif +{ + MsdOsdWindow *window; +#if !GTK_CHECK_VERSION (3, 0, 0) + cairo_t *context; +#endif + cairo_t *cr; + cairo_surface_t *surface; + int width; + int height; + GtkStyle *style; + GdkColor color; + double r, g, b; + + window = MSD_OSD_WINDOW (widget); + +#if !GTK_CHECK_VERSION (3, 0, 0) + context = gdk_cairo_create (gtk_widget_get_window (widget)); +#endif + + style = gtk_widget_get_style (widget); + cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); + gtk_window_get_size (GTK_WINDOW (widget), &width, &height); + + surface = cairo_surface_create_similar (cairo_get_target (context), + CAIRO_CONTENT_COLOR_ALPHA, + width, + height); + + if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { + goto done; + } + + cr = cairo_create (surface); + if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { + goto done; + } + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_paint (cr); + + /* draw a box */ + msd_osd_window_draw_rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); + msd_osd_window_color_reverse (&style->bg[GTK_STATE_NORMAL], &color); + r = (float)color.red / 65535.0; + g = (float)color.green / 65535.0; + b = (float)color.blue / 65535.0; + cairo_set_source_rgba (cr, r, g, b, BG_ALPHA); + cairo_fill_preserve (cr); + + msd_osd_window_color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color); + r = (float)color.red / 65535.0; + g = (float)color.green / 65535.0; + b = (float)color.blue / 65535.0; + cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); + + g_signal_emit (window, signals[EXPOSE_WHEN_COMPOSITED], 0, cr); + + cairo_destroy (cr); + + /* Make sure we have a transparent background */ + cairo_rectangle (context, 0, 0, width, height); + cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); + cairo_fill (context); + + cairo_set_source_surface (context, surface, 0, 0); + cairo_paint_with_alpha (context, window->priv->fade_out_alpha); + + done: + if (surface != NULL) { + cairo_surface_destroy (surface); + } +#if !GTK_CHECK_VERSION (3, 0, 0) + cairo_destroy (context); +#endif +} + +/* This is our expose-event handler when the window is *not* in a compositing manager. + * We just draw a rectangular frame by hand. We do this with hardcoded drawing code, + * instead of GtkFrame, to avoid changing the window's internal widget hierarchy: in + * either case (composited or non-composited), callers can assume that this works + * identically to a GtkWindow without any intermediate widgetry. + */ +static void +#if GTK_CHECK_VERSION (3, 0, 0) +draw_when_not_composited (GtkWidget *widget, cairo_t *cr) +#else +expose_when_not_composited (GtkWidget *widget, GdkEventExpose *event) +#endif +{ + MsdOsdWindow *window; +#if GTK_CHECK_VERSION (3, 0, 0) + int width; + int height; +#else + GtkAllocation allocation; +#endif + + window = MSD_OSD_WINDOW (widget); + +#if GTK_CHECK_VERSION (3, 0, 0) + width = gtk_widget_get_allocated_width (widget); + height = gtk_widget_get_allocated_width (widget); +#else + gtk_widget_get_allocation (widget, &allocation); +#endif + + gtk_paint_shadow (gtk_widget_get_style (widget), +#if GTK_CHECK_VERSION (3, 0, 0) + cr, +#else + gtk_widget_get_window (widget), +#endif + gtk_widget_get_state (widget), + GTK_SHADOW_OUT, +#if !GTK_CHECK_VERSION (3, 0, 0) + &event->area, +#endif + widget, + NULL, /* NULL detail -> themes should use the MsdOsdWindow widget name, probably */ + 0, + 0, +#if GTK_CHECK_VERSION (3, 0, 0) + width, + height); +#else + allocation.width, + allocation.height); +#endif +} + +static gboolean +#if GTK_CHECK_VERSION (3, 0, 0) +msd_osd_window_draw (GtkWidget *widget, + cairo_t *cr) +#else +msd_osd_window_expose_event (GtkWidget *widget, + GdkEventExpose *event) +#endif +{ + MsdOsdWindow *window; + GtkWidget *child; + + window = MSD_OSD_WINDOW (widget); + +#if GTK_CHECK_VERSION (3, 0, 0) + if (window->priv->is_composited) + draw_when_composited (widget, cr); + else + draw_when_not_composited (widget, cr); +#else + if (window->priv->is_composited) + expose_when_composited (widget, event); + else + expose_when_not_composited (widget, event); +#endif + + child = gtk_bin_get_child (GTK_BIN (window)); + if (child) +#if GTK_CHECK_VERSION (3, 0, 0) + gtk_container_propagate_draw (GTK_CONTAINER (window), child, cr); +#else + gtk_container_propagate_expose (GTK_CONTAINER (window), child, event); +#endif + + return FALSE; +} + +static void +msd_osd_window_real_show (GtkWidget *widget) +{ + MsdOsdWindow *window; + + if (GTK_WIDGET_CLASS (msd_osd_window_parent_class)->show) { + GTK_WIDGET_CLASS (msd_osd_window_parent_class)->show (widget); + } + + window = MSD_OSD_WINDOW (widget); + remove_hide_timeout (window); + add_hide_timeout (window); +} + +static void +msd_osd_window_real_hide (GtkWidget *widget) +{ + MsdOsdWindow *window; + + if (GTK_WIDGET_CLASS (msd_osd_window_parent_class)->hide) { + GTK_WIDGET_CLASS (msd_osd_window_parent_class)->hide (widget); + } + + window = MSD_OSD_WINDOW (widget); + remove_hide_timeout (window); +} + +static void +msd_osd_window_real_realize (GtkWidget *widget) +{ +#if GTK_CHECK_VERSION (3, 0, 0) + GdkScreen *screen; + GdkVisual *visual; + cairo_region_t *region; +#else + GdkColormap *colormap; + GtkAllocation allocation; + GdkBitmap *mask; + cairo_t *cr; +#endif + +#if GTK_CHECK_VERSION (3, 0, 0) + screen = gtk_widget_get_screen (widget); + visual = gdk_screen_get_rgba_visual (screen); + + if (visual == NULL) { + visual = gdk_screen_get_system_visual (screen); + } + gtk_widget_set_visual (widget, visual); +#else + colormap = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)); + + if (colormap != NULL) { + gtk_widget_set_colormap (widget, colormap); + } +#endif + + if (GTK_WIDGET_CLASS (msd_osd_window_parent_class)->realize) { + GTK_WIDGET_CLASS (msd_osd_window_parent_class)->realize (widget); + } + +#if GTK_CHECK_VERSION (3, 0, 0) + /* make the whole window ignore events */ + region = cairo_region_create (); + gtk_widget_input_shape_combine_region (widget, region); + cairo_region_destroy (region); +#else + gtk_widget_get_allocation (widget, &allocation); + mask = gdk_pixmap_new (gtk_widget_get_window (widget), + allocation.width, + allocation.height, + 1); + cr = gdk_cairo_create (mask); + + cairo_set_source_rgba (cr, 1., 1., 1., 0.); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + + /* make the whole window ignore events */ + gdk_window_input_shape_combine_mask (gtk_widget_get_window (widget), mask, 0, 0); + g_object_unref (mask); + cairo_destroy (cr); +#endif +} + +static void +msd_osd_window_style_set (GtkWidget *widget, + GtkStyle *previous_style) +{ + GtkStyle *style; + + GTK_WIDGET_CLASS (msd_osd_window_parent_class)->style_set (widget, previous_style); + + /* We set our border width to 12 (per the MATE standard), plus the + * thickness of the frame that we draw in our expose handler. This will + * make our child be 12 pixels away from the frame. + */ + + style = gtk_widget_get_style (widget); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12 + MAX (style->xthickness, style->ythickness)); +} + +#if GTK_CHECK_VERSION (3, 0, 0) +static void +msd_osd_window_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width) +{ + GtkStyle *style; + + GTK_WIDGET_CLASS (msd_osd_window_parent_class)->get_preferred_width (widget, minimum_width, natural_width); + + /* See the comment in msd_osd_window_style_set() for why we add the thickness here */ + + style = gtk_widget_get_style (widget); + + *minimum_width += style->xthickness; + *natural_width += style->xthickness; +} + +static void +msd_osd_window_get_preferred_height (GtkWidget *widget, + gint *minimum_height, + gint *natural_height) +{ + GtkStyle *style; + + GTK_WIDGET_CLASS (msd_osd_window_parent_class)->get_preferred_height (widget, minimum_height, natural_height); + + /* See the comment in msd_osd_window_style_set() for why we add the thickness here */ + + style = gtk_widget_get_style (widget); + + *minimum_height += style->ythickness; + *natural_height += style->ythickness; +} +#else +static void +msd_osd_window_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkStyle *style; + + GTK_WIDGET_CLASS (msd_osd_window_parent_class)->size_request (widget, requisition); + + /* See the comment in msd_osd_window_style_set() for why we add the thickness here */ + + style = gtk_widget_get_style (widget); + + requisition->width += style->xthickness; + requisition->height += style->ythickness; +} +#endif + +static GObject * +msd_osd_window_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + + object = G_OBJECT_CLASS (msd_osd_window_parent_class)->constructor (type, n_construct_properties, construct_params); + + g_object_set (object, + "type", GTK_WINDOW_POPUP, + "type-hint", GDK_WINDOW_TYPE_HINT_NOTIFICATION, + "skip-taskbar-hint", TRUE, + "skip-pager-hint", TRUE, + "focus-on-map", FALSE, + NULL); + + return object; +} + +static void +msd_osd_window_class_init (MsdOsdWindowClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gobject_class->constructor = msd_osd_window_constructor; + + widget_class->show = msd_osd_window_real_show; + widget_class->hide = msd_osd_window_real_hide; + widget_class->realize = msd_osd_window_real_realize; + widget_class->style_set = msd_osd_window_style_set; +#if GTK_CHECK_VERSION (3, 0, 0) + widget_class->get_preferred_width = msd_osd_window_get_preferred_width; + widget_class->get_preferred_height = msd_osd_window_get_preferred_height; + widget_class->draw = msd_osd_window_draw; +#else + widget_class->size_request = msd_osd_window_size_request; + widget_class->expose_event = msd_osd_window_expose_event; +#endif + +#if GTK_CHECK_VERSION (3, 0, 0) + signals[EXPOSE_WHEN_COMPOSITED] = g_signal_new ("draw-when-composited", +#else + signals[EXPOSE_WHEN_COMPOSITED] = g_signal_new ("expose-when-composited", +#endif + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, +#if GTK_CHECK_VERSION (3, 0, 0) + G_STRUCT_OFFSET (MsdOsdWindowClass, draw_when_composited), +#else + G_STRUCT_OFFSET (MsdOsdWindowClass, expose_when_composited), +#endif + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + + g_type_class_add_private (klass, sizeof (MsdOsdWindowPrivate)); +} + +/** + * msd_osd_window_is_composited: + * @window: a #MsdOsdWindow + * + * Return value: whether the window was created on a composited screen. + */ +gboolean +msd_osd_window_is_composited (MsdOsdWindow *window) +{ + return window->priv->is_composited; +} + +/** + * msd_osd_window_is_valid: + * @window: a #MsdOsdWindow + * + * Return value: TRUE if the @window's idea of being composited matches whether + * its current screen is actually composited. + */ +gboolean +msd_osd_window_is_valid (MsdOsdWindow *window) +{ + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window)); + return gdk_screen_is_composited (screen) == window->priv->is_composited; +} + +static void +msd_osd_window_init (MsdOsdWindow *window) +{ + GdkScreen *screen; + + window->priv = MSD_OSD_WINDOW_GET_PRIVATE (window); + + screen = gtk_widget_get_screen (GTK_WIDGET (window)); + + window->priv->is_composited = gdk_screen_is_composited (screen); + + if (window->priv->is_composited) { + gdouble scalew, scaleh, scale; + gint size; + + gtk_window_set_decorated (GTK_WINDOW (window), FALSE); + gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); + + /* assume 130x130 on a 640x480 display and scale from there */ + scalew = gdk_screen_get_width (screen) / 640.0; + scaleh = gdk_screen_get_height (screen) / 480.0; + scale = MIN (scalew, scaleh); + size = 130 * MAX (1, scale); + + gtk_window_set_default_size (GTK_WINDOW (window), size, size); + + window->priv->fade_out_alpha = 1.0; + } else { + gtk_container_set_border_width (GTK_CONTAINER (window), 12); + } +} + +GtkWidget * +msd_osd_window_new (void) +{ + return g_object_new (MSD_TYPE_OSD_WINDOW, NULL); +} + +/** + * msd_osd_window_update_and_hide: + * @window: a #MsdOsdWindow + * + * Queues the @window for immediate drawing, and queues a timer to hide the window. + */ +void +msd_osd_window_update_and_hide (MsdOsdWindow *window) +{ + remove_hide_timeout (window); + add_hide_timeout (window); + + if (window->priv->is_composited) { + gtk_widget_queue_draw (GTK_WIDGET (window)); + } +} diff --git a/src/msd-osd-window.h b/src/msd-osd-window.h new file mode 100644 index 0000000..fd33d36 --- /dev/null +++ b/src/msd-osd-window.h @@ -0,0 +1,102 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*- + * + * On-screen-display (OSD) window for mate-settings-daemon's plugins + * + * Copyright (C) 2006 William Jon McCann <[email protected]> + * Copyright (C) 2009 Novell, Inc + * + * Authors: + * William Jon McCann <[email protected]> + * Federico Mena-Quintero <[email protected]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +/* MsdOsdWindow is an "on-screen-display" window (OSD). It is the cute, + * semi-transparent, curved popup that appears when you press a hotkey global to + * the desktop, such as to change the volume, switch your monitor's parameters, + * etc. + * + * You can create a MsdOsdWindow and use it as a normal GtkWindow. It will + * automatically center itself, figure out if it needs to be composited, etc. + * Just pack your widgets in it, sit back, and enjoy the ride. + */ + +#ifndef MSD_OSD_WINDOW_H +#define MSD_OSD_WINDOW_H + +#include <glib-object.h> +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Alpha value to be used for foreground objects drawn in an OSD window */ +#define MSD_OSD_WINDOW_FG_ALPHA 1.0 + +#define MSD_TYPE_OSD_WINDOW (msd_osd_window_get_type ()) +#define MSD_OSD_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MSD_TYPE_OSD_WINDOW, MsdOsdWindow)) +#define MSD_OSD_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MSD_TYPE_OSD_WINDOW, MsdOsdWindowClass)) +#define MSD_IS_OSD_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MSD_TYPE_OSD_WINDOW)) +#define MSD_IS_OSD_WINDOW_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), MSD_TYPE_OSD_WINDOW)) +#define MSD_OSD_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MSD_TYPE_OSD_WINDOW, MsdOsdWindowClass)) + +typedef struct MsdOsdWindow MsdOsdWindow; +typedef struct MsdOsdWindowClass MsdOsdWindowClass; +typedef struct MsdOsdWindowPrivate MsdOsdWindowPrivate; + +struct MsdOsdWindow { + GtkWindow parent; + + MsdOsdWindowPrivate *priv; +}; + +struct MsdOsdWindowClass { + GtkWindowClass parent_class; + +#if GTK_CHECK_VERSION (3, 0, 0) + void (* draw_when_composited) (MsdOsdWindow *window, cairo_t *cr); +#else + void (* expose_when_composited) (MsdOsdWindow *window, cairo_t *cr); +#endif +}; + +GType msd_osd_window_get_type (void); + +GtkWidget * msd_osd_window_new (void); +gboolean msd_osd_window_is_composited (MsdOsdWindow *window); +gboolean msd_osd_window_is_valid (MsdOsdWindow *window); +void msd_osd_window_update_and_hide (MsdOsdWindow *window); + +void msd_osd_window_draw_rounded_rectangle (cairo_t *cr, + gdouble aspect, + gdouble x, + gdouble y, + gdouble corner_radius, + gdouble width, + gdouble height); + +void msd_osd_window_color_reverse (const GdkColor *a, + GdkColor *b); + +#ifdef __cplusplus +} +#endif + +#endif |