+
+
+#define split_ifaces(ifaces) (g_strsplit (ifaces, ";", 0))
+
+static gboolean
+match_interfaces_all_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
+ gchar **ifaces;
+ gint i, length;
+
+ if (interfaces == NULL)
+ return TRUE;
+
+ ifaces = split_ifaces (interfaces);
+ length = g_strv_length (ifaces);
+
+ for (i = 0; i < length; i++)
+ if (!child_interface_p (obj, ifaces [i], ev)){
+ g_free (ifaces);
+ return FALSE;
+ }
+ return TRUE;
+
+
+}
+
+static gboolean
+match_interfaces_any_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
+ gchar **ifaces;
+ gint i, length;
+
+ if (interfaces == NULL)
+ return TRUE;
+
+ ifaces = split_ifaces (interfaces);
+ length = g_strv_length (ifaces);
+
+ for (i = 0; i < length; i++)
+ if (child_interface_p (obj, ifaces [i], ev)){
+ g_free (ifaces);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+match_interfaces_none_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
+
+ gchar **ifaces = split_ifaces (interfaces);
+ gint i, length = g_strv_length (ifaces);
+
+ if (length == 0)
+ return TRUE;
+
+ for (i = 0; i < length; i++)
+ if (child_interface_p (obj, ifaces [i], ev))
+ return FALSE;
+
+ return TRUE;
+
+
+}
+
+static gboolean
+match_interfaces_lookup (Accessibility_Accessible child, MatchRulePrivate *mrp, CORBA_Environment *ev){
+
+ switch (mrp->interfacematchtype){
+
+ case Accessibility_Collection_MATCH_ALL :
+ if (match_interfaces_all_p (child, mrp->interfaces, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_ANY :
+ if (match_interfaces_any_p (child, mrp->interfaces, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_NONE :
+ if (match_interfaces_none_p (child, mrp->interfaces, ev))
+ return TRUE;
+ break;
+
+ default : break;
+ }
+
+ return FALSE;
+}
+
+#define split_attributes(attributes) (g_strsplit (attributes, ";", 0))
+
+static gboolean
+match_attributes_all_p (Accessibility_Accessible child, Accessibility_AttributeSet *attributes, CORBA_Environment *ev){
+
+ int i, k;
+ Accessibility_AttributeSet *oa ;
+ gboolean flag = FALSE;
+
+ if (attributes->_length == 0 || attributes == NULL)
+ return TRUE;
+
+ oa = Accessibility_Accessible_getAttributes (child, ev);
+
+ for (i = 0; i < attributes->_length; i++){
+ for (k = 0; k < oa->_length; k++)
+ if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer [i]))
+ flag = TRUE;
+ else
+ flag = FALSE;
+ if (!flag)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+match_attributes_any_p (Accessibility_Accessible child, Accessibility_AttributeSet *attributes, CORBA_Environment *ev){
+
+ int i, k;
+
+ Accessibility_AttributeSet *oa;
+
+ if (attributes->_length == 0 || attributes == NULL)
+ return TRUE;
+
+ oa = Accessibility_Accessible_getAttributes (child, ev);
+
+ for (i = 0; i < attributes->_length; i++)
+ for (k = 0; k < oa->_length; k++)
+ if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer[i]))
+ return TRUE;
+ return FALSE;
+}
+
+
+
+static gboolean
+match_attributes_none_p (Accessibility_Accessible child, Accessibility_AttributeSet *attributes, CORBA_Environment *ev){
+
+ int i, k;
+ Accessibility_AttributeSet *oa;
+ gboolean flag = FALSE;
+
+ if (attributes->_length == 0 || attributes == NULL)
+ return TRUE;
+
+ oa = Accessibility_Accessible_getAttributes (child, ev);
+
+ for (i = 0; i < attributes->_length; i++){
+ for (k = 0; k < oa->_length; k++)
+ if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer [i]))
+ flag = FALSE;
+ else
+ flag = TRUE;
+ if (flag)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+
+static gboolean
+match_attributes_lookup (Accessibility_Accessible child, MatchRulePrivate *mrp, CORBA_Environment *ev){
+
+ switch (mrp->attributematchtype){
+
+ case Accessibility_Collection_MATCH_ALL :
+ if (match_attributes_all_p (child, mrp->attributes, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_ANY :
+ if (match_attributes_any_p (child, mrp->attributes, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_NONE :
+ if (match_attributes_none_p (child, mrp->attributes, ev))
+ return TRUE;
+ break;
+
+ default : break;
+ }
+
+ return FALSE;
+
+
+
+}
+
+static gboolean
+traverse_p (Accessibility_Accessible child,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ if (traverse)
+ return TRUE;
+ else return !child_collection_p (child, ev);
+
+}
+
+static int
+sort_order_canonical (MatchRulePrivate *mrp, GList *ls,
+ gint kount, gint max,
+ Accessibility_Accessible obj, glong index, gboolean flag,
+ Accessibility_Accessible pobj, CORBA_boolean recurse,
+ CORBA_boolean traverse, CORBA_Environment *ev){
+
+ gint i = index;
+ glong acount = Accessibility_Accessible__get_childCount (obj, ev);
+ gboolean prev = pobj? TRUE : FALSE;
+
+ for (; i < acount && (max == 0 || kount < max); i++){
+ Accessibility_Accessible child = Accessibility_Accessible_getChildAtIndex (obj, i, ev);
+
+
+ if (prev && CORBA_Object_is_equivalent (child, pobj, ev)){
+
+ return kount;
+
+ }
+
+ if (flag && match_interfaces_lookup (child, mrp, ev) && match_states_lookup (child, mrp, ev)
+ && match_roles_lookup (child, mrp, ev)
+ && match_attributes_lookup (child, mrp, ev)
+ ){
+
+ ls = g_list_append (ls, child);
+
+ kount++;
+ }
+
+ if (!flag)
+ flag = TRUE;
+
+
+ if (recurse && traverse_p (child, traverse, ev))
+ kount = sort_order_canonical (mrp, ls, kount, max, child, 0, TRUE, pobj, recurse, traverse, ev);
+ }
+ return kount;
+}
+
+static int
+query_exec (MatchRulePrivate *mrp, Accessibility_Collection_SortOrder sortby,
+ GList *ls, gint kount, gint max,
+ Accessibility_Accessible obj, glong index,
+ gboolean flag,
+ Accessibility_Accessible pobj,
+ CORBA_boolean recurse, CORBA_boolean traverse,
+ CORBA_Environment *ev){
+ switch (sortby) {
+ case Accessibility_Collection_SORT_ORDER_CANONICAL : kount = sort_order_canonical (mrp, ls, 0, max, obj, index, flag, pobj, recurse, traverse, ev);
+ break;
+ case Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL :
+ kount = sort_order_canonical (mrp, ls, 0, max, obj, index, flag, pobj, recurse, traverse, ev);
+ break;
+
+ default: kount = 0; g_warning ("Sort method not implemented yet"); break;
+ }
+
+ return kount;
+
+}
+
+
+static Accessibility_AccessibleSet *
+_accessible_list_to_set (GList *ls, gint kount){
+ Accessibility_AccessibleSet *retval;
+ gint i;
+
+ retval = Accessibility_AccessibleSet__alloc ();
+ retval->_maximum = kount;
+ retval->_length = kount;
+ retval->_buffer = Accessibility_AccessibleSet_allocbuf (kount);
+
+ for (i=0; i < kount; i++){
+ retval->_buffer [i] = ls->data;
+ ls = g_list_next (ls);
+ }
+
+ CORBA_sequence_set_release (retval, TRUE);
+
+ return retval;
+}
+
+static Accessibility_AccessibleSet *
+impl_getMatchesFrom (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ const CORBA_boolean restrict,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ GList *ls = NULL;
+ Accessibility_Accessible parent;
+ MatchRulePrivate *mrp;
+ glong index = Accessibility_Accessible_getIndexInParent (current_object, ev);
+ gint kount = 0;
+
+ ls = g_list_append (ls, current_object);
+ mrp = get_collection_from_servant (servant)->_mrp;;
+
+ if (!restrict){
+ parent = Accessibility_Accessible__get_parent (current_object, ev);
+ kount = query_exec (mrp, sortby, ls, 0, count, parent, index, FALSE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
+
+ }
+ else
+ kount = query_exec (mrp, sortby, ls, 0,count, current_object, 0, FALSE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
+
+
+ ls = g_list_next (ls);
+
+ if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+}
+
+
+static Accessibility_AccessibleSet *
+impl_getMatchesTo (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ const CORBA_boolean restrict,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+
+ GList *ls = NULL;
+ AtkObject *aobj;
+ Accessibility_Accessible obj;
+ MatchRulePrivate *mrp;
+ gint kount = 0;
+
+
+ ls = g_list_append (ls, current_object);
+ mrp = get_collection_from_servant (servant)->_mrp;
+
+
+ if (restrict){
+ obj = Accessibility_Accessible__get_parent (current_object, ev);
+ kount = query_exec (mrp, sortby, ls, 0, count, obj, 0, TRUE, current_object, TRUE, traverse, ev);
+ }
+ else{
+ aobj = get_atkobject_from_servant (servant);
+ obj = spi_accessible_new_return (aobj, FALSE, ev);
+ kount = query_exec (mrp, sortby, ls, 0, count, obj, 0, TRUE, current_object, TRUE, traverse, ev);
+
+ }
+
+ ls = g_list_next (ls);
+
+ if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+
+}
+
+
+
+static Accessibility_AccessibleSet *
+impl_getMatches (PortableServer_Servant servant,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+ GList *ls = NULL;
+ AtkObject *aobj = get_atkobject_from_servant (servant);
+ Accessibility_Accessible obj;
+ MatchRulePrivate *mrp;
+ gint kount = 0;
+
+ obj = spi_accessible_new_return (aobj, FALSE, ev);
+ ls = g_list_prepend (ls, obj);
+ mrp = get_collection_from_servant (servant)->_mrp;
+
+ kount = query_exec (mrp, sortby, ls, 0, count, obj, 0, TRUE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
+
+ ls = g_list_next (ls);
+
+ if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+}
+