From 8946be1f0b504177132345fad8942b547c391515 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 22 Jun 2009 11:40:33 +0300 Subject: [PATCH] x(v)imagesink: catch tags and show title in own window Refactor the code that sets the window title. Catch tag-events and use title metadata for the window title. --- sys/ximage/ximagesink.c | 78 +++++++++++++++++++++++++++++++++++++++++++++ sys/ximage/ximagesink.h | 3 ++ sys/xvimage/xvimagesink.c | 81 +++++++++++++++++++++++++++++++++++++++++++---- sys/xvimage/xvimagesink.h | 3 ++ 4 files changed, 158 insertions(+), 7 deletions(-) diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index e2d73fc..0adc342 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -801,6 +801,46 @@ gst_ximagesink_xwindow_decorate (GstXImageSink * ximagesink, return TRUE; } +static void +gst_ximagesink_xwindow_set_title (GstXImageSink * ximagesink, + const gchar * media_title) +{ + if (media_title) { + g_free (ximagesink->media_title); + ximagesink->media_title = g_strdup (media_title); + } + if (ximagesink->xwindow) { + /* we have a window */ + if (ximagesink->xwindow->internal) { + XTextProperty xproperty; + const gchar *app_name; + const gchar *title = NULL; + gchar *title_mem = NULL; + + /* set application name as a title */ + app_name = g_get_application_name (); + + if (app_name && ximagesink->media_title) { + title = title_mem = g_strconcat (ximagesink->media_title, " : ", + app_name, NULL); + } else if (app_name) { + title = app_name; + } else if (ximagesink->media_title) { + title = ximagesink->media_title; + } + + if (title) { + if ((XStringListToTextProperty (((char **) &title), 1, + &xproperty)) != 0) + XSetWMName (ximagesink->xcontext->disp, ximagesink->xwindow->win, + &xproperty); + + g_free (title_mem); + } + } + } +} + /* This function handles a GstXWindow creation */ static GstXWindow * gst_ximagesink_xwindow_new (GstXImageSink * ximagesink, gint width, gint height) @@ -826,6 +866,9 @@ gst_ximagesink_xwindow_new (GstXImageSink * ximagesink, gint width, gint height) ConfigureNotify. This takes away flickering of video when resizing. */ XSetWindowBackgroundPixmap (ximagesink->xcontext->disp, xwindow->win, None); + /* set application name as a title */ + gst_ximagesink_xwindow_set_title (ximagesink, NULL); + if (ximagesink->handle_events) { Atom wm_delete; @@ -1638,6 +1681,38 @@ no_window: } } + +static gboolean +gst_ximagesink_event (GstBaseSink * sink, GstEvent * event) +{ + GstXImageSink *ximagesink = GST_XIMAGESINK (sink); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG:{ + GstTagList *l; + gchar *title = NULL; + + gst_event_parse_tag (event, &l); + gst_tag_list_get_string (l, GST_TAG_TITLE, &title); + + if (title) { + GST_DEBUG_OBJECT (ximagesink, "got tags, title='%s'", title); + gst_ximagesink_xwindow_set_title (ximagesink, title); + + g_free (title); + } + break; + } + default: + break; + } + if (GST_BASE_SINK_CLASS (parent_class)->event) + return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); + else + return TRUE; +} + + /* Buffer management * * The buffer_alloc function must either return a buffer with given size and @@ -2167,6 +2242,8 @@ gst_ximagesink_finalize (GObject * object) ximagesink->pool_lock = NULL; } + g_free (ximagesink->media_title); + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -2262,6 +2339,7 @@ gst_ximagesink_class_init (GstXImageSinkClass * klass) gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_ximagesink_get_times); gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_ximagesink_show_frame); gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_ximagesink_show_frame); + gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_ximagesink_event); } /* ============================================================= */ diff --git a/sys/ximage/ximagesink.h b/sys/ximage/ximagesink.h index 531b24e..75e5f52 100644 --- a/sys/ximage/ximagesink.h +++ b/sys/ximage/ximagesink.h @@ -215,6 +215,9 @@ struct _GstXImageSink { gboolean handle_events; gboolean handle_expose; gboolean draw_border; + + /* stream metadata */ + gchar *media_title; }; struct _GstXImageSinkClass { diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index c033a33..99a6511 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -906,6 +906,46 @@ gst_xvimagesink_xwindow_decorate (GstXvImageSink * xvimagesink, return TRUE; } +static void +gst_xvimagesink_xwindow_set_title (GstXvImageSink * xvimagesink, + const gchar * media_title) +{ + if (media_title) { + g_free (xvimagesink->media_title); + xvimagesink->media_title = g_strdup (media_title); + } + if (xvimagesink->xwindow) { + /* we have a window */ + if (xvimagesink->xwindow->internal) { + XTextProperty xproperty; + const gchar *app_name; + const gchar *title = NULL; + gchar *title_mem = NULL; + + /* set application name as a title */ + app_name = g_get_application_name (); + + if (app_name && xvimagesink->media_title) { + title = title_mem = g_strconcat (xvimagesink->media_title, " : ", + app_name, NULL); + } else if (app_name) { + title = app_name; + } else if (xvimagesink->media_title) { + title = xvimagesink->media_title; + } + + if (title) { + if ((XStringListToTextProperty (((char **) &title), 1, + &xproperty)) != 0) + XSetWMName (xvimagesink->xcontext->disp, xvimagesink->xwindow->win, + &xproperty); + + g_free (title_mem); + } + } + } +} + /* This function handles a GstXWindow creation * The width and height are the actual pixel size on the display */ static GstXWindow * @@ -914,8 +954,6 @@ gst_xvimagesink_xwindow_new (GstXvImageSink * xvimagesink, { GstXWindow *xwindow = NULL; XGCValues values; - XTextProperty xproperty; - const gchar *title; g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), NULL); @@ -937,11 +975,7 @@ gst_xvimagesink_xwindow_new (GstXvImageSink * xvimagesink, XSetWindowBackgroundPixmap (xvimagesink->xcontext->disp, xwindow->win, None); /* set application name as a title */ - title = g_get_application_name (); - if (title) { - if ((XStringListToTextProperty (((char **) &title), 1, &xproperty)) != 0) - XSetWMName (xvimagesink->xcontext->disp, xwindow->win, &xproperty); - } + gst_xvimagesink_xwindow_set_title (xvimagesink, NULL); if (xvimagesink->handle_events) { Atom wm_delete; @@ -2341,6 +2375,36 @@ no_window: } } +static gboolean +gst_xvimagesink_event (GstBaseSink * sink, GstEvent * event) +{ + GstXvImageSink *xvimagesink = GST_XVIMAGESINK (sink); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG:{ + GstTagList *l; + gchar *title = NULL; + + gst_event_parse_tag (event, &l); + gst_tag_list_get_string (l, GST_TAG_TITLE, &title); + + if (title) { + GST_DEBUG_OBJECT (xvimagesink, "got tags, title='%s'", title); + gst_xvimagesink_xwindow_set_title (xvimagesink, title); + + g_free (title); + } + break; + } + default: + break; + } + if (GST_BASE_SINK_CLASS (parent_class)->event) + return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); + else + return TRUE; +} + /* Buffer management */ static GstFlowReturn @@ -3236,6 +3300,8 @@ gst_xvimagesink_finalize (GObject * object) xvimagesink->pool_lock = NULL; } + g_free (xvimagesink->media_title); + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -3422,6 +3488,7 @@ gst_xvimagesink_class_init (GstXvImageSinkClass * klass) gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_xvimagesink_get_times); gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_xvimagesink_show_frame); gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_xvimagesink_show_frame); + gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_xvimagesink_event); } /* ============================================================= */ diff --git a/sys/xvimage/xvimagesink.h b/sys/xvimage/xvimagesink.h index 56cf594..02995f8 100644 --- a/sys/xvimage/xvimagesink.h +++ b/sys/xvimage/xvimagesink.h @@ -283,6 +283,9 @@ struct _GstXvImageSink { gboolean have_autopaint_colorkey; gboolean have_colorkey; gboolean have_double_buffer; + + /* stream metadata */ + gchar *media_title; }; struct _GstXvImageSinkClass { -- 2.7.4