+ if (!elem->classes)
+ return;
+
+ for (i = 0; i < elem->classes->len; i++)
+ {
+ GQuark quark;
+
+ quark = g_array_index (elem->classes, GQuark, i);
+
+ if (quark > qname)
+ break;
+ else if (quark == qname)
+ {
+ g_array_remove_index (elem->classes, i);
+ break;
+ }
+ }
+}
+
+/**
+ * gtk_widget_path_iter_clear_classes:
+ * @path: a #GtkWidget
+ * @pos: position to modify, -1 for the path head
+ *
+ * Removes all classes from the widget at position @pos in the
+ * hierarchy defined in @path.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_path_iter_clear_classes (GtkWidgetPath *path,
+ gint pos)
+{
+ GtkPathElement *elem;
+
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (path->elems->len != 0);
+
+ if (pos < 0 || pos >= path->elems->len)
+ pos = path->elems->len - 1;
+
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+
+ if (!elem->classes)
+ return;
+
+ if (elem->classes->len > 0)
+ g_array_remove_range (elem->classes, 0, elem->classes->len);
+}
+
+/**
+ * gtk_widget_path_iter_list_classes:
+ * @path: a #GtkWidgetPath
+ * @pos: position to query, -1 for the path head
+ *
+ * Returns a list with all the class names defined for the widget
+ * at position @pos in the hierarchy defined in @path.
+ *
+ * Returns: (transfer container) (element-type utf8): The list of
+ * classes, This is a list of strings, the #GSList contents
+ * are owned by GTK+, but you should use g_slist_free() to
+ * free the list itself.
+ *
+ * Since: 3.0
+ **/
+GSList *
+gtk_widget_path_iter_list_classes (const GtkWidgetPath *path,
+ gint pos)
+{
+ GtkPathElement *elem;
+ GSList *list = NULL;
+ guint i;
+
+ g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (path->elems->len != 0, NULL);
+
+ if (pos < 0 || pos >= path->elems->len)
+ pos = path->elems->len - 1;
+
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+
+ if (!elem->classes)
+ return NULL;
+
+ for (i = 0; i < elem->classes->len; i++)
+ {
+ GQuark quark;
+
+ quark = g_array_index (elem->classes, GQuark, i);
+ list = g_slist_prepend (list, (gchar *) g_quark_to_string (quark));
+ }
+
+ return g_slist_reverse (list);
+}
+
+/**
+ * gtk_widget_path_iter_has_qclass:
+ * @path: a #GtkWidgetPath
+ * @pos: position to query, -1 for the path head
+ * @qname: class name as a #GQuark
+ *
+ * See gtk_widget_path_iter_has_class(). This is a version that operates
+ * with GQuark<!-- -->s.
+ *
+ * Returns: %TRUE if the widget at @pos has the class defined.
+ *
+ * Since: 3.0
+ **/
+gboolean
+gtk_widget_path_iter_has_qclass (const GtkWidgetPath *path,
+ gint pos,
+ GQuark qname)
+{
+ GtkPathElement *elem;
+ guint i;
+
+ g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (path->elems->len != 0, FALSE);
+ g_return_val_if_fail (qname != 0, FALSE);
+
+ if (pos < 0 || pos >= path->elems->len)
+ pos = path->elems->len - 1;
+
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+
+ if (!elem->classes)
+ return FALSE;
+
+ for (i = 0; i < elem->classes->len; i++)
+ {
+ GQuark quark;
+
+ quark = g_array_index (elem->classes, GQuark, i);
+
+ if (quark == qname)
+ return TRUE;
+ else if (quark > qname)
+ break;
+ }
+
+ return FALSE;
+}
+
+/**
+ * gtk_widget_path_iter_has_class:
+ * @path: a #GtkWidgetPath
+ * @pos: position to query, -1 for the path head
+ * @name: class name
+ *
+ * Returns %TRUE if the widget at position @pos has the class @name
+ * defined, %FALSE otherwise.
+ *
+ * Returns: %TRUE if the class @name is defined for the widget at @pos
+ *
+ * Since: 3.0
+ **/
+gboolean
+gtk_widget_path_iter_has_class (const GtkWidgetPath *path,
+ gint pos,
+ const gchar *name)
+{
+ GQuark qname;
+
+ g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (path->elems->len != 0, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ if (pos < 0 || pos >= path->elems->len)
+ pos = path->elems->len - 1;
+
+ qname = g_quark_try_string (name);
+
+ if (qname == 0)
+ return FALSE;
+
+ return gtk_widget_path_iter_has_qclass (path, pos, qname);
+}
+
+/**
+ * gtk_widget_path_iter_add_region:
+ * @path: a #GtkWidgetPath
+ * @pos: position to modify, -1 for the path head
+ * @name: region name
+ * @flags: flags affecting the region
+ *
+ * Adds the region @name to the widget at position @pos in
+ * the hierarchy defined in @path. See
+ * gtk_style_context_add_region().
+ *
+ * <note><para>Region names must only contain lowercase letters
+ * and '-', starting always with a lowercase letter.</para></note>
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_path_iter_add_region (GtkWidgetPath *path,
+ gint pos,
+ const gchar *name,
+ GtkRegionFlags flags)
+{
+ GtkPathElement *elem;
+ GQuark qname;
+
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (path->elems->len != 0);
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (_gtk_style_context_check_region_name (name));
+
+ if (pos < 0 || pos >= path->elems->len)
+ pos = path->elems->len - 1;
+
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+ qname = g_quark_from_string (name);
+