diff options
Diffstat (limited to 'src/empathy-call-window.c')
-rw-r--r-- | src/empathy-call-window.c | 240 |
1 files changed, 227 insertions, 13 deletions
diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index 22a9eef44..b05999d8c 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -24,6 +24,7 @@ #include <math.h> +#include <gdk/gdkkeysyms.h> #include <gst/gst.h> #include <gtk/gtk.h> #include <glib/gi18n.h> @@ -39,10 +40,15 @@ #include "empathy-call-window.h" +#include "empathy-call-window-fullscreen.h" #include "empathy-sidebar.h" #define BUTTON_ID "empathy-call-dtmf-button-id" +#define CONTENT_HBOX_BORDER_WIDTH 6 +#define CONTENT_HBOX_SPACING 3 +#define CONTENT_HBOX_CHILDREN_PACKING_PADDING 3 + G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW) /* signal enum */ @@ -83,6 +89,14 @@ struct _EmpathyCallWindowPriv GtkWidget *pane; GtkAction *send_video; + /* We keep a reference on the hbox which contains the main content so we can + easilly repack everything when toggling fullscreen */ + GtkWidget *content_hbox; + + /* This vbox is contained in the content_hbox. When toggling fullscreen, + it needs to be repacked. We keep a reference on it for easier access. */ + GtkWidget *vbox; + gdouble volume; GtkAdjustment *audio_input_adj; @@ -109,6 +123,8 @@ struct _EmpathyCallWindowPriv GMutex *lock; gboolean call_started; gboolean sending_video; + + EmpathyCallWindowFullscreen *fullscreen; }; #define GET_PRIV(o) \ @@ -119,7 +135,10 @@ static void empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window); static gboolean empathy_call_window_delete_cb (GtkWidget *widget, - GdkEvent*event, EmpathyCallWindow *window); + GdkEvent *event, EmpathyCallWindow *window); + +static gboolean empathy_call_window_state_event_cb (GtkWidget *widget, + GdkEventWindowState *event, EmpathyCallWindow *window); static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle, EmpathyCallWindow *window); @@ -139,9 +158,26 @@ static void empathy_call_window_mic_toggled_cb ( static void empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar, EmpathyCallWindow *window); +static void empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar, + EmpathyCallWindow *window); + static void empathy_call_window_hangup_cb (gpointer object, EmpathyCallWindow *window); +static void empathy_call_window_fullscreen_cb (gpointer object, + EmpathyCallWindow *window); + +static void empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window); + +static gboolean empathy_call_window_video_button_press_cb (GtkWidget *video_output, + GdkEventButton *event, EmpathyCallWindow *window); + +static gboolean empathy_call_window_key_press_cb (GtkWidget *video_output, + GdkEventKey *event, EmpathyCallWindow *window); + +static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window, + guint button); + static void empathy_call_window_status_message (EmpathyCallWindow *window, gchar *message); @@ -459,8 +495,8 @@ empathy_call_window_init (EmpathyCallWindow *self) { EmpathyCallWindowPriv *priv = GET_PRIV (self); GtkBuilder *gui; - GtkWidget *vbox, *top_vbox; - GtkWidget *hbox, *h; + GtkWidget *top_vbox; + GtkWidget *h; GtkWidget *arrow; GtkWidget *page; GstBus *bus; @@ -485,6 +521,7 @@ empathy_call_window_init (EmpathyCallWindow *self) "camera", "toggled", empathy_call_window_camera_toggled_cb, "send_video", "toggled", empathy_call_window_send_video_toggled_cb, "show_preview", "toggled", empathy_call_window_show_preview_toggled_cb, + "menufullscreen", "activate", empathy_call_window_fullscreen_cb, NULL); priv->lock = g_mutex_new (); @@ -495,27 +532,34 @@ empathy_call_window_init (EmpathyCallWindow *self) priv->pipeline = gst_pipeline_new (NULL); - hbox = gtk_hbox_new (FALSE, 3); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 6); - gtk_paned_pack1 (GTK_PANED (priv->pane), hbox, TRUE, FALSE); + priv->content_hbox = gtk_hbox_new (FALSE, CONTENT_HBOX_SPACING); + gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), + CONTENT_HBOX_BORDER_WIDTH); + gtk_paned_pack1 (GTK_PANED (priv->pane), priv->content_hbox, TRUE, FALSE); bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); gst_bus_add_watch (bus, empathy_call_window_bus_message, self); priv->video_output = empathy_video_widget_new (bus); - gtk_box_pack_start (GTK_BOX (hbox), priv->video_output, TRUE, TRUE, 3); + gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->video_output, + TRUE, TRUE, CONTENT_HBOX_CHILDREN_PACKING_PADDING); + gtk_widget_add_events (priv->video_output, + GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); + g_signal_connect (G_OBJECT (priv->video_output), "button-press-event", + G_CALLBACK (empathy_call_window_video_button_press_cb), self); priv->video_tee = gst_element_factory_make ("tee", NULL); gst_object_ref (priv->video_tee); gst_object_sink (priv->video_tee); - vbox = gtk_vbox_new (FALSE, 3); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 3); + priv->vbox = gtk_vbox_new (FALSE, 3); + gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->vbox, + FALSE, FALSE, CONTENT_HBOX_CHILDREN_PACKING_PADDING); priv->video_preview = empathy_video_widget_new_with_size (bus, 160, 120); g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); - gtk_box_pack_start (GTK_BOX (vbox), priv->video_preview, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (priv->vbox), priv->video_preview, FALSE, FALSE, 0); priv->video_input = empathy_video_src_new (); gst_object_ref (priv->video_input); @@ -539,13 +583,14 @@ empathy_call_window_init (EmpathyCallWindow *self) gtk_button_set_image (GTK_BUTTON (priv->sidebar_button), arrow); h = gtk_hbox_new (FALSE, 3); - gtk_box_pack_end (GTK_BOX (vbox), h, FALSE, FALSE, 3); + gtk_box_pack_end (GTK_BOX (priv->vbox), h, FALSE, FALSE, 3); gtk_box_pack_end (GTK_BOX (h), priv->sidebar_button, FALSE, FALSE, 3); priv->sidebar = empathy_sidebar_new (); g_signal_connect (G_OBJECT (priv->sidebar), - "hide", G_CALLBACK (empathy_call_window_sidebar_hidden_cb), - self); + "hide", G_CALLBACK (empathy_call_window_sidebar_hidden_cb), self); + g_signal_connect (G_OBJECT (priv->sidebar), + "show", G_CALLBACK (empathy_call_window_sidebar_shown_cb), self); gtk_paned_pack2 (GTK_PANED (priv->pane), priv->sidebar, FALSE, FALSE); priv->dtmf_panel = empathy_call_window_create_dtmf (self); @@ -566,18 +611,30 @@ empathy_call_window_init (EmpathyCallWindow *self) gtk_widget_hide (priv->sidebar); + priv->fullscreen = empathy_call_window_fullscreen_new (self); + empathy_call_window_fullscreen_set_video_widget (priv->fullscreen, priv->video_output); + g_signal_connect (G_OBJECT (priv->fullscreen->leave_fullscreen_button), + "clicked", G_CALLBACK (empathy_call_window_fullscreen_cb), self); + g_signal_connect (G_OBJECT (self), "realize", G_CALLBACK (empathy_call_window_realized_cb), self); g_signal_connect (G_OBJECT (self), "delete-event", G_CALLBACK (empathy_call_window_delete_cb), self); + g_signal_connect (G_OBJECT (self), "window-state-event", + G_CALLBACK (empathy_call_window_state_event_cb), self); + + g_signal_connect (G_OBJECT (self), "key-press-event", + G_CALLBACK (empathy_call_window_key_press_cb), self); + empathy_call_window_status_message (self, _("Connecting...")); priv->timer = g_timer_new (); g_object_ref (priv->ui_manager); g_object_unref (gui); + g_free (filename); } static void @@ -1166,6 +1223,91 @@ empathy_call_window_delete_cb (GtkWidget *widget, GdkEvent*event, } static void +show_controls (EmpathyCallWindow *window, gboolean set_fullscreen) +{ + GtkWidget *menu; + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + menu = gtk_ui_manager_get_widget (priv->ui_manager, + "/menubar1"); + + if (set_fullscreen) + { + gtk_widget_hide (priv->sidebar); + gtk_widget_hide (menu); + gtk_widget_hide (priv->vbox); + gtk_widget_hide (priv->statusbar); + gtk_widget_hide (priv->toolbar); + } + else + { + if (priv->fullscreen->sidebar_was_visible) + gtk_widget_show (priv->sidebar); + + gtk_widget_show (menu); + gtk_widget_show (priv->vbox); + gtk_widget_show (priv->statusbar); + gtk_widget_show (priv->toolbar); + + gtk_window_resize (GTK_WINDOW (window), + priv->fullscreen->original_width, + priv->fullscreen->original_height); + } +} + +static void +show_borders (EmpathyCallWindow *window, gboolean set_fullscreen) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), + set_fullscreen ? 0 : CONTENT_HBOX_BORDER_WIDTH); + gtk_box_set_spacing (GTK_BOX (priv->content_hbox), + set_fullscreen ? 0 : CONTENT_HBOX_SPACING); + gtk_box_set_child_packing (GTK_BOX (priv->content_hbox), + priv->video_output, TRUE, TRUE, + set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING, + GTK_PACK_START); + gtk_box_set_child_packing (GTK_BOX (priv->content_hbox), + priv->vbox, TRUE, TRUE, + set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING, + GTK_PACK_START); +} + +static gboolean +empathy_call_window_state_event_cb (GtkWidget *widget, + GdkEventWindowState *event, EmpathyCallWindow *window) +{ + if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) + { + EmpathyCallWindowPriv *priv = GET_PRIV (window); + gboolean set_fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN; + + if (set_fullscreen) + { + gboolean sidebar_was_visible; + gint original_width = GTK_WIDGET (window)->allocation.width; + gint original_height = GTK_WIDGET (window)->allocation.height; + + g_object_get (priv->sidebar, "visible", + &sidebar_was_visible, NULL); + + empathy_call_window_fullscreen_set_fullscreen (priv->fullscreen, + sidebar_was_visible, original_width, original_height); + } + else + { + empathy_call_window_fullscreen_unset_fullscreen(priv->fullscreen); + } + + show_controls (window, set_fullscreen); + show_borders (window, set_fullscreen); + } + + return FALSE; +} + +static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle, EmpathyCallWindow *window) { @@ -1290,6 +1432,16 @@ empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar, } static void +empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar, + EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->sidebar_button), + TRUE); +} + +static void empathy_call_window_hangup_cb (gpointer object, EmpathyCallWindow *window) { @@ -1300,6 +1452,68 @@ empathy_call_window_hangup_cb (gpointer object, } static void +empathy_call_window_fullscreen_cb (gpointer object, + EmpathyCallWindow *window) +{ + empathy_call_window_fullscreen_toggle (window); +} + +static void +empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + if (priv->fullscreen->is_fullscreen) + gtk_window_unfullscreen (GTK_WINDOW (window)); + else + gtk_window_fullscreen (GTK_WINDOW (window)); +} + +static gboolean +empathy_call_window_video_button_press_cb (GtkWidget *video_output, + GdkEventButton *event, EmpathyCallWindow *window) +{ + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + { + empathy_call_window_video_menu_popup (window, event->button); + return TRUE; + } + + return FALSE; +} + +static gboolean +empathy_call_window_key_press_cb (GtkWidget *video_output, + GdkEventKey *event, EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + if (priv->fullscreen->is_fullscreen && event->keyval == GDK_Escape) + { + /* Since we are in fullscreen mode, toggling will bring us back to + normal mode. */ + empathy_call_window_fullscreen_toggle (window); + return TRUE; + } + + return FALSE; +} + +static void +empathy_call_window_video_menu_popup (EmpathyCallWindow *window, + guint button) +{ + GtkWidget *menu; + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + menu = gtk_ui_manager_get_widget (priv->ui_manager, + "/video-popup"); + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, + button, gtk_get_current_event_time ()); + gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); +} + +static void empathy_call_window_status_message (EmpathyCallWindow *window, gchar *message) { |