6f7d1c8943db25d3adcb7e9797f7332ac9b11b46
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index f0307dd..2e6df75 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -316,9 +316,12 @@ GFlagsValue
 g_enum_get_value
 g_enum_get_value_by_name
 g_enum_get_value_by_nick
+g_enum_get_value_from_string
 g_flags_get_first_value
 g_flags_get_value_by_name
 g_flags_get_value_by_nick
+g_flags_get_first_value_from_string
+g_flags_get_value_from_string
 g_enum_register_static
 g_flags_register_static
 g_enum_complete_type_info
diff --git a/gobject/genums.c b/gobject/genums.c
index b49cae5..4a2805c 100644
--- a/gobject/genums.c
+++ b/gobject/genums.c
@@ -622,5 +622,168 @@ g_value_get_flags (const GValue *value)
   return value->data[0].v_ulong;
 }
 
+/**
+ * g_enum_get_value_from_string:
+ * @enum_class: the enum class to translate to
+ * @string: string to parse containing a numeric or a literal name, or
+ * a nick.
+ *
+ * @string is converted to a number first, and returned as a matching
+ * %GEnumValue. If it fails, it is matched with the enum names, and
+ * finally with enum nick names.
+ *
+ * Returns: a %GEnumValue if @string was successfully translated
+ *          to a valid enum value, or %NULL.
+ *
+ * Since: 2.20
+ **/
+const GEnumValue *
+g_enum_get_value_from_string (GEnumClass  *enum_class,
+			      const gchar *string)
+{
+  GEnumValue *enum_value = NULL;
+  gchar *endptr;
+  gint ret;
+
+  g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
+  g_return_val_if_fail (string != NULL, NULL);
+
+  ret = g_ascii_strtoll (string, &endptr, 0);
+  if (endptr != string
+      && endptr == (string + strlen (string))) /* parsed a number */
+    enum_value = g_enum_get_value (enum_class, ret);
+
+  if (!enum_value)
+    {
+      enum_value = g_enum_get_value_by_name (enum_class, string);
+      if (!enum_value)
+	enum_value = g_enum_get_value_by_nick (enum_class, string);
+    }
+
+  return enum_value;
+}
+
+/**
+ * g_flags_get_first_value_from_string:
+ * @flags_class: the flags class to translate to
+ * @string: string to parse containing a numeric or `|' separated list
+ * of literal names, or nicks.
+ *
+ * Returns: the first #GFlagsValue which is set in @value, or %NULL if
+ *          none is set
+ *
+ * Since: 2.20
+ **/
+const GFlagsValue *
+g_flags_get_first_value_from_string (GFlagsClass *flags_class,
+				     const gchar *string)
+{
+  return g_flags_get_first_value (flags_class, g_flags_get_value_from_string (flags_class, string));
+}
+
+/**
+ * g_flags_get_value_from_string:
+ * @flags_class: the flags class to translate to
+ * @string: string to parse containing a numeric or `|' separated list
+ * of literal names, or nicks.
+ *
+ * Returns: the first #GFlagsValue which is set in @value, or %NULL if
+ *          none is set
+ *
+ * Since: 2.20
+ **/
+guint
+g_flags_get_value_from_string (GFlagsClass    *flags_class,
+                               const gchar    *string)
+{
+  GFlagsValue *flags_value = NULL;
+  gchar *endptr, *prevptr;
+  guint i, j, correct, value;
+  gchar *flagstr;
+  const gchar *flag;
+  gunichar ch;
+  gboolean eos;
+
+  g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), 0);
+  g_return_val_if_fail (string != NULL, 0);
+
+  correct = TRUE;
+
+  value = g_ascii_strtoull (string, &endptr, 0);
+  if (endptr != string
+      && endptr == (string + strlen (string))) /* parsed a number */
+    {
+      if (value & ~flags_class->mask) {
+	correct = FALSE;
+	value = 0;
+      }
+    }
+  else
+    {
+
+      flagstr = g_strdup (string);
+      for (value = i = j = 0; ; i++)
+	{
+
+	  eos = flagstr[i] == '\0';
+
+	  if (!eos && flagstr[i] != '|')
+	    continue;
+
+	  flag = &flagstr[j];
+	  endptr = &flagstr[i];
+
+	  if (!eos)
+	    {
+	      flagstr[i++] = '\0';
+	      j = i;
+	    }
+
+	  /* trim spaces */
+	  for (;;)
+	    {
+	      ch = g_utf8_get_char (flag);
+	      if (!g_unichar_isspace (ch))
+		break;
+	      flag = g_utf8_next_char (flag);
+	    }
+
+	  while (endptr > flag)
+	    {
+	      prevptr = g_utf8_prev_char (endptr);
+	      ch = g_utf8_get_char (prevptr);
+	      if (!g_unichar_isspace (ch))
+		break;
+	      endptr = prevptr;
+	    }
+
+	  if (endptr > flag)
+	    {
+	      *endptr = '\0';
+	      flags_value = g_flags_get_value_by_name (flags_class, flag);
+
+	      if (!flags_value)
+		flags_value = g_flags_get_value_by_nick (flags_class, flag);
+
+	      if (flags_value)
+		value |= flags_value->value;
+	      else
+		{
+		  correct = FALSE;
+		  value = 0;
+		  break;
+		}
+	    }
+
+	  if (eos)
+	    break;
+	}
+
+      g_free (flagstr);
+    }
+
+  return value;
+}
+
 #define __G_ENUMS_C__
 #include "gobjectaliasdef.c"
diff --git a/gobject/genums.h b/gobject/genums.h
index 32e885c..03ff994 100644
--- a/gobject/genums.h
+++ b/gobject/genums.h
@@ -229,6 +229,12 @@ GFlagsValue*	g_flags_get_value_by_name	(GFlagsClass	*flags_class,
 						 const gchar	*name);
 GFlagsValue*	g_flags_get_value_by_nick	(GFlagsClass	*flags_class,
 						 const gchar	*nick);
+const GEnumValue* g_enum_get_value_from_string  (GEnumClass     *enum_class,
+                                                 const gchar    *string);
+const GFlagsValue* g_flags_get_first_value_from_string (GFlagsClass *flags_class,
+                                                 const gchar    *string);
+guint           g_flags_get_value_from_string   (GFlagsClass    *flags_class,
+                                                 const gchar    *string);
 void            g_value_set_enum        	(GValue         *value,
 						 gint            v_enum);
 gint            g_value_get_enum        	(const GValue   *value);
@@ -237,7 +243,6 @@ void            g_value_set_flags       	(GValue         *value,
 guint           g_value_get_flags       	(const GValue   *value);
 
 
-
 /* --- registration functions --- */
 /* const_static_values is a NULL terminated array of enum/flags
  * values that is taken over!
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index 7a98dc3..740f4e6 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -87,11 +87,14 @@ g_enum_complete_type_info
 g_enum_get_value
 g_enum_get_value_by_name
 g_enum_get_value_by_nick
+g_enum_get_value_from_string
 g_enum_register_static
 g_flags_complete_type_info
 g_flags_get_first_value
 g_flags_get_value_by_name
 g_flags_get_value_by_nick
+g_flags_get_first_value_from_string
+g_flags_get_value_from_string
 g_flags_register_static
 g_value_set_enum
 g_value_set_flags
@@ -324,7 +327,7 @@ g_type_add_interface_dynamic
 g_type_add_interface_static
 g_type_check_class_cast
 g_type_check_class_is_a
-g_type_check_instance 
+g_type_check_instance
 g_type_check_instance_cast
 g_type_check_instance_is_a
 g_type_check_is_value_type
