Logo Search packages:      
Sourcecode: ldtp version File versions

ldtp-gui.c

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
 * Linux Desktop Testing Project http://ldtp.freedesktop.org
 *
 * Author:
 *    Nagappan A <nagappan@gmail.com>
 *    Poornima <pnayak@novell.com>
 *    Premkumar J <jpremkumar@novell.com>
 *
 * Copyright 2004 - 2006 Novell, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "ldtp.h"
#include "remap.h"
#include "ldtp-gui.h"
#include "ldtp-utils.h"
#include "ldtp-logger.h"
#include "localization.h"
#include "ldtp-command.h"

extern gboolean ldtp_debug;
extern gint ldtp_gui_timeout;
extern gint ldtp_obj_timeout;
static char *last_new_context = NULL;
static char *last_existing_context = NULL;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static struct {
      int states_count;
      int states[10];
} state_list[80] = {
      {0, {0}},  // INVALID 0
      {0, {0}},  // ACCEL_LABEL 1
      {5, { SPI_STATE_ENABLED, SPI_STATE_MODAL, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},  // ALERT 2
      {0, {0}},  // ANIMATION 3
      {0, {0}},  // ARROW 4
      {0, {0}},  // CALENDAR 5
      {0, {0}},  //CANVAS 6
      {2, {SPI_STATE_FOCUSABLE, SPI_STATE_VISIBLE}},  // CHECK_BOX 7
      {3, { SPI_STATE_ENABLED, SPI_STATE_SELECTABLE, SPI_STATE_SENSITIVE}},  // CHECK_MENU_ITEM 8

      {0, {0}},  // COLOR_CHOOSER 9
      {0, {0}},  // COLUMN_HEADER 10

      {4,{SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}},  // COMBO_BOX 11

      {0, {0}},  // DATE_EDITOR 12
      {0, {0}},  // DESKTOP_ICON 13
      {4, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},  // DESKTOP_FRAME 14
      {0, {0}},  // DIAL 15

      {4, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}}, // DIALOG 16

      {0, {0}},  // DIRECTORY_PANE 17
      {0, {0}},  // DRAWING_AREA 18
      {0, {0}},  // FILE_CHOOSER 19

      {5, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VERTICAL, SPI_STATE_VISIBLE      }},  // FILLER 20

      {0, {0}},  // FONT_CHOOSER 21 

      {5, { SPI_STATE_ENABLED, SPI_STATE_RESIZABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},  // FRAME 22

      {0, {0}},  // GLASS_PANE 23
      {5, { SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},  // HTML_CONTAINER 24
      {4, { SPI_STATE_FOCUSABLE, SPI_STATE_SELECTABLE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},  // ICON 25
      {0, {0}},  // IMAGE 26
      {0, {0}},  // INTERNAL_FRAME 27
      {4, { SPI_STATE_ENABLED, SPI_STATE_MULTI_LINE, SPI_STATE_SENSITIVE, SPI_STATE_VISIBLE }}, // LABEL 28
      {5, { SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},  // LAYERED_PANE 29

      {6, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_FOCUSABLE, SPI_STATE_SELECTABLE, SPI_STATE_VISIBLE}},  // LIST 30

      {6, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}},  //LIST_ITEM 31

      {1, { SPI_STATE_ENABLED}}, //MENU 32

      {4, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}},//MENU_BAR 33

      {1, { SPI_STATE_ENABLED }}, // MENU_ITEM 34

      {0, {0}},//OPTION_PANE 35

      {6, {SPI_STATE_ENABLED, SPI_STATE_MULTI_LINE, SPI_STATE_SELECTABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}}, // PAGE_TAB 36

      {4, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},//PAGE_TAB_LIST 37

      {3, {SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_VISIBLE }}, // PANEL 38

      {0, {0}}, //PASSWORD_TEXT 39
      {0, {0}}, //POPUP_MENU 40
      {0, {0}}, //PROGRESS_BAR 41

      {4, { SPI_STATE_ENABLED, SPI_STATE_VISIBLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING}}, //PUSH_BUTTON 42

      {4, { SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_SENSITIVE, SPI_STATE_VISIBLE }},//RADIO_BUTTON 43

      {3, { SPI_STATE_ENABLED, SPI_STATE_SELECTABLE, SPI_STATE_SENSITIVE }},//RADIO_MENU_ITEM 44

      {0, {0}},//ROOT_PANE 45
      {0, {0}},//ROW_HEADER 46
      {2, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE }},//SCROLL_BAR 47

      {5, { SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}},//SCROLL_PANE 48

      {3, { SPI_STATE_ENABLED, SPI_STATE_SELECTABLE, SPI_STATE_SENSITIVE }}, //SEPARATOR 49

      {0, {0}},//SLIDER 50

      {6, { SPI_STATE_EDITABLE, SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_SENSITIVE, SPI_STATE_SINGLE_LINE, SPI_STATE_VISIBLE }}, //SPIN_BUTTON 51

      {6, { SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VERTICAL, SPI_STATE_VISIBLE}}, //SPLIT_PANE 52

      {4, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},//STATUS_BAR 53

      {6, {SPI_STATE_VISIBLE, SPI_STATE_SHOWING, SPI_STATE_SENSITIVE, SPI_STATE_MANAGES_DESCENDANTS, SPI_STATE_FOCUSABLE, SPI_STATE_ENABLED     }},//TABLE 54

      {6, { SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_SINGLE_LINE, SPI_STATE_TRANSIENT, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }},   //TABLE_CELL 55

      {6, { SPI_STATE_ENABLED, SPI_STATE_SELECTABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_FOCUSABLE, SPI_STATE_VISIBLE}}, //TABLE_COLUMN_HEADER 56

      {0, {0}},//TABLE_ROW_HEADER 57
      {0, {0}},//TEAROFF_MENU_ITEM 58
      {5, { SPI_STATE_ENABLED, SPI_STATE_RESIZABLE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }}, //TERMINAL 59

      {7, {SPI_STATE_EDITABLE, SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE, SPI_STATE_MULTI_LINE, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE }}, //TEXT 60

      {2, {SPI_STATE_ENABLED, SPI_STATE_FOCUSABLE}},//TOGGLE_BUTTON 61

      {0, {SPI_STATE_ENABLED,SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}},//TOOL_BAR 62
      {0, {0}},//TOOL_TIP 63
      {0, {0}},//TREE 64
      {0, {0}},//TREE_TABLE 65

      {5, { SPI_STATE_ENABLED, SPI_STATE_HORIZONTAL, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_VISIBLE}}, //UNKNOWN 66

      {2, { SPI_STATE_ENABLED, SPI_STATE_SENSITIVE }},//VIEWPORT 67
      {0, {0}},//WINDOW 68
      {0, {0}},//EXTENDED 69
      {0, {0}},//HEADER 70
      {0, {0}},//FOOTER 71
      {0, {0}},//PARAGRAPH 72
      {0, {0}},//RULER 73
      {0, {0}},//APPLICATION 74
      {0, {0}},//AUTOCOMPLETE 75
      {0, {0}},//EDITBAR 76
      {0, {0}},//LAST_DEFINED 77
      {0, {0}},//CALENDAR_VIEW 78
      {0, {0}},//CALENDAR_EVENT 79
};                

static int
push (struct node *head, int value)
{
      struct node *new_node;

      new_node = (struct node *) malloc (sizeof (struct node));
      if (new_node) {
            new_node->child_index = value;
            new_node->next = head->next;
            head->next = new_node;
            return 1;
      }
      else
            return 0;
}

static int
pop (struct node *head)
{
      struct node *temp;
      int index;
      if (head->next) {
            index = head->next->child_index;
            temp = head->next;
            head->next = temp->next;
            g_free (temp);
      }
      else
            index = -1;
      return index;
}

static struct node*
init_stack ()
{
      struct node *head;
      head = g_new0 (struct node, 1);
      if (head) {
            head->child_index = -1;
            head->next = NULL;
            return head;
      }
      else
            return NULL;
}

static struct node*
trace_path_to_parent (GHashTable *context, char *context_name,
                  GHashTable *component, FILE *log_fp,
                  LDTPClientContext *cctxt, LDTPErrorCode *err)
{
      struct node *head;
      char *parent_name;
      char *prop = NULL;

      head = init_stack ();
      if (!head) {
            log_msg (LDTP_LOG_CAUSE, "Unable to initialize stack", log_fp);
            return NULL;
      }
      else {
            char *tmp = NULL;
            prop = get_property (component, "child_index", log_fp);
            if (!prop) {
                  log_msg (LDTP_LOG_CAUSE, "Unable to get_property", log_fp);
                  return NULL;
            }
            push (head, atoi (prop));
            parent_name = get_property (component, "parent", log_fp);
            if (ldtp_debug && parent_name && context_name)
                  g_print ("Parent name: %s - Context name: %s\n", parent_name, context_name);
            while (1) {
                  if (g_utf8_strchr (context_name, -1, ' ') != NULL) {
                        char *str = escape_character (context_name, ' ');
                        tmp = g_strdup_printf ("*%s", str);
                        g_free (str);
                  }
                  else
                        tmp = g_strdup_printf ("*%s", context_name);
                  g_print ("TMP: %s\n", tmp);
                  if (!context_name || !parent_name ||
                      !g_utf8_collate (context_name, parent_name) ||
                      g_pattern_match_simple (context_name, parent_name) ||
                      g_pattern_match_simple (tmp, parent_name)) {
                        g_free (tmp);
                        break;
                  }
                  g_free (tmp);
                  component = (GHashTable *) get_property (context, parent_name, log_fp);
                  if (component) {
                        prop = get_property (component, "child_index", log_fp);
                        if (!prop) {
                              log_msg (LDTP_LOG_CAUSE, "Unable to get_property", log_fp);
                              return NULL;
                        }
                        push (head, atoi (prop));
                        parent_name = get_property (component, "parent", log_fp);
                        if (ldtp_debug && parent_name && context_name)
                              g_print ("InsideWhile: Parent name: %s - Context name: %s - child index: %s\n",
                                     parent_name, context_name, prop);
                  }
                  else
                        break;
            }
      }
      return head;
}

int
object_state_contains (Accessible *object, int control_type, FILE *log_fp)
{
      int i;
      int count;
      char msg [256];
      char *name = NULL;
      SPIBoolean object_state;
      AccessibleStateSet *state;

      name = Accessible_getRoleName (object);
      state = Accessible_getStateSet (object);
      count = state_list [control_type].states_count;

      g_print ("State check count: %d - Control type: %d\n", count, control_type);

      for (i = 0; i < count; i++) {
            object_state = AccessibleStateSet_contains (state,
                                              state_list [control_type].states [i]);
            if (object_state == FALSE) {
                  g_sprintf (msg, "%s required state %d is not enabled", name, i);
                  log_msg (LDTP_LOG_CAUSE, msg, log_fp);
                  SPI_freeString (name);
                  AccessibleStateSet_unref (state);
                  return -1;
            }
      }
      SPI_freeString (name);
      AccessibleStateSet_unref (state);
      return 0;
}

int
wait_till_object_state_contains (Accessible *object, int control_type, FILE *log_fp)
{
      int i;
      int count;
      char msg [256];
      char *name = NULL;
      gboolean flag = FALSE;
      SPIBoolean object_state;
      AccessibleStateSet *state;

      int time_wait = ldtp_obj_timeout;
      time_t start, cur;

      /*
        Copied from LTFX source code
      */
      start = cur = time (NULL);

      state = Accessible_getStateSet (object);
      count = state_list [control_type].states_count;

      g_print ("State check count: %d - Control type: %d\n", count, control_type);

      if (!ldtp_obj_timeout) {
            time_wait = 5; // Max wait for 5 seconds
      }

      while ((difftime (cur, start) < time_wait) && (state != NULL)) {
            ldtp_nsleep (0, 30000);

            cur = time (NULL);
            flag = TRUE;
            for (i = 0; i < count; i++) {
                  object_state = AccessibleStateSet_contains (state,
                                                    state_list [control_type].states [i]);
                  if (object_state == FALSE) {
                        flag = FALSE;
                        break;
                  }
            }
            if (state) {
                  AccessibleStateSet_unref (state);
                  state = NULL;
            }
            if (flag)
                  break;
            state = Accessible_getStateSet (object);
      }
      if (flag) {
            sleep (1);
            return 0;
      }
      name = Accessible_getRoleName (object);
      if (name) {
            g_sprintf (msg, "%s required states are not enabled", name);
            log_msg (LDTP_LOG_CAUSE, msg, log_fp);
            SPI_freeString (name);
      }
      if (state)
            AccessibleStateSet_unref (state);
      return -1;
}

/*
  Get accessible handle of the given application
*/
static Accessible*
get_accessible_app_handle (char *app_name)
{
      long i, num_apps;
      Accessible *desktop;

      if (app_name == NULL)
            return NULL;

      /*
        Get SPI handle of desktop 0
        FIXME: Need to change the hardcoded value of desktop
      */
      desktop = SPI_getDesktop (0);

      if (!desktop)
            return NULL;
      /*
        Get the total count of childs in the desktop
      */
      num_apps = Accessible_getChildCount (desktop);
      /*
        Traverse the list of application handle and if application
        name matches, then return the handle
      */
      for (i = 0; i < num_apps; i++) {
            char *name, *descr;
            char *window_title = NULL;
            Accessible *child;

            child = Accessible_getChildAtIndex (desktop, i);
            if (!child)
                  continue;
            /*
              Application name of child handle
            */
            name = Accessible_getName (child);
            /*
              Description of child handle
            */
            descr = Accessible_getDescription (child);

            /*
              Incase of OO.o due to spaces, string compare gives different result.
              Found because of extra spaces. Now stripped it ;)
            */
            if (name && g_utf8_strchr (name, -1, ' ') != NULL) {
                  gchar *str = NULL;
                  str = escape_character (name, ' ');
                  window_title = str;
            }
            else
                  window_title = g_strdup (name);

            if (name)
                  SPI_freeString (name);
            if (descr)
                  SPI_freeString (descr);
            if (window_title == NULL) {
                  Accessible_unref (child);
                  Accessible_unref (desktop);
                  return NULL;
            }
            g_print ("Accessible application name: %s\n", window_title);
            if (g_ascii_strcasecmp (window_title, app_name) == 0) {
                  /*
                    Application name matched
                  */
                  char *role_name;

                  role_name = Accessible_getRoleName (child);
                  if (ldtp_debug && role_name)
                        g_print ("Application: %s \t- Role: %s\n", window_title, role_name);
                  SPI_freeString (role_name);

                  Accessible_unref (desktop);
                  g_free (window_title);
                  return child;
            }
            g_free (window_title);
            Accessible_unref (child);
      }
      Accessible_unref (desktop);
      return NULL;
}

/*
  Get window list
*/
GHashTable*
get_window_list (void)
{
      long i, num_apps;
      Accessible *desktop;
      GHashTable *table = g_hash_table_new (&g_str_hash, &g_str_equal);

      /*
        Get SPI handle of desktop 0
        FIXME: Need to change the hardcoded value of desktop
      */
      desktop = SPI_getDesktop (0);

      /*
        Get the total count of childs in the desktop
      */
      num_apps = Accessible_getChildCount (desktop);
      /*
        Traverse the list of application handle and if application
        name matches, then return the handle
      */
      for (i = 0; i < num_apps; i++) {
            char *name;
            char *window_title;
            Accessible *child;

            child = Accessible_getChildAtIndex (desktop, i);
            if (!child)
                  continue;
            /*
              Application name of child handle
            */
            name = Accessible_getName (child);
            /*
              Incase of OO.o due to spaces, string compare gives different result.
              Found because of extra spaces. Now stripped it ;)
            */
            if (g_utf8_strchr (name, -1, ' ') != NULL) {
                  window_title = escape_character (name, ' ');
            }
            else
                  window_title = g_strdup (name);

            if (name)
                  SPI_freeString (name);
            if (window_title == NULL) {
                  Accessible_unref (child);
                  Accessible_unref (desktop);
                  continue;
            }
            g_print ("Accessible application name: %s\n", window_title);
            if (table)
                  g_hash_table_insert (table, g_strdup (window_title), NULL);
            Accessible_unref (child);
            g_free (window_title);
      }
      Accessible_unref (desktop);
      return table;
}

/*
 * To get accessible handle of the context (window)
 */
static Accessible*
get_accessible_context_handle (Accessible *app_handle, char *context)
{
      long i, j = 0, k = 1;
      long child_count;
      char *tmp  = NULL;
      char *name = NULL;
      char *child_name  = NULL;
      char *window_name = NULL;
#ifdef ENABLE_LOCALIZATION
      char *temp = NULL;
#endif
      AccessibleRole role;
      Accessible *child = NULL;
      GHashTable *tmpTable = NULL;
      GPatternSpec *context_pattern = NULL;
      GPatternSpec *last_existing_context_pattern = NULL;

      if (!app_handle || !context) {
            g_print ("accessible_context_handle: NULL arguments\n");
            return NULL;
      }

      context_pattern = g_pattern_spec_new (context);
      if (last_existing_context)
            last_existing_context_pattern = g_pattern_spec_new (last_existing_context);

      child_count = Accessible_getChildCount (app_handle);
      name = Accessible_getName (app_handle);
      if (ldtp_debug && name)
            g_print ("Child count: %ld of %s\n", child_count, name);
      SPI_freeString (name);
      if (child_count > 0) {
            tmpTable = g_hash_table_new (&g_str_hash, &g_str_equal);
            for (i = 0; i < child_count; i++) {
                  child = Accessible_getChildAtIndex (app_handle, i);
                  if (!child)
                        continue;
                  //child_name = Accessible_getName (child);
                  /*
                    Application name of child handle
                  */
                  child_name = Accessible_getName (child);
                  role = Accessible_getRole (child);
                  if (child_name) {
                        g_print ("child_name: %s\n", child_name);
                        window_name = get_window_text_in_appmap_format (child_name, role);
                  }
                  if (!window_name) {
                        gchar *tmp = g_strdup_printf ("%ld", j++);
                        if (tmp) {
                              window_name = get_window_text_in_appmap_format (tmp, role);
                              g_free (tmp);
                              tmp = NULL;
                        }
                  }
                  if (window_name && tmpTable) {
                        g_print ("window_name: %s\n", window_name);
                        if (g_hash_table_lookup_extended (tmpTable, window_name, NULL, NULL) == FALSE) {
                              g_hash_table_insert (tmpTable, g_strdup (window_name), NULL);
                              /* Enable for debugging purpose
                                 g_hash_table_foreach (tmpTable, (GHFunc)&print_tmp_table, NULL);
                              */
                        } else {
                              if (child_name)
                                    tmp = g_strdup_printf ("%s%ld", child_name, k++);
                              if (window_name) {
                                    g_free (window_name);
                                    window_name = NULL;
                              }
                              if (tmp) {
                                    window_name = get_window_text_in_appmap_format (tmp, role);
                                    g_free (tmp);
                                    tmp = NULL;
                              }
                              if (window_name && g_hash_table_lookup_extended (tmpTable,
                                                                    window_name,
                                                                    NULL, NULL) == FALSE) {
                                    g_hash_table_insert (tmpTable, g_strdup (window_name), NULL);
                              }
                        }
                  }
                  if (last_new_context && last_existing_context) {
                        g_print ("Last new: **%s** - existing: %s - context: %s - **%s**\n",
                               last_new_context, last_existing_context, context, child_name);
                        if (context_pattern && child_name && last_existing_context_pattern &&
                            (g_pattern_match_string (last_existing_context_pattern, context) ||
                             (window_name && g_pattern_match_string (context_pattern, window_name)))) {
#ifdef ENABLE_LOCALIZATION
                              if ((temp = ldtp_compare_with_locale (last_new_context, child_name))) {
                                    g_free (temp);
                                    g_free (window_name);
                                    SPI_freeString (child_name);
                                    if (last_existing_context_pattern)
                                          g_pattern_spec_free (last_existing_context_pattern);
                                    if (context_pattern)
                                          g_pattern_spec_free (context_pattern);
                                    return child;
                              }
#else
                              char *tmp = escape_character (child_name, ' ');
                              if (g_utf8_collate (last_new_context, child_name) == 0 ||
                                  g_utf8_collate (last_new_context, tmp) == 0 ||
                                  g_pattern_match_simple (last_new_context, child_name)) {
                                    g_free (tmp);
                                    g_free (window_name);
                                    SPI_freeString (child_name);
                                    if (last_existing_context_pattern)
                                          g_pattern_spec_free (last_existing_context_pattern);
                                    if (context_pattern)
                                          g_pattern_spec_free (context_pattern);
                                    return child;
                              }
                              g_free (tmp);
#endif
                        }
                  }
#ifdef ENABLE_LOCALIZATION
                  if (context && child_name &&
                      (temp = ldtp_compare_with_locale (context, child_name))) {
                        g_print ("Context: %s In_Locale: %s Child_name: %s\n", context, temp, child_name);
                        g_free (temp);
                        g_free (window_name);
                        SPI_freeString (child_name);
                        if (last_existing_context_pattern)
                              g_pattern_spec_free (last_existing_context_pattern);
                        if (context_pattern)
                              g_pattern_spec_free (context_pattern);
                        return child;
                  }
#else
                  if (ldtp_debug && context && child_name)
                        g_print ("Context: %s Child_name: %s\n", context, child_name);
                  if (ldtp_debug && window_name)
                        g_print ("Window name: %s\n", window_name);
                  if (context_pattern && child_name &&
                      (g_pattern_match_string (context_pattern, child_name) ||
                       (window_name && g_pattern_match_string (context_pattern, window_name)))) {
                        g_free (window_name);
                        g_print ("Matched - Context: %s Child_name: %s\n", context, child_name);
                        SPI_freeString (child_name);
                        if (last_existing_context_pattern)
                              g_pattern_spec_free (last_existing_context_pattern);
                        if (context_pattern)
                              g_pattern_spec_free (context_pattern);
                        return child;
                  }
#endif
                  else {
                        g_free (window_name);
                        window_name = NULL;
                        SPI_freeString (child_name);
                        Accessible_unref (child);
                  }
            }
      }
      if (last_existing_context_pattern)
            g_pattern_spec_free (last_existing_context_pattern);
      if (context_pattern)
            g_pattern_spec_free (context_pattern);
      return NULL;
}

/*
  Get accessible handle of the given object
*/
static Accessible*
get_accessible_component_handle (struct node *head, Accessible *context, FILE *log_fp)
{
      long i;
      char *role;
      Accessible *child, *parent;

      if (!head) {
            g_print ("Head pointer is NULL\n");
            return NULL;
      }
      i = pop (head);
      parent = context;
      while (i != -1) {
            child = Accessible_getChildAtIndex (parent, i);
            if (!child) {
                  char msg [256];
                  char *child_name = NULL;
                  char *parent_name = NULL;
                  child_name = Accessible_getName (context);
                  parent_name = Accessible_getName (parent);
                  if (ldtp_debug && parent_name && child_name)
                        g_print ("Parent: %s - Child: %s - %ld\n", parent_name, child_name, i);
                  if (parent != context)
                        Accessible_unref (parent);
                  g_sprintf (msg, "Unable to find child index as available in appmap");
                  g_print ("%s\n", msg);
                  log_msg (LDTP_LOG_CAUSE, msg, log_fp);
                  SPI_freeString (child_name);
                  SPI_freeString (parent_name);
                  return NULL;
            }
            role = Accessible_getRoleName (child);
            if (role) {
                  char *name = Accessible_getName (child);
                  if (ldtp_debug && name)
                        g_print ("Role: %s - %s\n", role, name);
                  SPI_freeString (role);
                  SPI_freeString (name);
            }
            if (parent != context)
                  Accessible_unref (parent);
            parent = child;
            i = pop (head);
      }
      return parent;
}

char*
get_relation_name (Accessible *object, long *len)
{
      long i = 0, j = 0, k = 0;
      int max_accessible = 0;
      char *label_by = NULL;
      AccessibleRelation **relation = NULL;

      relation = Accessible_getRelationSet (object);
      if (!relation) {
            return NULL;
      }
      max_accessible = AccessibleRelation_getNTargets (*relation);
      if (max_accessible <= 0) {
            for (k = 0; relation[k] != NULL; k++)
                  AccessibleRelation_unref (relation[k]);
            g_free (relation);
            return NULL;
      }
      for (i = 0; relation[i] != NULL; i++) {
            for (j = 0; j < AccessibleRelation_getNTargets (relation[i]); j++) {
                  AccessibleRelationType relation_type;
                  relation_type = AccessibleRelation_getRelationType (relation[i]);
                  if (relation_type == SPI_RELATION_LABELED_BY ||
                      relation_type == SPI_RELATION_CONTROLLED_BY ||
                      relation_type == SPI_RELATION_LABEL_FOR) {
                        char *name = NULL;
                        Accessible *tmp_obj;
                        tmp_obj = AccessibleRelation_getTarget (relation[i], i);
                        name = Accessible_getName (tmp_obj);
                        if (name == NULL) {
                              Accessible_unref (tmp_obj);
                              for (k = 0; relation[k] != NULL; k++)
                                    AccessibleRelation_unref (relation[k]);
                              g_free (relation);
                              return NULL;
                        }
                        if (g_ascii_strcasecmp (name, "") == 0) {
                              SPI_freeString (name);
                              Accessible_unref (tmp_obj);
                              for (k = 0; relation[k] != NULL; k++)
                                    AccessibleRelation_unref (relation[k]);
                              g_free (relation);
                              return NULL;
                        }
                        g_print ("Relation name: %s\n", name);
                        label_by = g_strdup (name);
                        SPI_freeString (name);
                        if (Accessible_isText (tmp_obj) && len != NULL) {
                              AccessibleText *text = NULL;
                              text = Accessible_getText (tmp_obj);
                              *len = AccessibleText_getCharacterCount (text);
                              Accessible_unref (text);
                        }
                        Accessible_unref (tmp_obj);
                        for (k = 0; relation[k] != NULL; k++)
                              AccessibleRelation_unref (relation[k]);
                        g_free (relation);
                        return label_by;
                  }
            } // for j
            AccessibleRelation_unref (relation[i]);
      } // for i
      g_free (relation);
      return NULL;
} // get_relation_name

static gboolean
is_object_matching (Accessible *object, GHashTable *comp_attributes, FILE *log_fp)
{
      char *accessible_label;
      char *hash_label;
#ifdef ENABLE_LOCALIZATION
      gchar *value;
#else
      gint value;
#endif
      /*
       * NOTE: Checking if the obtained object is the required one 
       * with respect to label/label_by only
       */
      hash_label = get_property (comp_attributes, "label", log_fp);
      if (hash_label) {
            char *role;
            accessible_label = Accessible_getName (object);
            role = Accessible_getRoleName (object);
            if (role) {
                  g_print ("Role: %s\n", role);
                  SPI_freeString (role);
            }
            g_print ("Label: %s - %s\n", hash_label, accessible_label);
#ifdef ENABLE_LOCALIZATION
            value = ldtp_compare_with_locale (hash_label, accessible_label);
            if (value)
#else
                  if (g_utf8_strchr (hash_label, -1, '_') != NULL) {
                        gchar *str = NULL;
                        str = escape_character (hash_label, '_');
                        g_print ("Before: %s - After: %s\n", hash_label, str);
                        value = g_utf8_collate (str, accessible_label);
                        g_free (str);
                  }
                  else
                        value = g_utf8_collate (hash_label, accessible_label);
            if (value == 0)
#endif
                  {
                        SPI_freeString (accessible_label);
                        g_print ("Object matches\n");
#ifdef ENABLE_LOCALIZATION
                        g_free (value);
#endif
                        return TRUE;
                  }
            else {
                  SPI_freeString (accessible_label);
                  return FALSE;
            }
      }
      else {
            hash_label = get_property (comp_attributes, "label_by", log_fp);
            if (hash_label) {
                  long len = -1;
                  accessible_label = get_relation_name (object, &len);
#ifdef ENABLE_LOCALIZATION
                  value = ldtp_compare_with_locale (hash_label, accessible_label);
                  if (value)
#else
                        if (g_utf8_strchr (hash_label, -1, '_') != NULL) {
                              gchar *str = NULL;
                              str = escape_character (hash_label, '_');
                              g_print ("Before: %s - After: %s\n", hash_label, str);
                              value = g_utf8_collate (str, accessible_label);
                              g_free (str);
                        }
                        else
                              value = g_utf8_collate (hash_label, accessible_label);
                  if (value == 0)
#endif
                        {
                              g_free (accessible_label);
                              g_print ("Object matches\n");
#ifdef ENABLE_LOCALIZATION
                              g_free (value);
#endif
                              return TRUE;
                        }
                  else {
                        g_free (accessible_label);
                        return FALSE;
                  }
            }
      }
      return TRUE;
}

static gboolean
does_window_exist (char *context, char *name, char *window_name, GPatternSpec *pattern, GPatternSpec *tmp_pattern)
{
      if (name && window_name && context &&
          (g_utf8_collate (context, name) == 0 ||
           (pattern && g_pattern_match_string (pattern, name)) ||
           g_utf8_collate (context, window_name) == 0 ||
           (pattern && g_pattern_match_string (pattern, window_name)) ||
           (tmp_pattern && g_pattern_match_string (tmp_pattern, window_name)))) {
            g_print ("Window name matched\n");
            return TRUE;
      }
      return FALSE;
}

static gboolean
remove_tmp_entries (gpointer key, gpointer value, gpointer user_data)
{
      if (key) {
            g_free (key);
            key = NULL;
      }
      return TRUE;
}

void
print_tmp_table (char *key, char *value, char *userdata)
{
      if (key)
            g_print (":%s:\n", key);
}

static Accessible*
get_child_window_handle (Accessible *app_handle, char *context, char **window_name, gboolean *flag)
{
      long i, j = 0, k = 1;
      char *tmp  = NULL;
      char *name = NULL;
      long child_count = 0;
      Accessible *child = NULL;
      AccessibleRole role;
      GPatternSpec *pattern = NULL;
      GPatternSpec *tmp_pattern = NULL;
      GHashTable *tmpTable = NULL;

      /*
        FIXME: If app_handle is NULL, then get the desktop handle and from there
        search for window handle instead of directly returning from here
      */
      if (!app_handle || !context)
            return NULL;

      *flag = FALSE;

      child_count = Accessible_getChildCount (app_handle);
      tmp = g_strdup_printf ("*%s", context);
      if (context)
            pattern = g_pattern_spec_new (context);
      if (tmp) {
            tmp_pattern = g_pattern_spec_new (tmp);
            g_free (tmp);
            tmp = NULL;
      }

      *window_name = NULL;
      tmpTable = g_hash_table_new (&g_str_hash, &g_str_equal);
      for (i = 0; i < child_count; i++) {
            child = Accessible_getChildAtIndex (app_handle, i);
            if (!child)
                  continue;

            /*
              Application name of child handle
            */
            name = Accessible_getName (child);
            role = Accessible_getRole (child);
            if (name) {
                  g_print ("child_name: %s\n", name);
                  *window_name = get_window_text_in_appmap_format (name, role);
            }
            if (!*window_name) {
                  gchar *tmp = g_strdup_printf ("%ld", j++);
                  if (tmp) {
                        *window_name = get_window_text_in_appmap_format (tmp, role);
                        g_free (tmp);
                        tmp = NULL;
                  }
            }
            if (*window_name && tmpTable) {
                  g_print ("window_name: %s\n", *window_name);
                  if (g_hash_table_lookup_extended (tmpTable, *window_name, NULL, NULL) == FALSE) {
                        g_hash_table_insert (tmpTable, g_strdup (*window_name), NULL);
                        /* Enable for debugging purpose
                          g_hash_table_foreach (tmpTable, (GHFunc)&print_tmp_table, NULL);
                        */
                  } else {
                        if (name)
                              tmp = g_strdup_printf ("%s%ld", name, k++);
                        if (*window_name) {
                              g_free (*window_name);
                              *window_name = NULL;
                        }
                        if (tmp) {
                              *window_name = get_window_text_in_appmap_format (tmp, role);
                              g_free (tmp);
                              tmp = NULL;
                        }
                        if (*window_name && g_hash_table_lookup_extended (tmpTable,
                                                              *window_name,
                                                              NULL, NULL) == FALSE) {
                              g_hash_table_insert (tmpTable, g_strdup (*window_name), NULL);
                              *flag = TRUE;
                        }
                  }
            }

            if (ldtp_debug && context && name && *window_name)
                  g_print ("Search window name: %s - %s - %s\n", context, name, *window_name);
            if (does_window_exist (context, name, *window_name, pattern, tmp_pattern)) {
                  SPI_freeString (name);
                  if (pattern)
                        g_pattern_spec_free (pattern);
                  if (tmp_pattern)
                        g_pattern_spec_free (tmp_pattern);
                  g_hash_table_foreach_remove (tmpTable, (GHRFunc)&remove_tmp_entries, NULL);
                  g_hash_table_destroy (tmpTable);
                  return child;
            }
            SPI_freeString (name);
            Accessible_unref (child);
      }
      if (pattern)
            g_pattern_spec_free (pattern);
      if (tmp_pattern)
            g_pattern_spec_free (tmp_pattern);
      g_hash_table_foreach_remove (tmpTable, (GHRFunc)&remove_tmp_entries, NULL);
      g_hash_table_destroy (tmpTable);
      return NULL;
}

static Accessible*
get_window_handle (Accessible *app_handle, char *context, char **window_name, gboolean *flag)
{
      char *name = NULL;
      long i, num_apps;
      Accessible *child = NULL;
      Accessible *desktop = NULL;
      Accessible *window_handle = NULL;
      if (app_handle) {
            window_handle = get_child_window_handle (app_handle, context, window_name, flag);
            if (window_handle)
                  return window_handle;
      }

      /*
        Get SPI handle of desktop 0
        FIXME: Need to change the hardcoded value of desktop
      */
      desktop = SPI_getDesktop (0);

      /*
        Get the total count of childs in the desktop
      */
      num_apps = Accessible_getChildCount (desktop);
      /*
        Traverse the list of application handle and if application
        name matches, then return the handle
      */
      for (i = 0; i < num_apps; i++) {
            child = Accessible_getChildAtIndex (desktop, i);
            if (!child)
                  continue;
            /*
              Application name of child handle
            */
            name = Accessible_getName (child);
            if (!name) {
                  Accessible_unref (child);
                  continue;
            }
            /*
              Incase of OO.o due to spaces, string compare gives different result.
              Found because of extra spaces. Now stripped it ;)
            */
            if (strchr (name, ' '))
                  g_strstrip (name);

            g_print ("Accessible application name: %s\n", name);
            window_handle = get_child_window_handle (child, context, window_name, flag);
            if (window_handle) {
                  SPI_freeString (name);
                  Accessible_unref (child);
                  Accessible_unref (desktop);
                  return window_handle;
            }
            SPI_freeString (name);
            Accessible_unref (child);
      }
      Accessible_unref (desktop);
      return NULL;
}

void
update_cur_window_appmap_handle (LDTPClientContext* cctxt,
                         LDTPErrorCode* err)
{
      char *context = NULL;
      char *window_name = NULL;
      char *parent_name = NULL;
      gboolean flag = FALSE;
      Accessible *child = NULL;
      Accessible *parent = NULL;
      GHashTable *new_hashtable = NULL;

      context = (char *) cctxt->req->context;
      if (!context) {
            *err = LDTP_ERROR_ARGUMENT_NULL;
            g_print ("%s", ldtp_error_get_message (*err));
            return;
      }
      child = get_window_handle (cctxt->app_handle, context, &(cctxt->window_name), &flag);
      if (!child) {
            g_print ("%s - %d - Window %s not open\n", __FILE__, __LINE__, context);
            *err = LDTP_ERROR_WIN_NOT_OPEN;
            return;
      }

      /* Unable to find using the new context based on the dynamic context generated */
      window_name = cctxt->window_name;
      parent = Accessible_getParent (child);
      if (flag == FALSE && parent) {
            AccessibleRole role;
            parent_name = Accessible_getName (parent);
            if (ldtp_debug && parent_name)
                  g_print ("Parent name: %s\n", parent_name);
            role = Accessible_getRole (parent) == SPI_ROLE_APPLICATION ? SPI_ROLE_APPLICATION : Accessible_getRole (child);
            window_name = get_window_text_in_appmap_format (parent_name, role);
            if (ldtp_debug && window_name && parent_name)
                  g_print ("Window name - Stripped: %s - %s\n", window_name, parent_name);
            SPI_freeString (parent_name);
      }
      else
            g_print ("Unable to get parent\n");
      if (parent)
            Accessible_unref (parent);

      pthread_mutex_lock (&mutex);
      if (ldtp_debug && cctxt->window_name)
            g_print ("%s %d %s\n", __FILE__, __LINE__, cctxt->window_name);
      new_hashtable = do_remap (child, window_name, NULL, NULL, cctxt->locale_set, flag, FALSE);
      pthread_mutex_unlock (&mutex);

      if (flag == FALSE && window_name) {
            g_free (window_name);
            window_name = NULL;
      }

      if (new_hashtable) {
            char *name = NULL;

            if (!cctxt->app_map) {
                  g_print ("Appmap hashtable not initalized\n");
                  cctxt->app_map = g_hash_table_new (&g_str_hash, &g_str_equal);
            }
            name = Accessible_getName (child);

            if (name && window_name) {
                  g_print ("Window name: %s - Stripped: %s\n", window_name, name);
            }
            SPI_freeString (name);
            Accessible_unref (child);
            if (cctxt->window_name) {
                  g_print ("cctxt->window_name: %s\n", cctxt->window_name);
                  pthread_mutex_lock (&mutex);
                  g_hash_table_replace (cctxt->app_map, g_strdup (cctxt->window_name), new_hashtable);
                  pthread_mutex_unlock (&mutex);
                  if (window_name && window_name != cctxt->window_name) {
                        g_free (window_name);
                        window_name = NULL;
                  }
            }
            else {
                  *err = LDTP_ERROR_UNABLE_TO_UPDATE_APPMAP;
                  g_print ("DEBUG: Window name NULL\n");
                  g_hash_table_destroy (new_hashtable);
                  return;
            }
      }
      else {
            Accessible_unref (child);
            g_print ("DEBUG: New hash table NULL\n");
            *err = LDTP_ERROR_UNABLE_TO_UPDATE_APPMAP;
            return;
      }
      if (ldtp_debug) {
            /*
              Enable it for debugging purpose
            */
            g_hash_table_foreach (cctxt->app_map, (GHFunc)&print_context, NULL);
      }
      *err = LDTP_ERROR_SUCCESS;
}

void
update_cur_context_appmap_handle (LDTPClientContext *cctxt,
                          LDTPErrorCode *err)
{
      char *parent_name  = NULL;
      GHashTable *context_table   = NULL;
      GHashTable *component_table = NULL;
      LDTPGuiHandle *gui_handle   = NULL;

      if (!cctxt->req->context || !cctxt->req->component) {
            *err = LDTP_ERROR_ARGUMENT_NULL;
            g_print ("%s", ldtp_error_get_message (*err));
            return;
      }
      if (cctxt->app_map == NULL) {
            *err =  (LDTP_ERROR_APPMAP_NOT_INITIALIZED);
            g_print ("%s - %d - %s\n", __FILE__, __LINE__, ldtp_error_get_message (*err));
            return;
      }
      context_table = get_object_def (cctxt->app_map, cctxt->req->context, cctxt->log_fp, TRUE);
      if (!context_table) {
            *err = LDTP_ERROR_WIN_NAME_NOT_FOUND_IN_APPMAP;
            g_print ("%s", ldtp_error_get_message (*err));
            return;
      }
      component_table = get_object_def (context_table, cctxt->req->component, cctxt->log_fp, FALSE);
      if (!component_table) {
            *err = LDTP_ERROR_OBJ_NAME_NOT_FOUND_IN_APPMAP;
            g_print ("%s", ldtp_error_get_message (*err));
            return;
      }
      parent_name = get_property (component_table, "parent", cctxt->log_fp);

      if (ldtp_debug && cctxt->window_name)
            g_print ("%s %d %s\n", __FILE__, __LINE__, cctxt->window_name);

      gui_handle = ldtp_gui_get_gui_handle (cctxt, err);
      if (*err != LDTP_ERROR_SUCCESS) {
            g_print ("Unable to get handle: %s %d\n", __FILE__, __LINE__);
            return;
      }
      pthread_mutex_lock (&mutex);
      g_hash_table_foreach_remove (context_table, remove_remapped_entry, NULL);
      do_remap (gui_handle->handle, parent_name, context_table, NULL, cctxt->locale_set, FALSE, TRUE);
      pthread_mutex_unlock (&mutex);
      Accessible_unref (gui_handle->handle);
      *err = LDTP_ERROR_SUCCESS;
}

/*
  Get gui handle based on context and compoment
*/
LDTPGuiHandle*
ldtp_gui_get_gui_handle (LDTPClientContext* cctxt,
                   LDTPErrorCode* err)
{
      char msg [256]    = "";
      gchar *context    = NULL;
      char *app_name    = NULL;
      char *component   = NULL;
      char *window_prop = NULL;
      struct node *head;
      gboolean flag = FALSE;
      gboolean updated_appmap = FALSE;
      AccessibleRole class;
      Accessible *component_handle  = NULL;
      Accessible *context_handle = NULL;
      LDTPGuiHandle* ctxt_handle = NULL;

      GHashTable *cur_window;
      GHashTable *cur_component;

      if (!cctxt || !cctxt->req->context) {
            /* FIXME: Error handling */
            *err = LDTP_ERROR_ARGUMENT_NULL;
            log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (*err), cctxt->log_fp);
            return NULL;
      }

      context = (char *) cctxt->req->context;
      component = (char *) cctxt->req->component;
      /*
        For guiexist, waittillguiexist functions, both context and component are same
      */
      if (!cctxt->req->component)
            component = context;

      if (!cctxt->app_map) {
            if (cctxt->window_name) {
                  g_free (cctxt->window_name);
                  cctxt->window_name = NULL;
            }
            update_cur_window_appmap_handle (cctxt, err);
            updated_appmap = TRUE;
            if (*err != LDTP_ERROR_SUCCESS) {
                  g_sprintf (msg, "Unable to update context: %s in appmap", context);
                  goto error;
            }
      }

      cur_window = get_object_def (cctxt->app_map, context, cctxt->log_fp, TRUE);
      if (context)
            g_print ("context: %s - cur_window: %d\n", context, cur_window == NULL ? 0 : 1);
      /*
        If window info, not available in appmap hash table, try to remap it
        iff, the window exist
      */
      if (!cur_window) {
            if (cctxt->window_name) {
                  g_free (cctxt->window_name);
                  cctxt->window_name = NULL;
            }
            update_cur_window_appmap_handle (cctxt, err);
            updated_appmap = TRUE;
            if (*err != LDTP_ERROR_SUCCESS) {
                  g_sprintf (msg, "Unable to update context: %s in appmap", context);
                  goto error;
            }
            cur_window = get_object_def (cctxt->app_map, context, cctxt->log_fp, TRUE);
            if (!cur_window) {
                  Accessible *child;

                  if (cctxt->window_name) {
                        g_free (cctxt->window_name);
                        cctxt->window_name = NULL;
                  }
                  /*
                    If context is given without window type, then use dynamically created window name
                    Example: if context is Replace, instead of dlgReplace (in gedit app, replace dialog)
                    then we will try to search using our dynamic context dlgReplace
                  */
                  child = get_window_handle (cctxt->app_handle, context, &(cctxt->window_name), &flag);
                  if (!child) {
                        g_print ("%s - %d - Window %s not open\n", __FILE__, __LINE__, context);
                        g_sprintf (msg, "Window %s not open", context);
                        *err = LDTP_ERROR_WIN_NOT_OPEN;
                        goto error;
                  }
                  /*
                  name = Accessible_getName (child);
                  window_name = get_window_text_in_appmap_format (name, Accessible_getRole (child));
                  */
                  Accessible_unref (child);
                  if (cctxt->window_name) {
                        gboolean tmpflag = FALSE;
                        if (cctxt->req->context == component)
                              tmpflag = TRUE;
                        if (cctxt->req->context)
                              g_free (cctxt->req->context);
                        cctxt->req->context = g_strdup (cctxt->window_name);
                        context = (char *) cctxt->req->context;
                        /* 
                           In case of waittillguiexist and waittillguinotexist,
                           both context and component members of the ClientContext
                           structure points to same string and they don't need 
                           class_id.
                        */
                        if (tmpflag)
                              component = context;
                        if (context)
                              cur_window = get_object_def (cctxt->app_map, context, cctxt->log_fp, TRUE);
                        //g_free (window_name);
                        //window_name = NULL;
                  }
            }
            if (!cur_window) {
                  g_sprintf (msg, "Unable to find window name: %s in appmap", context);
                  *err = LDTP_ERROR_WIN_NAME_NOT_FOUND_IN_APPMAP;
                  goto error;
            }
      }
      cur_component = get_object_def (cur_window, context, cctxt->log_fp, TRUE);
      if (!cur_component) {
            g_sprintf (msg, "%s - %d - Unable to find context name: %s in appmap", __FILE__, __LINE__, context);
            *err = LDTP_ERROR_WIN_NAME_NOT_FOUND_IN_APPMAP;
            goto error;
      }
      app_name = get_property (cur_component, "parent", cctxt->log_fp);
      if (app_name)
            g_print ("app_name: %s\n", app_name);
      window_prop = get_property (cur_component, "label", cctxt->log_fp);
      if (window_prop)
            g_print ("window_prop: %s\n", window_prop);

      if (context && component &&
          g_utf8_collate ((const gchar *)context, (const gchar *)component)) {
            cur_component = get_object_def (cur_window, component, cctxt->log_fp, FALSE);

            if (!cur_component) {
                  int time_wait = ldtp_obj_timeout;
                  time_t start, cur;
                  gboolean flag = FALSE;

                  g_print ("Unable to get component\n");
                  if (cctxt->window_name) {
                        g_free (cctxt->window_name);
                        cctxt->window_name = NULL;
                  }
                  /*
                    Copied from LTFX source code
                  */
                  start = cur = time (NULL);

                  if (!ldtp_obj_timeout) {
                        time_wait = 5; // Max wait for 5 seconds
                  }

                  while (difftime (cur, start) < time_wait) {
                        update_cur_window_appmap_handle (cctxt, err);
                        updated_appmap = TRUE;
                        cur_window = get_object_def (cctxt->app_map, context, cctxt->log_fp, TRUE);
                        cur_component = get_object_def (cur_window, component, cctxt->log_fp, FALSE);

                        if (!cur_component) {
                              ldtp_nsleep (0, 30000);

                              cur = time (NULL);
                        } else {
                              flag = TRUE;
                              break;
                        }
                  }
                  if (flag == FALSE) {
                        g_sprintf (msg, "%s - %d - Unable to find object name: %s in appmap", __FILE__, __LINE__, component);
                        *err = LDTP_ERROR_OBJ_NAME_NOT_FOUND_IN_APPMAP;
                        goto error;
                  }
            }
      }
      /*
        Update the ClientContext structure with application 
        handle, iff, it wasn't already updated.
        FIXME: We should think about scenarios that involve
        multiple-app-maps and multiple-application-handles.
      */
      if (app_name && cctxt->window_name)
            g_print ("Appname: %s - %s\n", app_name, cctxt->window_name);

      if (cctxt->app_handle) {
            Accessible_unref (cctxt->app_handle);
            cctxt->app_handle = NULL;
      }

      cctxt->app_handle = get_accessible_app_handle (app_name);
      if (!cctxt->app_handle) {
            g_sprintf (msg, "Application: %s not running", app_name);
            *err = LDTP_ERROR_APP_NOT_RUNNING;
            goto error;
      }

      if (updated_appmap == FALSE) {
            if (cctxt->window_name) {
                  g_free (cctxt->window_name);
                  cctxt->window_name = NULL;
            }
            if (window_prop)
                  cctxt->window_name = g_strdup (window_prop);
      }
      context_handle = get_accessible_context_handle (cctxt->app_handle, window_prop);
      if (!context_handle) {
            context_handle = get_accessible_context_handle (cctxt->app_handle, context);
      }
      if (!context_handle) {
            if (g_utf8_collate (context, component)) {
                  g_sprintf (msg, "Window: %s not opened", context);
                  *err = LDTP_ERROR_WIN_NOT_OPEN;
            }
            else
                  *err = LDTP_ERROR_UNABLE_TO_GET_CONTEXT_HANDLE;
            goto error;
      }

      ctxt_handle = g_new0 (LDTPGuiHandle, 1);
      ctxt_handle->handle = context_handle;

      g_print ("Window: %s - Object: %s\n", context, component);

      /* 
            In case of waittillguiexist and waittillguinotexist,
            both context and component members of the ClientContext 
            structure points to same string and they don't need 
            class_id.
      */
      if (context && component &&
          !g_utf8_collate ((const gchar *)context, (const gchar *)component))
            return ctxt_handle;

      head = trace_path_to_parent (cur_window, context, cur_component, cctxt->log_fp, cctxt, err);
      component_handle = get_accessible_component_handle (head, context_handle, cctxt->log_fp);
      Accessible_unref (context_handle);
      ctxt_handle->handle = NULL;
      g_free (head);

      if (!component_handle || Accessible_getRole (component_handle) == SPI_ROLE_UNKNOWN) {
            int time_wait = ldtp_obj_timeout;
            time_t start, cur;
            gboolean flag = FALSE;

            if (component_handle) {
                  Accessible_unref (component_handle);
                  component_handle = NULL;
            }
            /*
              Copied from LTFX source code
            */
            start = cur = time (NULL);

            if (!ldtp_obj_timeout) {
                  time_wait = 5; // Max wait for 5 seconds
            }

            while (difftime (cur, start) < time_wait) {
                  /*
                    To avoid runtime remap function to be called, let us call remap here
                  */
                  g_print ("Updating appmap\n");
                  if (cctxt->window_name) {
                        g_free (cctxt->window_name);
                        cctxt->window_name = NULL;
                  }
                  update_cur_window_appmap_handle (cctxt, err);
                  updated_appmap = TRUE;
                  context_handle = get_accessible_context_handle (cctxt->app_handle, window_prop);
                  if (!context_handle) {
                        context_handle = get_accessible_context_handle (cctxt->app_handle, context);
                  }
                  if (context_handle) {
                        cur_window = get_object_def (cctxt->app_map, context, cctxt->log_fp, TRUE);
                        cur_component = get_object_def (cur_window, component, cctxt->log_fp, FALSE);
                        head = trace_path_to_parent (cur_window, context, cur_component, cctxt->log_fp, cctxt, err);
                        component_handle = get_accessible_component_handle (head, context_handle, cctxt->log_fp);
                        Accessible_unref (context_handle);
                        g_free (head);
                  }
                  if (!component_handle || Accessible_getRole (component_handle) == SPI_ROLE_UNKNOWN) {
                        if (component_handle) {
                              Accessible_unref (component_handle);
                              component_handle = NULL;
                        }
                        ldtp_nsleep (0, 30000);

                        cur = time (NULL);
                  } else {
                        flag = TRUE;
                        break;
                  }
            }
      }
      if (!component_handle) {
            if (ldtp_debug && component) {
                  g_sprintf (msg, "Unable to get object handle %s", component);
                  g_print ("%s\n", msg);
            }
            *err = LDTP_ERROR_GET_OBJ_HANDLE_FAILED;
            goto error;
      }

      if (!is_object_matching (component_handle, cur_component, cctxt->log_fp)) {
            char *name = NULL;
            name = Accessible_getName (component_handle);
            if (name) {
                  g_sprintf (msg, "Object information: %s does not match with appmap entry", name);
                  g_print ("%s\n", msg);
                  SPI_freeString (name);
            }
            Accessible_unref (component_handle);
            *err = LDTP_ERROR_OBJ_INFO_MISMATCH;
            goto error;
      }
      ctxt_handle->class_id = 0;
      class = Accessible_getRole (component_handle);

      if (class == SPI_ROLE_EXTENDED) {
            char *name;
            name = Accessible_getRoleName (component_handle);
            if (g_ascii_strcasecmp (name, "calendar view") == 0)
                  ctxt_handle->class_id = CALENDAR_VIEW;
            else if (g_ascii_strcasecmp (name, "calendar event") == 0)
                  ctxt_handle->class_id = CALENDAR_EVENT;
            SPI_freeString (name);
      }
      else
            ctxt_handle->class_id = class;

      g_print ("Class id: %d\n", ctxt_handle->class_id);
  
      ctxt_handle->handle = component_handle;
      *err = LDTP_ERROR_SUCCESS;
      return ctxt_handle;

 error:
      g_free (ctxt_handle);
      if (g_ascii_strcasecmp (msg, "") != 0) {
            g_print ("%s\n", msg);
            log_msg (LDTP_LOG_ERROR, msg, cctxt->log_fp);
      }
      return NULL;
}

static Accessible*
get_object_handle (Accessible *accessible, AccessibleRole role)
{
      long i;
      long count;
      Accessible *child, *parent;
      
      count = Accessible_getChildCount (accessible);
      for (i = 0; i < count; i++) {
            child = Accessible_getChildAtIndex (accessible, i);

            if (!child)
                  continue;   

            parent = child;
            if (Accessible_getRole (child) == role)
                  return child;
            else {
                  Accessible *tmp_parent = child;
                  child = get_object_handle (tmp_parent, role);
                  /*
                    Unref local parent
                  */
                  if (child == NULL && parent == tmp_parent)
                        parent = NULL;
                  if (tmp_parent) {
                        Accessible_unref (tmp_parent);
                        tmp_parent = NULL;
                  }
                  if (child != NULL)
                        return child;
            }
            if (parent) {
                  Accessible_unref (parent);
                  parent = NULL;
            }
      }
      return NULL;
}

Accessible *
get_list_handle (Accessible *accessible)
{
      return get_object_handle (accessible, SPI_ROLE_LIST);
}

Accessible *
get_text_handle (Accessible *accessible)
{
      return get_object_handle (accessible, SPI_ROLE_TEXT);
}

Accessible *
get_menu_handle (Accessible *accessible)
{
      return get_object_handle (accessible, SPI_ROLE_MENU);
}

int 
get_object_type (Accessible *accessible)
{
      int object_type = 0;
      AccessibleRole role;
      role = Accessible_getRole (accessible);

      if (role == SPI_ROLE_LIST)
            object_type = SPI_ROLE_LIST;
      else if (role == SPI_ROLE_MENU)
            object_type = SPI_ROLE_MENU;
      else if (role == SPI_ROLE_TEXT)
            object_type = SPI_ROLE_TEXT;
      else if (role == SPI_ROLE_TOGGLE_BUTTON)
            object_type = SPI_ROLE_TOGGLE_BUTTON;
      else if (role == SPI_ROLE_TABLE_CELL)
            object_type = SPI_ROLE_TABLE_CELL;
      else if (role == SPI_ROLE_EXTENDED) {
            char *role_name;
            role_name = Accessible_getRoleName (accessible);
            if (g_ascii_strcasecmp (role_name, "calendar event") == 0)
                  object_type = CALENDAR_EVENT;
            SPI_freeString (role_name);
      }
      return object_type;
}

int 
get_child_object_type (Accessible *accessible)
{
      int i;
      int num_child;
      int child_type;
      AccessibleRole role;
      Accessible *child;
                                                                                
      num_child = Accessible_getChildCount (accessible);
      for (i = 0; i < num_child; i++) {
            child = Accessible_getChildAtIndex (accessible, i);
            if (!child)
                  continue;
                                                                                
            role = Accessible_getRole (child);
            if (role == SPI_ROLE_MENU) {
                  Accessible_unref (child);
                  return SPI_ROLE_MENU;
            }
            else if (role == SPI_ROLE_LIST) {
                  Accessible_unref (child);
                  return SPI_ROLE_LIST;
            }
                                                                                
            child_type = get_child_object_type (child);
            if (child_type != 0) {
                  Accessible_unref (child);
                  return child_type;
            }
            Accessible_unref (child);
      }
      return 0;
}

int 
set_new_context (char *existing_context, char *new_context)
{
      if (last_new_context) {
            g_free (last_new_context);
            last_new_context = NULL;
      }
      if (last_existing_context) {
            g_free (last_existing_context);
            last_existing_context = NULL;
      }
      last_new_context = g_strdup (new_context);
      last_existing_context = g_strdup (existing_context);
      return 1;
}

int 
release_last_context ()
{
      if (last_new_context) {
            g_free (last_new_context);
            last_new_context = NULL;
      }
      if (last_existing_context) {
            g_free (last_existing_context);
            last_existing_context = NULL;
      }
      return 1;
}

void
ldtp_gui_free_gui_handle (LDTPGuiHandle *ui_handle)
{
      if (!ui_handle)
            return;
      if (ui_handle->handle) {
            Accessible_unref (ui_handle->handle);
            ui_handle->handle = NULL;
      }
      g_free (ui_handle);
      ui_handle = NULL;
}

void
ldtp_gui_wait_till_gui_exist (LDTPClientContext* cctxt, LDTPErrorCode* err)
{
      int time_wait = ldtp_gui_timeout;
      time_t start, cur;
      LDTPGuiHandle *accessible = NULL;

      /*
        Copied from LTFX source code
      */
      start = cur = time (NULL);

      if (cctxt->req->arg_list) {
            char *time_out = NULL;
            time_out = g_slist_nth_data (cctxt->req->arg_list, 0);
            time_wait = atoi (time_out);
            if (!time_wait && !ldtp_gui_timeout)
                  time_wait = 30;
      } else if (!ldtp_gui_timeout) {
            time_wait = 30; // Max wait for 30 seconds
      }

      while ((difftime (cur, start) < time_wait) && (accessible == NULL)) {
            ldtp_nsleep (0, 30000);

            cur = time (NULL);
            accessible = ldtp_gui_get_gui_handle (cctxt, err);
      }

      if (accessible == NULL)
            *err = LDTP_ERROR_GUI_NOT_EXIST;
      else {
            Accessible_unref (accessible->handle);
            g_free (accessible);
            *err = LDTP_ERROR_SUCCESS;
      }
}

void
ldtp_gui_wait_till_gui_not_exist (LDTPClientContext* cctxt, LDTPErrorCode* err)
{
      int time_wait = ldtp_gui_timeout;
      time_t start, cur;
      LDTPGuiHandle *accessible = NULL;

      /*
        Copied from LTFX source code
      */
      start = cur = time (NULL);

      if (cctxt->req->arg_list) {
            char *time_out = NULL;
            time_out = g_slist_nth_data (cctxt->req->arg_list, 0);
            time_wait = atoi (time_out);
            if (!time_wait && !ldtp_gui_timeout)
                  time_wait = 30;
      } else if (!ldtp_gui_timeout) {
            time_wait = 30; // Max wait for 30 seconds
      }

      accessible = ldtp_gui_get_gui_handle (cctxt, err);

      while ((difftime (cur, start) < time_wait) && (accessible != NULL)) {
            ldtp_nsleep (0, 30000);

            cur = time (NULL);
            if (accessible) {
                  Accessible_unref (accessible->handle);
                  g_free (accessible);
                  accessible = NULL;
            }
            accessible = ldtp_gui_get_gui_handle (cctxt, err);
      }

      if (accessible == NULL)
            *err = LDTP_ERROR_SUCCESS;
      else {
            Accessible_unref (accessible->handle);
            g_free (accessible);
            *err = LDTP_ERROR_GUI_EXIST;
      }
}

void
ldtp_gui_gui_exist (LDTPClientContext* cctxt, LDTPErrorCode* err)
{
      LDTPGuiHandle *accessible = NULL;

      accessible = ldtp_gui_get_gui_handle (cctxt, err);
      if (accessible == NULL)
            *err = LDTP_ERROR_GUI_NOT_EXIST;
      else {
            /*
              FIXME: Bug 407728
              AccessibleStateSet_contains returns TRUE on passing SPI_STATE_SHOWING
              to an object which does not have the state. Need to investigate more.
            if (cctxt->req->component) {
                  g_print ("Component: %s - %d\n", cctxt->req->component,
                         object_state_contains (accessible->handle, PUSH_BUTTON, cctxt->log_fp));
                  if (object_state_contains (accessible->handle, PUSH_BUTTON, cctxt->log_fp) == -1) {
                        Accessible_unref (accessible->handle);
                        g_free (accessible);
                        *err = LDTP_ERROR_GUI_NOT_EXIST;
                        return;
                  }
            }
            */
            Accessible_unref (accessible->handle);
            g_free (accessible);
            *err = LDTP_ERROR_SUCCESS;
      }
}

LDTPErrorCode
grab_focus (Accessible *object, FILE *log_fp)
{
      LDTPErrorCode error;
      SPIBoolean flag = FALSE;
      AccessibleComponent* component;

      component = Accessible_getComponent (object);
      if (component) {
            flag = AccessibleComponent_grabFocus (component);
            Accessible_unref (component);
            if (flag == TRUE)
                  return LDTP_ERROR_SUCCESS;
            else {
                  error = LDTP_ERROR_UNABLE_TO_GRAB_FOCUS;
                  log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
                  return error;
            }
      }
      error = LDTP_ERROR_OBJ_NOT_COMPONENT_TYPE;
      log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
      return error;
}

Generated by  Doxygen 1.6.0   Back to index