Add a check for lack of memory
[platform/core/uifw/at-spi2-atk.git] / libspi / stateset.c
index ef9c58d..7ebeeaf 100644 (file)
@@ -2,7 +2,8 @@
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
- * Copyright 2001 Sun Microsystems Inc.
+ * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2002 Ximian, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -36,16 +37,23 @@ spi_init_state_type_tables (void)
 {
   gint i;
 
+  if (accessible_state_types || atk_state_types)
+    return FALSE;
+  if (!accessible_state_types)
+    accessible_state_types = g_new (Accessibility_StateType, ATK_STATE_LAST_DEFINED);
+  if (!atk_state_types)
+    atk_state_types = g_new (AtkStateType, Accessibility_STATE_LAST_DEFINED);
   g_return_val_if_fail (accessible_state_types, FALSE);
   g_return_val_if_fail (atk_state_types, FALSE);
   
-  accessible_state_types = g_new (Accessibility_StateType, ATK_STATE_LAST_DEFINED);
-  atk_state_types = g_new (AtkStateType, ATK_STATE_LAST_DEFINED);
-
-  for (i = 0; i < ATK_STATE_LAST_DEFINED; i++)
+  for (i = 0; i < Accessibility_STATE_LAST_DEFINED; i++)
     {
       atk_state_types[i] = ATK_STATE_INVALID;
-      accessible_state_types[i] = Accessibility_STATE_INVALID;
+    }
+
+  for (i=0; i < ATK_STATE_LAST_DEFINED; i++)
+    {
+      accessible_state_types[i] = Accessibility_STATE_INVALID; 
     }
 
   accessible_state_types[ATK_STATE_ACTIVE] = Accessibility_STATE_ACTIVE;
@@ -104,11 +112,45 @@ spi_init_state_type_tables (void)
   atk_state_types[Accessibility_STATE_VERTICAL] = ATK_STATE_VERTICAL;
   accessible_state_types[ATK_STATE_VISIBLE] = Accessibility_STATE_VISIBLE;
   atk_state_types[Accessibility_STATE_VISIBLE] = ATK_STATE_VISIBLE;
+  accessible_state_types[ATK_STATE_MANAGES_DESCENDANTS] = Accessibility_STATE_MANAGES_DESCENDANTS;
+  atk_state_types[Accessibility_STATE_MANAGES_DESCENDANTS] = ATK_STATE_MANAGES_DESCENDANTS;
+  accessible_state_types[ATK_STATE_INDETERMINATE] = Accessibility_STATE_INDETERMINATE;
+  atk_state_types[Accessibility_STATE_INDETERMINATE] = ATK_STATE_INDETERMINATE;
+  accessible_state_types[ATK_STATE_TRUNCATED] = Accessibility_STATE_TRUNCATED;
+  atk_state_types[Accessibility_STATE_TRUNCATED] = ATK_STATE_TRUNCATED;
+  accessible_state_types[ATK_STATE_REQUIRED] = Accessibility_STATE_REQUIRED;
+  atk_state_types[Accessibility_STATE_REQUIRED] = ATK_STATE_REQUIRED;
+  accessible_state_types[ATK_STATE_INVALID_ENTRY] = Accessibility_STATE_INVALID_ENTRY;
+  atk_state_types[Accessibility_STATE_INVALID_ENTRY] = ATK_STATE_INVALID_ENTRY;
+  accessible_state_types[ATK_STATE_SUPPORTS_AUTOCOMPLETION] = Accessibility_STATE_SUPPORTS_AUTOCOMPLETION;
+  atk_state_types[Accessibility_STATE_SUPPORTS_AUTOCOMPLETION] = ATK_STATE_SUPPORTS_AUTOCOMPLETION;
+  accessible_state_types[ATK_STATE_SELECTABLE_TEXT] = Accessibility_STATE_SELECTABLE_TEXT;
+  atk_state_types[Accessibility_STATE_SELECTABLE_TEXT] = ATK_STATE_SELECTABLE_TEXT;
+  accessible_state_types[ATK_STATE_DEFAULT] = Accessibility_STATE_IS_DEFAULT;
+  atk_state_types[Accessibility_STATE_IS_DEFAULT] = ATK_STATE_DEFAULT;
+  accessible_state_types[ATK_STATE_VISITED] = Accessibility_STATE_VISITED;
+  atk_state_types[Accessibility_STATE_VISITED] = ATK_STATE_VISITED;
+
 
   return TRUE;
 }
 
+static inline AtkState
+state_spi_to_atk (Accessibility_StateType state)
+{
+  guint idx = state;
+  if (idx < Accessibility_STATE_LAST_DEFINED)
+    return atk_state_types [idx];
+  else
+    return ATK_STATE_INVALID;
+}
 
+AtkState
+spi_atk_state_from_spi_state (Accessibility_StateType state)
+{
+  spi_init_state_type_tables ();
+  return state_spi_to_atk (state);
+}
 
 static AtkStateSet *
 atk_state_set_from_servant (PortableServer_Servant servant)
@@ -119,29 +161,39 @@ atk_state_set_from_servant (PortableServer_Servant servant)
   return  ATK_STATE_SET(base->gobj);
 }
 
+AtkStateSet *
+spi_state_set_cache_from_sequence (const Accessibility_StateSeq *seq)
+{
+  int i;
+  AtkStateSet *set;
+  AtkStateType *states;
 
+  spi_init_state_type_tables ();
+  
+  states = g_newa (AtkStateType, seq->_length);
+  for (i = 0; i < seq->_length; i++)
+    states [i] = state_spi_to_atk (seq->_buffer [i]);
+
+  set = atk_state_set_new ();
+  atk_state_set_add_states (set, states, seq->_length);
+
+  return set;
+}
 
 static AtkStateSet *
 atk_state_set_from_accessibility_state_set (Accessibility_StateSet set, CORBA_Environment *ev)
 {
-  AtkStateType *states, *tmp;
   AtkStateSet *rv;
-  gint i;
   Accessibility_StateSeq *seq;
   
   seq = Accessibility_StateSet_getStates (set, ev);
-  states = tmp = g_new (AtkStateType, seq->_length);
-  for (i = 0; i < seq->_length; i++)
-    *tmp++ = atk_state_types[seq->_buffer[i]];
-  rv = atk_state_set_new ();
-  atk_state_set_add_states (rv, states, seq->_length);
+  rv = spi_state_set_cache_from_sequence (seq);
   CORBA_free (seq);
-  g_free (states);
+
   return rv;
 }
 
 
-
 SpiStateSet *
 spi_state_set_new (AtkStateSet *obj)
 {
@@ -151,7 +203,6 @@ spi_state_set_new (AtkStateSet *obj)
 }
 
 
-
 static CORBA_boolean
 impl_contains (PortableServer_Servant servant,
               const Accessibility_StateType state,
@@ -160,25 +211,22 @@ impl_contains (PortableServer_Servant servant,
   AtkStateSet *set = atk_state_set_from_servant (servant);
 
   g_return_val_if_fail (set, FALSE);
-  return (CORBA_boolean)
-    atk_state_set_contains_state (set, atk_state_types[state]);
+  return atk_state_set_contains_state (set, state_spi_to_atk (state));
 }
 
 
-
 static void 
-impl_add(PortableServer_Servant servant,
-    const Accessibility_StateType state,
-    CORBA_Environment * ev)
+impl_add (PortableServer_Servant servant,
+         const Accessibility_StateType state,
+         CORBA_Environment * ev)
 {
   AtkStateSet *set = atk_state_set_from_servant (servant);
 
   g_return_if_fail (set);
-  atk_state_set_add_state (set, atk_state_types[state]);
+  atk_state_set_add_state (set, state_spi_to_atk (state));
 }
 
 
-
 static void 
 impl_remove (PortableServer_Servant servant,
             const Accessibility_StateType state,
@@ -187,11 +235,10 @@ impl_remove (PortableServer_Servant servant,
   AtkStateSet *set = atk_state_set_from_servant (servant);
 
   g_return_if_fail (set);
-  atk_state_set_remove_state (set, atk_state_types[state]);
+  atk_state_set_remove_state (set, state_spi_to_atk (state));
 }
 
 
-
 static CORBA_boolean
 impl_equals (PortableServer_Servant servant,
             const Accessibility_StateSet stateSet,
@@ -210,8 +257,7 @@ impl_equals (PortableServer_Servant servant,
   g_object_unref (G_OBJECT(set2));
   if (return_set)
     {
-      rv = (CORBA_boolean)
-       atk_state_set_is_empty (return_set);
+      rv = atk_state_set_is_empty (return_set);
       g_object_unref (G_OBJECT(return_set));
     }
   else
@@ -220,7 +266,6 @@ impl_equals (PortableServer_Servant servant,
 }
 
 
-
 static Accessibility_StateSet
 impl_compare (PortableServer_Servant servant,
              const Accessibility_StateSet compareState,
@@ -230,7 +275,7 @@ impl_compare (PortableServer_Servant servant,
   AtkStateSet *set2, *return_set;
   SpiStateSet *spi_set;
   
-  g_return_val_if_fail (set, FALSE);
+  g_return_val_if_fail (set, NULL);
 
   set2 = atk_state_set_from_accessibility_state_set (compareState, ev);
   g_return_val_if_fail (set2, CORBA_OBJECT_NIL);
@@ -242,7 +287,6 @@ impl_compare (PortableServer_Servant servant,
 }
 
 
-
 static CORBA_boolean
 impl_isEmpty (PortableServer_Servant servant,
              CORBA_Environment * ev)
@@ -250,12 +294,10 @@ impl_isEmpty (PortableServer_Servant servant,
   AtkStateSet *set = atk_state_set_from_servant (servant);
 
   g_return_val_if_fail (set, TRUE);
-  return (CORBA_boolean)
-    atk_state_set_is_empty (set);
+  return atk_state_set_is_empty (set);
 }
 
 
-
 static Accessibility_StateSeq *
 impl_getStates (PortableServer_Servant servant,
                CORBA_Environment * ev)
@@ -326,6 +368,24 @@ impl_getStates (PortableServer_Servant servant,
     states = g_slist_append (states, (gpointer) Accessibility_STATE_VERTICAL);
   if (atk_state_set_contains_state (set, ATK_STATE_VISIBLE))
     states = g_slist_append (states, (gpointer) Accessibility_STATE_VISIBLE);
+  if (atk_state_set_contains_state (set, ATK_STATE_MANAGES_DESCENDANTS))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_MANAGES_DESCENDANTS);
+  if (atk_state_set_contains_state (set, ATK_STATE_INDETERMINATE))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_INDETERMINATE);
+  if (atk_state_set_contains_state (set, ATK_STATE_REQUIRED))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_REQUIRED);
+  if (atk_state_set_contains_state (set, ATK_STATE_TRUNCATED))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_TRUNCATED);
+  if (atk_state_set_contains_state (set, ATK_STATE_ANIMATED))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_ANIMATED);
+  if (atk_state_set_contains_state (set, ATK_STATE_INVALID_ENTRY))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_INVALID_ENTRY);
+  if (atk_state_set_contains_state (set, ATK_STATE_SUPPORTS_AUTOCOMPLETION))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_SUPPORTS_AUTOCOMPLETION);
+  if (atk_state_set_contains_state (set, ATK_STATE_DEFAULT))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_IS_DEFAULT);
+  if (atk_state_set_contains_state (set, ATK_STATE_VISITED))
+    states = g_slist_append (states, (gpointer) Accessibility_STATE_VISITED);
 
   rv = Accessibility_StateSeq__alloc ();
   rv->_length = rv->_maximum = g_slist_length (states);
@@ -341,12 +401,12 @@ impl_getStates (PortableServer_Servant servant,
 }
 
 
-
 static void
 spi_state_set_class_init (SpiStateSetClass *klass)
 {
   POA_Accessibility_StateSet__epv *epv = &klass->epv;
 
+  spi_init_state_type_tables ();
   epv->contains = impl_contains;
   epv->add = impl_add;
   epv->remove = impl_remove;
@@ -366,4 +426,4 @@ spi_state_set_init (SpiStateSet *set)
 BONOBO_TYPE_FUNC_FULL (SpiStateSet,
                       Accessibility_StateSet,
                       SPI_TYPE_BASE,
-                      spi_state_set);
+                      spi_state_set)