clockoverlay: Fix broken string formatting by strftime() on Windows
authorSeungha Yang <seungha@centricular.com>
Sun, 4 Apr 2021 15:34:21 +0000 (00:34 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 8 Apr 2021 08:27:53 +0000 (08:27 +0000)
Like other foobarA variant APIs on Windows, formatted string
by strftime() is ANSI string, not unicode encoded one.
It would be problematic for non-english locale systems.
We should use unicode version API (wcsftime in this case)
whenever it's possible on Windows.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1093>

ext/pango/gstclockoverlay.c
ext/pango/gstclockoverlay.h

index 5e7a5fa..88ddfd5 100644 (file)
@@ -83,7 +83,11 @@ gst_clock_overlay_render_time (GstClockOverlay * overlay)
 #endif
   struct tm *t;
   time_t now;
+#ifdef G_OS_WIN32
+  gunichar2 buf[256];
+#else
   gchar buf[256];
+#endif
 
   now = time (NULL);
 
@@ -100,9 +104,17 @@ gst_clock_overlay_render_time (GstClockOverlay * overlay)
   if (t == NULL)
     return g_strdup ("--:--:--");
 
+#ifdef G_OS_WIN32
+  if (wcsftime (buf, sizeof (buf), (wchar_t *) overlay->wformat, t) == 0)
+    return g_strdup ("");
+
+  return g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
+#else
   if (strftime (buf, sizeof (buf), overlay->format, t) == 0)
     return g_strdup ("");
+
   return g_strdup (buf);
+#endif
 }
 
 /* Called with lock held */
@@ -115,7 +127,10 @@ gst_clock_overlay_get_text (GstBaseTextOverlay * overlay,
 
   txt = g_strdup (overlay->default_text);
 
+  GST_OBJECT_LOCK (overlay);
   time_str = gst_clock_overlay_render_time (clock_overlay);
+  GST_OBJECT_UNLOCK (overlay);
+
   if (txt != NULL && *txt != '\0') {
     ret = g_strdup_printf ("%s %s", txt, time_str);
   } else {
@@ -173,6 +188,8 @@ gst_clock_overlay_finalize (GObject * object)
   g_free (overlay->text);
   overlay->format = NULL;
 
+  g_free (overlay->wformat);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -191,6 +208,11 @@ gst_clock_overlay_init (GstClockOverlay * overlay)
 
   overlay->format = g_strdup (DEFAULT_PROP_TIMEFORMAT);
 
+#ifdef G_OS_WIN32
+  overlay->wformat =
+      g_utf8_to_utf16 (DEFAULT_PROP_TIMEFORMAT, -1, NULL, NULL, NULL);
+#endif
+
   context = textoverlay->pango_context;
 
   pango_context_set_language (context, pango_language_from_string ("en_US"));
@@ -218,6 +240,13 @@ gst_clock_overlay_set_property (GObject * object, guint prop_id,
     case PROP_TIMEFORMAT:
       g_free (overlay->format);
       overlay->format = g_value_dup_string (value);
+      if (!overlay->format)
+        overlay->format = g_strdup (DEFAULT_PROP_TIMEFORMAT);
+#ifdef G_OS_WIN32
+      g_free (overlay->wformat);
+      overlay->wformat =
+          g_utf8_to_utf16 (overlay->format, -1, NULL, NULL, NULL);
+#endif
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
index b3f4a43..3a52c35 100644 (file)
@@ -48,6 +48,10 @@ typedef struct _GstClockOverlayClass GstClockOverlayClass;
 struct _GstClockOverlay {
   GstBaseTextOverlay textoverlay;
   gchar         *format; /* as in strftime () */
+
+  /* for wcsftime */
+  gunichar2     *wformat;
+
   gchar         *text;
 };