summaryrefslogtreecommitdiff
path: root/plugins/common/gsd-osd-window.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/common/gsd-osd-window.c')
-rw-r--r--plugins/common/gsd-osd-window.c573
1 files changed, 0 insertions, 573 deletions
diff --git a/plugins/common/gsd-osd-window.c b/plugins/common/gsd-osd-window.c
deleted file mode 100644
index 123313c..0000000
--- a/plugins/common/gsd-osd-window.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/* -*- 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, 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
-expose_when_composited (GtkWidget *widget, GdkEventExpose *event)
-{
- MsdOsdWindow *window;
- cairo_t *context;
- cairo_t *cr;
- cairo_surface_t *surface;
- int width;
- int height;
- GtkStyle *style;
- GdkColor color;
- double r, g, b;
-
- window = MSD_OSD_WINDOW (widget);
-
- 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 */
- 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);
- }
- cairo_destroy (context);
-}
-
-/* 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
-expose_when_not_composited (GtkWidget *widget, GdkEventExpose *event)
-{
- MsdOsdWindow *window;
- GtkAllocation allocation;
-
- window = MSD_OSD_WINDOW (widget);
-
- gtk_widget_get_allocation (widget, &allocation);
-
- gtk_paint_shadow (gtk_widget_get_style (widget),
- gtk_widget_get_window (widget),
- gtk_widget_get_state (widget),
- GTK_SHADOW_OUT,
- &event->area,
- widget,
- NULL, /* NULL detail -> themes should use the MsdOsdWindow widget name, probably */
- 0,
- 0,
- allocation.width,
- allocation.height);
-}
-
-static gboolean
-msd_osd_window_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
-{
- MsdOsdWindow *window;
- GtkWidget *child;
-
- window = MSD_OSD_WINDOW (widget);
-
- if (window->priv->is_composited)
- expose_when_composited (widget, event);
- else
- expose_when_not_composited (widget, event);
-
- child = gtk_bin_get_child (GTK_BIN (window));
- if (child)
- gtk_container_propagate_expose (GTK_CONTAINER (window), child, event);
-
- 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)
-{
- 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 (msd_osd_window_parent_class)->realize) {
- GTK_WIDGET_CLASS (msd_osd_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
-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));
-}
-
-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;
-}
-
-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;
- widget_class->size_request = msd_osd_window_size_request;
- widget_class->expose_event = msd_osd_window_expose_event;
-
- signals[EXPOSE_WHEN_COMPOSITED] = g_signal_new ("expose-when-composited",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MsdOsdWindowClass, expose_when_composited),
- 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));
- }
-}