From 49f3dfb8bde4c1181025fe31326bc9e72f2bdf3f Mon Sep 17 00:00:00 2001 From: Emilio Pozuelo Monfort Date: Fri, 18 Feb 2011 15:51:12 +0000 Subject: Add an EmpathyCallWindowFullscreen class --- src/empathy-call-window-fullscreen.c | 309 +++++++++++++++++++++++++++++++++++ src/empathy-call-window-fullscreen.h | 77 +++++++++ 2 files changed, 386 insertions(+) create mode 100644 src/empathy-call-window-fullscreen.c create mode 100644 src/empathy-call-window-fullscreen.h (limited to 'src') diff --git a/src/empathy-call-window-fullscreen.c b/src/empathy-call-window-fullscreen.c new file mode 100644 index 000000000..1b993458b --- /dev/null +++ b/src/empathy-call-window-fullscreen.c @@ -0,0 +1,309 @@ +/* + * empathy-call-window-fullscreen.c - Source for EmpathyCallWindowFullscreen + * Copyright (C) 2009-2011 Collabora Ltd. + * + * Some code is based on the Totem Movie Player, especially + * totem-fullscreen.c which has the following copyright: + * Copyright (C) 2001-2007 Bastien Nocera + * Copyright (C) 2007 Sunil Mohan Adapa + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "empathy-call-window-fullscreen.h" + +#include + +#include +#include + +/* The number of seconds for which the "leave fullscreen" popup should + be shown */ +#define FULLSCREEN_POPUP_TIMEOUT 5 + +G_DEFINE_TYPE (EmpathyCallWindowFullscreen, empathy_call_window_fullscreen, + G_TYPE_OBJECT) + +/* private structure */ +typedef struct _EmpathyCallWindowFullscreenPriv + EmpathyCallWindowFullscreenPriv; + +struct _EmpathyCallWindowFullscreenPriv +{ + EmpathyCallWindow *parent_window; + + GtkWidget *leave_fullscreen_popup; + GtkWidget *video_widget; + + guint popup_timeout; + gboolean popup_creation_in_progress; + gboolean dispose_has_run; +}; + +#define GET_PRIV(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowFullscreenPriv)) + +static void empathy_call_window_fullscreen_dispose (GObject *object); +static void empathy_call_window_fullscreen_finalize (GObject *object); + +static gboolean empathy_call_window_fullscreen_hide_popup ( + EmpathyCallWindowFullscreen *fs); + +static void +empathy_call_window_fullscreen_set_cursor_visible ( + EmpathyCallWindowFullscreen *fs, + gboolean show_cursor) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + GdkWindow *window; + + if (priv->video_widget == NULL) + return; + + window = gtk_widget_get_window (priv->video_widget); + + if (!show_cursor) + gdk_window_set_cursor (window, gdk_cursor_new (GDK_BLANK_CURSOR)); + else + gdk_window_set_cursor (window, NULL); +} + +static void +empathy_call_window_fullscreen_add_popup_timeout ( + EmpathyCallWindowFullscreen *self) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + if (priv->popup_timeout == 0) + { + priv->popup_timeout = g_timeout_add_seconds (FULLSCREEN_POPUP_TIMEOUT, + (GSourceFunc) empathy_call_window_fullscreen_hide_popup, self); + } +} + +static void +empathy_call_window_fullscreen_remove_popup_timeout ( + EmpathyCallWindowFullscreen *self) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + if (priv->popup_timeout != 0) + { + g_source_remove (priv->popup_timeout); + priv->popup_timeout = 0; + } +} + +void +empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self) +{ + gint leave_fullscreen_width, leave_fullscreen_height; + GdkScreen *screen; + GdkRectangle fullscreen_rect; + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + g_assert (self->is_fullscreen); + + g_return_if_fail (priv->parent_window != NULL); + + if (priv->popup_creation_in_progress) + return; + + if (!gtk_window_is_active (GTK_WINDOW (priv->parent_window))) + return; + + priv->popup_creation_in_progress = TRUE; + + empathy_call_window_fullscreen_set_cursor_visible (self, TRUE); + + /* Obtaining the screen rectangle */ + screen = gtk_window_get_screen (GTK_WINDOW (priv->parent_window)); + gdk_screen_get_monitor_geometry (screen, + gdk_screen_get_monitor_at_window (screen, + gtk_widget_get_window (GTK_WIDGET (priv->parent_window))), + &fullscreen_rect); + + /* Getting the popup window sizes */ + gtk_window_get_size (GTK_WINDOW (priv->leave_fullscreen_popup), + &leave_fullscreen_width, &leave_fullscreen_height); + + /* Moving the popup to the top-right corner (if the direction is LTR) or the + top-left corner (if the direction is RTL).*/ + if (gtk_widget_get_direction (priv->leave_fullscreen_popup) + == GTK_TEXT_DIR_LTR) + { + gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), + fullscreen_rect.width + fullscreen_rect.x - leave_fullscreen_width, + fullscreen_rect.y); + + } + else + { + gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), + fullscreen_rect.x, fullscreen_rect.y); + } + + gtk_widget_show_all (priv->leave_fullscreen_popup); + empathy_call_window_fullscreen_add_popup_timeout (self); + + priv->popup_creation_in_progress = FALSE; +} + +static gboolean +empathy_call_window_fullscreen_hide_popup (EmpathyCallWindowFullscreen *fs) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + if (priv->video_widget == NULL || !fs->is_fullscreen) + return TRUE; + + gtk_widget_hide (priv->leave_fullscreen_popup); + empathy_call_window_fullscreen_remove_popup_timeout (fs); + + empathy_call_window_fullscreen_set_cursor_visible (fs, FALSE); + + return FALSE; +} + +static void +empathy_call_window_fullscreen_init (EmpathyCallWindowFullscreen *self) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + GtkBuilder *gui; + gchar *filename; + + filename = empathy_file_lookup ("empathy-call-window-fullscreen.ui", "src"); + gui = empathy_builder_get_file (filename, + "leave_fullscreen_window", &priv->leave_fullscreen_popup, + "leave_fullscreen_button", &self->leave_fullscreen_button, + NULL); + + gtk_widget_add_events (priv->leave_fullscreen_popup, GDK_POINTER_MOTION_MASK); + + g_object_unref (gui); + g_free (filename); +} + +static void +empathy_call_window_fullscreen_class_init ( + EmpathyCallWindowFullscreenClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (EmpathyCallWindowFullscreenPriv)); + + object_class->dispose = empathy_call_window_fullscreen_dispose; + object_class->finalize = empathy_call_window_fullscreen_finalize; +} + +void +empathy_call_window_fullscreen_dispose (GObject *object) +{ + EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (object); + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + if (priv->dispose_has_run) + return; + + priv->dispose_has_run = TRUE; + + if (priv->leave_fullscreen_popup != NULL) + gtk_widget_destroy (priv->leave_fullscreen_popup); + priv->leave_fullscreen_popup = NULL; + + if (G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose) + { + G_OBJECT_CLASS ( + empathy_call_window_fullscreen_parent_class)->dispose (object); + } +} + +void +empathy_call_window_fullscreen_finalize (GObject *object) +{ + EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (object); + + empathy_call_window_fullscreen_remove_popup_timeout (self); + + G_OBJECT_CLASS ( + empathy_call_window_fullscreen_parent_class)->finalize (object); +} + +static void +empathy_call_window_fullscreen_parent_window_notify (GtkWidget *parent_window, + GParamSpec *property, EmpathyCallWindowFullscreen *fs) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + if (!fs->is_fullscreen) + return; + + if (parent_window == GTK_WIDGET (priv->parent_window) && + !gtk_window_is_active (GTK_WINDOW (parent_window))) + { + empathy_call_window_fullscreen_hide_popup (fs); + empathy_call_window_fullscreen_set_cursor_visible (fs, TRUE); + } +} + +EmpathyCallWindowFullscreen * +empathy_call_window_fullscreen_new (EmpathyCallWindow *parent_window) +{ + EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN ( + g_object_new (EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, NULL)); + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + priv->parent_window = parent_window; + g_signal_connect (G_OBJECT (priv->parent_window), "notify::is-active", + G_CALLBACK (empathy_call_window_fullscreen_parent_window_notify), self); + + return self; +} + +void +empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs, + gboolean set_fullscreen) +{ + + if (set_fullscreen) + empathy_call_window_fullscreen_remove_popup_timeout (fs); + else + empathy_call_window_fullscreen_hide_popup (fs); + + empathy_call_window_fullscreen_set_cursor_visible (fs, !set_fullscreen); + fs->is_fullscreen = set_fullscreen; +} + +static void +video_widget_destroy_cb (GtkWidget *widget, + EmpathyCallWindowFullscreen *self) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + priv->video_widget = NULL; +} + +void +empathy_call_window_fullscreen_set_video_widget ( + EmpathyCallWindowFullscreen *fs, + GtkWidget *video_widget) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + priv->video_widget = video_widget; + + tp_g_signal_connect_object (video_widget, "destroy", + G_CALLBACK (video_widget_destroy_cb), fs, 0); +} diff --git a/src/empathy-call-window-fullscreen.h b/src/empathy-call-window-fullscreen.h new file mode 100644 index 000000000..7e9bd63e5 --- /dev/null +++ b/src/empathy-call-window-fullscreen.h @@ -0,0 +1,77 @@ +/* + * empathy-call-window-fullscreen.h - Header for EmpathyCallWindowFullscreen + * Copyright (C) 2009-2011 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_CALL_WINDOW_FULLSCREEN_H__ +#define __EMPATHY_CALL_WINDOW_FULLSCREEN_H__ + +#include +#include + +#include "empathy-call-window.h" + +G_BEGIN_DECLS + +typedef struct _EmpathyCallWindowFullscreen EmpathyCallWindowFullscreen; +typedef struct _EmpathyCallWindowFullscreenClass + EmpathyCallWindowFullscreenClass; + +struct _EmpathyCallWindowFullscreenClass { + GObjectClass parent_class; +}; + +struct _EmpathyCallWindowFullscreen { + GObject parent; + gboolean is_fullscreen; + GtkWidget *leave_fullscreen_button; +}; + +GType empathy_call_window_fullscreen_get_type (void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN \ + (empathy_call_window_fullscreen_get_type ()) +#define EMPATHY_CALL_WINDOW_FULLSCREEN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowFullscreen)) +#define EMPATHY_CALL_WINDOW_FULLSCREEN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowClassFullscreen)) +#define EMPATHY_IS_CALL_WINDOW_FULLSCREEN(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN)) +#define EMPATHY_IS_CALL_WINDOW_FULLSCREEN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN)) +#define EMPATHY_CALL_WINDOW_FULLSCREEN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowFullscreenClass)) + +EmpathyCallWindowFullscreen *empathy_call_window_fullscreen_new ( + EmpathyCallWindow *parent); + +void empathy_call_window_fullscreen_set_fullscreen ( + EmpathyCallWindowFullscreen *fs, + gboolean set_fullscreen); +void empathy_call_window_fullscreen_set_video_widget ( + EmpathyCallWindowFullscreen *fs, + GtkWidget *video_widget); +void empathy_call_window_fullscreen_show_popup ( + EmpathyCallWindowFullscreen *fs); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_CALL_WINDOW_FULLSCREEN_H__*/ -- cgit v1.2.3