[gnome-settings-daemon] media-keys: Merge OSD into single object



commit b1c0fc91bfd634c374535119e71fb5f1166b909b
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Apr 16 17:44:36 2012 +0100

    media-keys: Merge OSD into single object
    
    As the window isn't a container anymore, the drawing can take
    place in a single location.

 plugins/media-keys/Makefile.am              |    6 -
 plugins/media-keys/gsd-media-keys-manager.c |   26 +-
 plugins/media-keys/gsd-media-keys-window.c  |  640 ---------------------------
 plugins/media-keys/gsd-media-keys-window.h  |   73 ---
 plugins/media-keys/gsd-osd-window.c         |  590 ++++++++++++++++++++++++-
 plugins/media-keys/gsd-osd-window.h         |   18 +-
 plugins/media-keys/test-media-window.c      |   42 +-
 7 files changed, 621 insertions(+), 774 deletions(-)
---
diff --git a/plugins/media-keys/Makefile.am b/plugins/media-keys/Makefile.am
index c79aca9..bdc924b 100644
--- a/plugins/media-keys/Makefile.am
+++ b/plugins/media-keys/Makefile.am
@@ -24,8 +24,6 @@ libmedia_keys_la_SOURCES = 		\
 	gsd-media-keys-plugin.c		\
 	gsd-media-keys-manager.h	\
 	gsd-media-keys-manager.c	\
-	gsd-media-keys-window.h		\
-	gsd-media-keys-window.c		\
 	gsd-osd-window.c		\
 	gsd-osd-window.h		\
 	shortcuts-list.h		\
@@ -72,8 +70,6 @@ noinst_PROGRAMS =				\
 test_media_window_SOURCES =			\
 	gsd-osd-window.c			\
 	gsd-osd-window.h			\
-	gsd-media-keys-window.c			\
-	gsd-media-keys-window.h			\
 	test-media-window.c			\
 	$(NULL)
 
@@ -101,8 +97,6 @@ test_media_window_LDADD = \
 test_media_keys_SOURCES =			\
 	gsd-media-keys-manager.c		\
 	gsd-media-keys-manager.h		\
-	gsd-media-keys-window.h			\
-	gsd-media-keys-window.c			\
 	gsd-osd-window.c			\
 	gsd-osd-window.h			\
 	test-media-keys.c			\
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index bdef10d..a7021ea 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -49,7 +49,7 @@
 #include "gsd-media-keys-manager.h"
 
 #include "shortcuts-list.h"
-#include "gsd-media-keys-window.h"
+#include "gsd-osd-window.h"
 #include "gsd-input-helper.h"
 #include "gsd-enums.h"
 
@@ -342,7 +342,7 @@ dialog_init (GsdMediaKeysManager *manager)
         }
 
         if (manager->priv->dialog == NULL) {
-                manager->priv->dialog = gsd_media_keys_window_new ();
+                manager->priv->dialog = gsd_osd_window_new ();
         }
 }
 
@@ -840,7 +840,7 @@ do_eject_action (GsdMediaKeysManager *manager)
 
         /* Show the dialogue */
         dialog_init (manager);
-        gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+        gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (manager->priv->dialog),
                                                  "media-eject-symbolic",
                                                  FALSE);
         dialog_show (manager);
@@ -902,7 +902,7 @@ static void
 do_touchpad_osd_action (GsdMediaKeysManager *manager, gboolean state)
 {
         dialog_init (manager);
-        gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+        gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (manager->priv->dialog),
                                                  state ? "input-touchpad-symbolic" : "touchpad-disabled-symbolic",
                                                  FALSE);
         dialog_show (manager);
@@ -944,11 +944,11 @@ update_dialog (GsdMediaKeysManager *manager,
         }
 
         dialog_init (manager);
-        gsd_media_keys_window_set_volume_muted (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+        gsd_osd_window_set_volume_muted (GSD_OSD_WINDOW (manager->priv->dialog),
                                                 muted);
-        gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), vol);
-        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
-                                          GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
+        gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (manager->priv->dialog), vol);
+        gsd_osd_window_set_action (GSD_OSD_WINDOW (manager->priv->dialog),
+                                          GSD_OSD_WINDOW_ACTION_VOLUME);
         dialog_show (manager);
 
         if (quiet == FALSE && sound_changed != FALSE && muted == FALSE) {
@@ -1367,7 +1367,7 @@ gsd_media_player_key_pressed (GsdMediaKeysManager *manager,
         if (!have_listeners) {
                 /* Popup a dialog with an (/) icon */
                 dialog_init (manager);
-                gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (manager->priv->dialog),
                                                          "action-unavailable-symbolic",
                                                          FALSE);
                 dialog_show (manager);
@@ -1700,10 +1700,10 @@ update_screen_cb (GObject             *source_object,
         /* update the dialog with the new value */
         g_variant_get (new_percentage, "(u)", &percentage);
         dialog_init (manager);
-        gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+        gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (manager->priv->dialog),
                                                  "display-brightness-symbolic",
                                                  TRUE);
-        gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+        gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (manager->priv->dialog),
                                                 percentage);
         dialog_show (manager);
         g_variant_unref (new_percentage);
@@ -1752,10 +1752,10 @@ update_keyboard_cb (GObject             *source_object,
         /* update the dialog with the new value */
         g_variant_get (new_percentage, "(u)", &percentage);
         dialog_init (manager);
-        gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+        gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (manager->priv->dialog),
                                                  "keyboard-brightness-symbolic",
                                                  TRUE);
-        gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+        gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (manager->priv->dialog),
                                                 percentage);
         dialog_show (manager);
         g_variant_unref (new_percentage);
diff --git a/plugins/media-keys/gsd-osd-window.c b/plugins/media-keys/gsd-osd-window.c
index dd8d7fa..22f7316 100644
--- a/plugins/media-keys/gsd-osd-window.c
+++ b/plugins/media-keys/gsd-osd-window.c
@@ -39,9 +39,10 @@
 
 #include "gsd-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 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 ICON_SCALE 0.50           /* The size of the icon compared to the whole OSD */
 
 #define BG_ALPHA 0.75
 
@@ -56,14 +57,14 @@ struct GsdOsdWindowPrivate
         gint                     screen_width;
         gint                     screen_height;
         gint                     monitor;
-};
 
-enum {
-        DRAW_WHEN_COMPOSITED,
-        LAST_SIGNAL
-};
+        GsdOsdWindowAction       action;
+        char                    *icon_name;
+        gboolean                 show_level;
 
-static guint signals[LAST_SIGNAL] = { 0 };
+        guint                    volume_muted : 1;
+        int                      volume_level;
+};
 
 G_DEFINE_TYPE (GsdOsdWindow, gsd_osd_window, GTK_TYPE_WINDOW)
 
@@ -132,6 +133,557 @@ add_hide_timeout (GsdOsdWindow *window)
                                                        window);
 }
 
+static const char *
+get_image_name_for_volume (gboolean muted,
+			   int volume)
+{
+        static const char *icon_names[] = {
+                "audio-volume-muted-symbolic",
+                "audio-volume-low-symbolic",
+                "audio-volume-medium-symbolic",
+                "audio-volume-high-symbolic",
+                NULL
+        };
+        int n;
+
+        if (muted) {
+                n = 0;
+        } else {
+                /* select image */
+                n = 3 * volume / 100 + 1;
+                if (n < 1) {
+                        n = 1;
+                } else if (n > 3) {
+                        n = 3;
+                }
+        }
+
+	return icon_names[n];
+}
+
+static void
+action_changed (GsdOsdWindow *window)
+{
+        gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+}
+
+static void
+volume_level_changed (GsdOsdWindow *window)
+{
+        gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+}
+
+static void
+volume_muted_changed (GsdOsdWindow *window)
+{
+        gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+}
+
+void
+gsd_osd_window_set_action (GsdOsdWindow      *window,
+                                  GsdOsdWindowAction action)
+{
+        g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+        g_return_if_fail (action == GSD_OSD_WINDOW_ACTION_VOLUME);
+
+        if (window->priv->action != action) {
+                window->priv->action = action;
+                action_changed (window);
+        } else {
+                gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+        }
+}
+
+void
+gsd_osd_window_set_action_custom (GsdOsdWindow      *window,
+                                         const char              *icon_name,
+                                         gboolean                 show_level)
+{
+        g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+        g_return_if_fail (icon_name != NULL);
+
+        if (window->priv->action != GSD_OSD_WINDOW_ACTION_CUSTOM ||
+            g_strcmp0 (window->priv->icon_name, icon_name) != 0 ||
+            window->priv->show_level != show_level) {
+                window->priv->action = GSD_OSD_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 {
+                gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window));
+        }
+}
+
+void
+gsd_osd_window_set_volume_muted (GsdOsdWindow *window,
+                                        gboolean            muted)
+{
+        g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+
+        if (window->priv->volume_muted != muted) {
+                window->priv->volume_muted = muted;
+                volume_muted_changed (window);
+        }
+}
+
+void
+gsd_osd_window_set_volume_level (GsdOsdWindow *window,
+                                        int                 level)
+{
+        g_return_if_fail (GSD_IS_OSD_WINDOW (window));
+
+        if (window->priv->volume_level != level) {
+                window->priv->volume_level = level;
+                volume_level_changed (window);
+        }
+}
+
+static GdkPixbuf *
+load_pixbuf (GsdOsdWindow *window,
+             const char         *name,
+             int                 icon_size)
+{
+        GtkIconTheme    *theme;
+        GtkIconInfo     *info;
+        GdkPixbuf       *pixbuf;
+        GtkStyleContext *context;
+        GdkRGBA          color;
+
+        if (window != NULL && gtk_widget_has_screen (GTK_WIDGET (window))) {
+                theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
+        } else {
+                theme = gtk_icon_theme_get_default ();
+        }
+
+        context = gtk_widget_get_style_context (GTK_WIDGET (window));
+        gtk_style_context_get_background_color (context, GTK_STATE_NORMAL, &color);
+        info = gtk_icon_theme_lookup_icon (theme,
+                                           name,
+                                           icon_size,
+                                           GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_GENERIC_FALLBACK);
+
+        if (info == NULL) {
+                g_warning ("Failed to load '%s'", name);
+                return NULL;
+        }
+
+        pixbuf = gtk_icon_info_load_symbolic (info,
+                                              &color,
+                                              NULL,
+                                              NULL,
+                                              NULL,
+                                              NULL,
+                                              NULL);
+        gtk_icon_info_free (info);
+
+        return pixbuf;
+}
+
+static void
+draw_eject (cairo_t *cr,
+            double   _x0,
+            double   _y0,
+            double   width,
+            double   height)
+{
+        int box_height;
+        int tri_height;
+        int separation;
+
+        box_height = height * 0.2;
+        separation = box_height / 3;
+        tri_height = height - box_height - separation;
+
+        cairo_rectangle (cr, _x0, _y0 + height - box_height, width, box_height);
+
+        cairo_move_to (cr, _x0, _y0 + tri_height);
+        cairo_rel_line_to (cr, width, 0);
+        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, GSD_OSD_WINDOW_FG_ALPHA);
+        cairo_fill_preserve (cr);
+
+        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2);
+        cairo_set_line_width (cr, 2);
+        cairo_stroke (cr);
+}
+
+static void
+draw_waves (cairo_t *cr,
+            double   cx,
+            double   cy,
+            double   max_radius,
+            int      volume_level)
+{
+        const int n_waves = 3;
+        int last_wave;
+        int i;
+
+        last_wave = n_waves * volume_level / 100;
+
+        for (i = 0; i < n_waves; i++) {
+                double angle1;
+                double angle2;
+                double radius;
+                double alpha;
+
+                angle1 = -M_PI / 4;
+                angle2 = M_PI / 4;
+
+                if (i < last_wave)
+                        alpha = 1.0;
+                else if (i > last_wave)
+                        alpha = 0.1;
+                else alpha = 0.1 + 0.9 * (n_waves * volume_level % 100) / 100.0;
+
+                radius = (i + 1) * (max_radius / n_waves);
+                cairo_arc (cr, cx, cy, radius, angle1, angle2);
+                cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, 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, alpha);
+                cairo_set_line_width (cr, 10);
+                cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
+                cairo_stroke (cr);
+        }
+}
+
+static void
+draw_cross (cairo_t *cr,
+            double   cx,
+            double   cy,
+            double   size)
+{
+        cairo_move_to (cr, cx, cy - size/2.0);
+        cairo_rel_line_to (cr, size, size);
+
+        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, GSD_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, GSD_OSD_WINDOW_FG_ALPHA);
+        cairo_set_line_width (cr, 10);
+        cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+        cairo_stroke (cr);
+}
+
+static void
+draw_speaker (cairo_t *cr,
+              double   cx,
+              double   cy,
+              double   width,
+              double   height)
+{
+        double box_width;
+        double box_height;
+        double _x0;
+        double _y0;
+
+        box_width = width / 3;
+        box_height = height / 3;
+
+        _x0 = cx - (width / 2) + box_width;
+        _y0 = cy - box_height / 2;
+
+        cairo_move_to (cr, _x0, _y0);
+        cairo_rel_line_to (cr, - box_width, 0);
+        cairo_rel_line_to (cr, 0, box_height);
+        cairo_rel_line_to (cr, box_width, 0);
+
+        cairo_line_to (cr, cx + box_width, cy + height / 2);
+        cairo_rel_line_to (cr, 0, -height);
+        cairo_line_to (cr, _x0, _y0);
+        cairo_close_path (cr);
+
+        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, GSD_OSD_WINDOW_FG_ALPHA);
+        cairo_fill_preserve (cr);
+
+        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2);
+        cairo_set_line_width (cr, 2);
+        cairo_stroke (cr);
+}
+
+static gboolean
+render_speaker (GsdOsdWindow *window,
+                cairo_t            *cr,
+                double              _x0,
+                double              _y0,
+                double              width,
+                double              height)
+{
+        GdkPixbuf         *pixbuf;
+        const char        *icon_name;
+        int                icon_size;
+
+	icon_name = get_image_name_for_volume (window->priv->volume_muted,
+					       window->priv->volume_level);
+
+        icon_size = (int)width;
+
+        pixbuf = load_pixbuf (window, icon_name, icon_size);
+
+        if (pixbuf == NULL) {
+                return FALSE;
+        }
+
+        gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
+        cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA);
+
+        g_object_unref (pixbuf);
+
+        return TRUE;
+}
+
+#define LIGHTNESS_MULT  1.3
+#define DARKNESS_MULT   0.7
+
+static void
+draw_volume_boxes (GsdOsdWindow *window,
+                   cairo_t            *cr,
+                   double              percentage,
+                   double              _x0,
+                   double              _y0,
+                   double              width,
+                   double              height)
+{
+        gdouble   x1;
+        GtkStyleContext *context;
+        GdkRGBA  acolor;
+
+        height = round (height) - 1;
+        width = round (width) - 1;
+        x1 = round ((width - 1) * percentage);
+        context = gtk_widget_get_style_context (GTK_WIDGET (window));
+
+        /* bar background */
+        gtk_style_context_get_background_color (context, GTK_STATE_NORMAL, &acolor);
+        gsd_osd_window_color_shade (&acolor, DARKNESS_MULT);
+        gsd_osd_window_color_reverse (&acolor);
+        acolor.alpha = GSD_OSD_WINDOW_FG_ALPHA / 2;
+        gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height);
+        gdk_cairo_set_source_rgba (cr, &acolor);
+        cairo_fill (cr);
+
+        /* bar progress */
+        if (percentage < 0.01)
+                return;
+        gtk_style_context_get_background_color (context, GTK_STATE_NORMAL, &acolor);
+        acolor.alpha = GSD_OSD_WINDOW_FG_ALPHA;
+        gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, x1, height);
+        gdk_cairo_set_source_rgba (cr, &acolor);
+        cairo_fill (cr);
+}
+
+static void
+draw_action_volume (GsdOsdWindow *window,
+                    cairo_t            *cr)
+{
+        int window_width;
+        int window_height;
+        double icon_box_width;
+        double icon_box_height;
+        double icon_box_x0;
+        double icon_box_y0;
+        double volume_box_x0;
+        double volume_box_y0;
+        double volume_box_width;
+        double volume_box_height;
+        gboolean res;
+
+        gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height);
+
+        icon_box_width = round (window_width * ICON_SCALE);
+        icon_box_height = round (window_height * ICON_SCALE);
+        volume_box_width = icon_box_width;
+        volume_box_height = round (window_height * 0.05);
+
+        icon_box_x0 = round ((window_width - icon_box_width) / 2);
+        icon_box_y0 = round ((window_height - icon_box_height - volume_box_height) / 2 - volume_box_height);
+        volume_box_x0 = round (icon_box_x0);
+        volume_box_y0 = round (icon_box_height + icon_box_y0) + volume_box_height;
+
+#if 0
+        g_message ("icon box: w=%f h=%f _x0=%f _y0=%f",
+                   icon_box_width,
+                   icon_box_height,
+                   icon_box_x0,
+                   icon_box_y0);
+        g_message ("volume box: w=%f h=%f _x0=%f _y0=%f",
+                   volume_box_width,
+                   volume_box_height,
+                   volume_box_x0,
+                   volume_box_y0);
+#endif
+
+        res = render_speaker (window,
+                              cr,
+                              icon_box_x0, icon_box_y0,
+                              icon_box_width, icon_box_height);
+        if (! res) {
+                double speaker_width;
+                double speaker_height;
+                double speaker_cx;
+                double speaker_cy;
+
+                speaker_width = icon_box_width * 0.5;
+                speaker_height = icon_box_height * 0.75;
+                speaker_cx = icon_box_x0 + speaker_width / 2;
+                speaker_cy = icon_box_y0 + speaker_height / 2;
+
+#if 0
+                g_message ("speaker box: w=%f h=%f cx=%f cy=%f",
+                           speaker_width,
+                           speaker_height,
+                           speaker_cx,
+                           speaker_cy);
+#endif
+
+                /* draw speaker symbol */
+                draw_speaker (cr, speaker_cx, speaker_cy, speaker_width, speaker_height);
+
+                if (! window->priv->volume_muted) {
+                        /* draw sound waves */
+                        double wave_x0;
+                        double wave_y0;
+                        double wave_radius;
+
+                        wave_x0 = window_width / 2;
+                        wave_y0 = speaker_cy;
+                        wave_radius = icon_box_width / 2;
+
+                        draw_waves (cr, wave_x0, wave_y0, wave_radius, window->priv->volume_level);
+                } else {
+                        /* draw 'mute' cross */
+                        double cross_x0;
+                        double cross_y0;
+                        double cross_size;
+
+                        cross_size = speaker_width * 3 / 4;
+                        cross_x0 = icon_box_x0 + icon_box_width - cross_size;
+                        cross_y0 = speaker_cy;
+
+                        draw_cross (cr, cross_x0, cross_y0, cross_size);
+                }
+        }
+
+        /* draw volume meter */
+        draw_volume_boxes (window,
+                           cr,
+                           (double)window->priv->volume_level / 100.0,
+                           volume_box_x0,
+                           volume_box_y0,
+                           volume_box_width,
+                           volume_box_height);
+}
+
+static gboolean
+render_custom (GsdOsdWindow *window,
+               cairo_t            *cr,
+               double              _x0,
+               double              _y0,
+               double              width,
+               double              height)
+{
+        GdkPixbuf         *pixbuf;
+        int                icon_size;
+
+        icon_size = (int)width;
+
+        pixbuf = load_pixbuf (window, window->priv->icon_name, icon_size);
+
+        if (pixbuf == NULL) {
+                char *name;
+                if (gtk_widget_get_direction (GTK_WIDGET (window)) == GTK_TEXT_DIR_RTL)
+                        name = g_strdup_printf ("%s-rtl", window->priv->icon_name);
+                else
+                        name = g_strdup_printf ("%s-ltr", window->priv->icon_name);
+                pixbuf = load_pixbuf (window, name, icon_size);
+                g_free (name);
+                if (pixbuf == NULL)
+                        return FALSE;
+        }
+
+        gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
+        cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA);
+
+        g_object_unref (pixbuf);
+
+        return TRUE;
+}
+
+static void
+draw_action_custom (GsdOsdWindow *window,
+                    cairo_t            *cr)
+{
+        int window_width;
+        int window_height;
+        double icon_box_width;
+        double icon_box_height;
+        double icon_box_x0;
+        double icon_box_y0;
+        double bright_box_x0;
+        double bright_box_y0;
+        double bright_box_width;
+        double bright_box_height;
+        gboolean res;
+
+        gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height);
+
+        icon_box_width = round (window_width * ICON_SCALE);
+        icon_box_height = round (window_height * ICON_SCALE);
+        bright_box_width = round (icon_box_width);
+        bright_box_height = round (window_height * 0.05);
+
+        icon_box_x0 = round ((window_width - icon_box_width) / 2);
+        icon_box_y0 = round ((window_height - icon_box_height - bright_box_height) / 2 - bright_box_height);
+        bright_box_x0 = round (icon_box_x0);
+        bright_box_y0 = round (icon_box_height + icon_box_y0) + bright_box_height;
+
+#if 0
+        g_message ("icon box: w=%f h=%f _x0=%f _y0=%f",
+                   icon_box_width,
+                   icon_box_height,
+                   icon_box_x0,
+                   icon_box_y0);
+        g_message ("brightness box: w=%f h=%f _x0=%f _y0=%f",
+                   bright_box_width,
+                   bright_box_height,
+                   bright_box_x0,
+                   bright_box_y0);
+#endif
+
+        res = render_custom (window,
+                             cr,
+                             icon_box_x0, icon_box_y0,
+                             icon_box_width, icon_box_height);
+        if (! res && g_str_has_prefix (window->priv->icon_name, "media-eject")) {
+                /* draw eject symbol */
+                draw_eject (cr,
+                            icon_box_x0, icon_box_y0,
+                            icon_box_width, icon_box_height);
+        }
+
+        if (window->priv->show_level != FALSE) {
+                /* draw volume meter */
+                draw_volume_boxes (window,
+                                   cr,
+                                   (double)window->priv->volume_level / 100.0,
+                                   bright_box_x0,
+                                   bright_box_y0,
+                                   bright_box_width,
+                                   bright_box_height);
+        }
+}
+
+
 void
 gsd_osd_window_draw_rounded_rectangle (cairo_t* cr,
                                        gdouble  aspect,
@@ -442,7 +994,16 @@ gsd_osd_window_draw (GtkWidget *widget,
         gdk_cairo_set_source_rgba (cr, &acolor);
         cairo_fill (cr);
 
-        g_signal_emit (window, signals[DRAW_WHEN_COMPOSITED], 0, cr);
+        switch (window->priv->action) {
+        case GSD_OSD_WINDOW_ACTION_VOLUME:
+                draw_action_volume (window, cr);
+                break;
+        case GSD_OSD_WINDOW_ACTION_CUSTOM:
+                draw_action_custom (window, cr);
+                break;
+        default:
+                break;
+        }
 
         cairo_destroy (cr);
 
@@ -606,15 +1167,6 @@ gsd_osd_window_class_init (GsdOsdWindowClass *klass)
         widget_class->get_preferred_height = gsd_osd_window_get_preferred_height;
         widget_class->draw = gsd_osd_window_draw;
 
-        signals[DRAW_WHEN_COMPOSITED] = g_signal_new ("draw-when-composited",
-                                                      G_TYPE_FROM_CLASS (gobject_class),
-                                                      G_SIGNAL_RUN_FIRST,
-                                                      G_STRUCT_OFFSET (GsdOsdWindowClass, draw_when_composited),
-                                                      NULL, NULL,
-                                                      g_cclosure_marshal_VOID__POINTER,
-                                                      G_TYPE_NONE, 1,
-                                                      G_TYPE_POINTER);
-
         g_type_class_add_private (klass, sizeof (GsdOsdWindowPrivate));
 }
 
diff --git a/plugins/media-keys/gsd-osd-window.h b/plugins/media-keys/gsd-osd-window.h
index 69c743c..abdb8bb 100644
--- a/plugins/media-keys/gsd-osd-window.h
+++ b/plugins/media-keys/gsd-osd-window.h
@@ -71,11 +71,25 @@ struct GsdOsdWindowClass {
         void (* draw_when_composited) (GsdOsdWindow *window, cairo_t *cr);
 };
 
+typedef enum {
+        GSD_OSD_WINDOW_ACTION_VOLUME,
+        GSD_OSD_WINDOW_ACTION_CUSTOM
+} GsdOsdWindowAction;
+
 GType                 gsd_osd_window_get_type          (void);
 
 GtkWidget *           gsd_osd_window_new               (void);
-gboolean              gsd_osd_window_is_valid          (GsdOsdWindow      *window);
-void                  gsd_osd_window_update_and_hide   (GsdOsdWindow      *window);
+gboolean              gsd_osd_window_is_valid          (GsdOsdWindow       *window);
+void                  gsd_osd_window_update_and_hide   (GsdOsdWindow       *window);
+void                  gsd_osd_window_set_action        (GsdOsdWindow       *window,
+                                                        GsdOsdWindowAction  action);
+void                  gsd_osd_window_set_action_custom (GsdOsdWindow       *window,
+                                                        const char         *icon_name,
+                                                        gboolean            show_level);
+void                  gsd_osd_window_set_volume_muted  (GsdOsdWindow       *window,
+                                                        gboolean            muted);
+void                  gsd_osd_window_set_volume_level  (GsdOsdWindow       *window,
+                                                        int                 level);
 
 void                  gsd_osd_window_draw_rounded_rectangle (cairo_t *cr,
                                                              gdouble  aspect,
diff --git a/plugins/media-keys/test-media-window.c b/plugins/media-keys/test-media-window.c
index 41f7f6c..a1a8787 100644
--- a/plugins/media-keys/test-media-window.c
+++ b/plugins/media-keys/test-media-window.c
@@ -27,7 +27,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
-#include "gsd-media-keys-window.h"
+#include "gsd-osd-window.h"
 
 static gboolean
 update_state (GtkWidget *window)
@@ -38,63 +38,63 @@ update_state (GtkWidget *window)
 
         switch (count) {
         case 1:
-                gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (window),
                                                         50);
-                gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window),
-                                                  GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
+                gsd_osd_window_set_action (GSD_OSD_WINDOW (window),
+                                                  GSD_OSD_WINDOW_ACTION_VOLUME);
 
                 gtk_widget_show (window);
                 break;
         case 2:
-                gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (window),
                                                         100);
-                gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window),
-                                                  GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
+                gsd_osd_window_set_action (GSD_OSD_WINDOW (window),
+                                                  GSD_OSD_WINDOW_ACTION_VOLUME);
 
                 gtk_widget_show (window);
                 break;
         case 3:
-                gsd_media_keys_window_set_volume_muted (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_volume_muted (GSD_OSD_WINDOW (window),
                                                         TRUE);
-                gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window),
-                                                  GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
+                gsd_osd_window_set_action (GSD_OSD_WINDOW (window),
+                                                  GSD_OSD_WINDOW_ACTION_VOLUME);
 
                 gtk_widget_show (window);
                 break;
         case 4:
-                gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (window),
                                                          "media-eject-symbolic",
                                                          FALSE);
 
                 gtk_widget_show (window);
                 break;
         case 5:
-                gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (window),
                                                         50);
-                gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (window),
                                                          "display-brightness-symbolic",
                                                          TRUE);
 
                 gtk_widget_show (window);
                 break;
         case 6:
-                gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (window),
                                                         50);
-                gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (window),
                                                          "keyboard-brightness-symbolic",
                                                          TRUE);
 
                 gtk_widget_show (window);
                 break;
         case 7:
-                gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (window),
                                                          "touchpad-disabled-symbolic",
                                                          TRUE);
 
                 gtk_widget_show (window);
                 break;
         case 8:
-                gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window),
+                gsd_osd_window_set_action_custom (GSD_OSD_WINDOW (window),
                                                          "input-touchpad-symbolic",
                                                          TRUE);
 
@@ -113,13 +113,13 @@ test_window (void)
 {
         GtkWidget *window;
 
-        window = gsd_media_keys_window_new ();
+        window = gsd_osd_window_new ();
         gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER_ALWAYS);
 
-        gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window),
+        gsd_osd_window_set_volume_level (GSD_OSD_WINDOW (window),
                                                 0);
-        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window),
-                                          GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
+        gsd_osd_window_set_action (GSD_OSD_WINDOW (window),
+                                          GSD_OSD_WINDOW_ACTION_VOLUME);
 
         gtk_widget_show (window);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]