static void
test_editable_text (AccessibleEditableText *etext)
{
	char *str;
	AccessibleText *text;

	fprintf (stderr, "Testing editable text ...\n");
	
	g_assert (Accessible_isText (etext));
	text = Accessible_getText (etext);

	AccessibleEditableText_setTextContents (
		etext, TEST_STRING_B);

	str = AccessibleText_getText (text, 0, WHOLE_STRING);
	g_assert (!strcmp (str, TEST_STRING_B));

	SPI_freeString (str);

	/* FIXME: lots more editing here */

	AccessibleEditableText_setTextContents (
		etext, TEST_STRING_A);

	AccessibleText_unref (text);
}
Esempio n. 2
0
static void
log_object_text_caret_moved (EventLog *log, const AccessibleEvent *event)
{
	AccessibleText *text;
	long int start, end, offset, text_length;

	if (!log_sanity_check_text (log, event))
		return;

	offset = event->detail1;

	log_message (log, "caret moved (%s) to %d on ", event->type, offset);
	log_accessible (log, event->source);

	text = Accessible_getText (event->source);

	offset = event->detail1;
	text_length = AccessibleText_getCharacterCount (text);
	if (offset < 0 || offset > text_length) {
		log_error (log, TRUE, "caret moved beyond end of text %d characters long", text_length);
		return;
	}

	AccessibleText_getTextAtOffset (text, offset, 
					SPI_TEXT_BOUNDARY_SENTENCE_START,
					&start, &end);
	log_message (log, "offsets: sentance_start %d->%d, ", start, end);
	AccessibleText_getTextAtOffset (text, offset, 
					SPI_TEXT_BOUNDARY_SENTENCE_END,
					&start, &end);
	log_message (log, "sentance_end %d->%d, ", start, end);
	AccessibleText_getTextAtOffset (text, offset, 
					SPI_TEXT_BOUNDARY_LINE_START,
					&start, &end);
	log_message (log, "line_start %d->%d, ", start, end);
	AccessibleText_getTextAtOffset (text, offset, 
					SPI_TEXT_BOUNDARY_LINE_END,
					&start, &end);
	log_message (log, "line_end %d->%d, ", start, end);

	AccessibleText_getTextAtOffset (text, offset, 
					SPI_TEXT_BOUNDARY_WORD_START,
					&start, &end);
	log_message (log, "word_start %d->%d, ", start, end);
	AccessibleText_getTextAtOffset (text, offset, 
					SPI_TEXT_BOUNDARY_WORD_END,
					&start, &end);
	log_message (log, "word_end %d->%d, ", start, end);
	log_message (log, "\n");
}
char * windows_text ( SQByteArray * _pointer )
{
   char * text = NULL;
   Accessible * accessibleObject = windows_to_accessible(_pointer);
   if ( Accessible_isText(accessibleObject) == SPI_TRUE )
   {
       AccessibleText * textObj = Accessible_getText(accessibleObject);
       long count = AccessibleText_getCharacterCount ( textObj );
       text = AccessibleText_getText ( textObj, 0, count );
       AccessibleText_unref ( textObj );
       return windows_string(text);
   }
   else if ( Accessible_isValue(accessibleObject) == SPI_TRUE )
   {
       AccessibleValue * valueObj = Accessible_getValue(accessibleObject);

       double current = AccessibleValue_getCurrentValue ( valueObj );
       text = malloc(SQ_MAX_VALUE_LENGTH);
       SNPRINTF_FUNCTION ( text, SQ_MAX_VALUE_LENGTH, "%f", current );
       return text;
   }
   return SQ_STRDUP_FUNCTION("");
}
Esempio n. 4
0
static void evListenerCB(const AccessibleEvent *event, void *user_data) {
  static int running = 0;
  struct evList *ev = malloc(sizeof(*ev));
  AccessibleEvent_ref(event);
  AccessibleText *newText;
  ev->next = evs;
  ev->ev = event;
  evs = ev;
  int state_changed_focused;

  /* this is not atomic but we can only be recursively called within calls
   * to the lib */
  if (running)
    return;
  else
    running = 1;

  while (evs) {
    pthread_mutex_lock(&updateMutex);
    /* pickup a list of events to handle */
    ev = evs;
    evs = NULL;
    for (; ev; AccessibleEvent_unref(ev->ev), ev = ev->next) {
      event = ev->ev;
      state_changed_focused = !strcmp(event->type,"object:state-changed:focused");
      if (state_changed_focused && !event->detail1) {
	if (event->source == curFocus)
	  finiTerm();
      } else if (!strcmp(event->type,"focus:") || (state_changed_focused && event->detail1)) {
	if (!(newText = Accessible_getText(event->source))) {
	  if (curFocus) finiTerm();
	} else {
          AccessibleRole role = Accessible_getRole(event->source);
	  if (typeAll ||
	      (typeText && ((role == SPI_ROLE_TEXT) || (role == SPI_ROLE_PASSWORD_TEXT) || (role == SPI_ROLE_PARAGRAPH))) ||
	      (typeTerminal && (role == SPI_ROLE_TERMINAL))) {
	    restartTerm(event->source, newText);
	  } else {
	    logMessage(LOG_DEBUG,"AT SPI widget not for us");
	    if (curFocus) finiTerm();
	  }
	}
      } else if (!strcmp(event->type,"object:text-caret-moved")) {
	if (event->source != curFocus) continue;
	logMessage(LOG_DEBUG,"caret move to %lu",event->detail1);
	caretPosition(event->detail1);
      } else if (!strcmp(event->type,"object:text-changed:delete")) {
	long x,y,toDelete = event->detail2;
	long length = 0, toCopy;
	long downTo; /* line that will provide what will follow x */
	logMessage(LOG_DEBUG,"delete %lu from %lu",event->detail2,event->detail1);
	if (event->source != curFocus) continue;
	findPosition(event->detail1,&x,&y);
	downTo = y;
	if (downTo < curNumRows)
		length = curRowLengths[downTo];
	while (x+toDelete >= length) {
	  downTo++;
	  if (downTo <= curNumRows - 1)
	    length += curRowLengths[downTo];
	  else {
	    /* imaginary extra line doesn't provide more length, and shouldn't need to ! */
	    if (x+toDelete > length) {
	      logMessage(LOG_ERR,"deleting past end of text !");
	      /* discarding */
	      toDelete = length - x;
	    }
	    break; /* deleting up to end */
	  }
	}
	if (length-toDelete>0) {
	  /* still something on line y */
	  if (y!=downTo) {
	    curRowLengths[y] = length-toDelete;
	    curRows[y]=realloc(curRows[y],curRowLengths[y]*sizeof(*curRows[y]));
	  }
	  if ((toCopy = length-toDelete-x))
	    memmove(curRows[y]+x,curRows[downTo]+curRowLengths[downTo]-toCopy,toCopy*sizeof(*curRows[downTo]));
	  if (y==downTo) {
	    curRowLengths[y] = length-toDelete;
	    curRows[y]=realloc(curRows[y],curRowLengths[y]*sizeof(*curRows[y]));
	  }
	} else {
	  /* kills this line as well ! */
	  y--;
	}
	if (downTo>=curNumRows)
	  /* imaginary extra lines don't need to be deleted */
	  downTo=curNumRows-1;
	delRows(y+1,downTo-y);
	caretPosition(AccessibleText_getCaretOffset(curTerm));
      } else if (!strcmp(event->type,"object:text-changed:insert")) {
	long len=event->detail2,semilen,x,y;
	char *added;
	const char *adding,*c;
	logMessage(LOG_DEBUG,"insert %lu from %lu",event->detail2,event->detail1);
	if (event->source != curFocus) continue;
	findPosition(event->detail1,&x,&y);
	adding = c = added = AccessibleTextChangedEvent_getChangeString(event);
	if (x && (c = strchr(adding,'\n'))) {
	  /* splitting line */
	  addRows(y,1);
	  semilen=my_mbslen(adding,c+1-adding);
	  curRowLengths[y]=x+semilen;
	  if (x+semilen-1>curNumCols)
	    curNumCols=x+semilen-1;

	  /* copy beginning */
	  curRows[y]=malloc(curRowLengths[y]*sizeof(*curRows[y]));
	  memcpy(curRows[y],curRows[y+1],x*sizeof(*curRows[y]));
	  /* add */
	  my_mbsrtowcs(curRows[y]+x,&adding,semilen,NULL);
	  len-=semilen;
	  adding=c+1;
	  /* shift end */
	  curRowLengths[y+1]-=x;
	  memmove(curRows[y+1],curRows[y+1]+x,curRowLengths[y+1]*sizeof(*curRows[y+1]));
	  x=0;
	  y++;
	}
	while ((c = strchr(adding,'\n'))) {
	  /* adding lines */
	  addRows(y,1);
	  semilen=my_mbslen(adding,c+1-adding);
	  curRowLengths[y]=semilen;
	  if (semilen-1>curNumCols)
	    curNumCols=semilen-1;
	  curRows[y]=malloc(semilen*sizeof(*curRows[y]));
	  my_mbsrtowcs(curRows[y],&adding,semilen,NULL);
	  len-=semilen;
	  adding=c+1;
	  y++;
	}
	if (len) {
	  /* still length to add on the line following it */
	  if (y==curNumRows) {
	    /* It won't insert ending \n yet */
	    addRows(y,1);
	    curRows[y]=NULL;
	    curRowLengths[y]=0;
	  }
	  curRowLengths[y] += len;
	  curRows[y]=realloc(curRows[y],curRowLengths[y]*sizeof(*curRows[y]));
	  memmove(curRows[y]+x+len,curRows[y]+x,(curRowLengths[y]-(x+len))*sizeof(*curRows[y]));
	  my_mbsrtowcs(curRows[y]+x,&adding,len,NULL);
	  if (curRowLengths[y]-(curRows[y][curRowLengths[y]-1]=='\n')>curNumCols)
	    curNumCols=curRowLengths[y]-(curRows[y][curRowLengths[y]-1]=='\n');
	}
	SPI_freeString(added);
	caretPosition(AccessibleText_getCaretOffset(curTerm));
      } else
	logMessage(LOG_INFO,"event %s, source %p, detail1 %lu detail2 %lu",event->type,event->source,event->detail1,event->detail2);
    }
    pthread_mutex_unlock(&updateMutex);
  }
  running = 0;
}
static void
validate_accessible (Accessible *accessible,
		     gboolean    has_parent,
		     gboolean    recurse_down)
{
	Accessible          *tmp;
	char                *name, *descr;
	AccessibleRole       role;
	AccessibleRelation **relations;
	char                *role_name;
	GString             *item_str = g_string_new ("");
	int                  i;

	name = Accessible_getName (accessible);
	g_assert (name != NULL);
	
	descr = Accessible_getDescription (accessible);
	g_assert (descr != NULL);

	role = Accessible_getRole (accessible);
	g_assert (role != SPI_ROLE_INVALID);
	role_name = Accessible_getRoleName (accessible);
	g_assert (role_name != NULL);

	relations = Accessible_getRelationSet (accessible);
	g_assert (relations != NULL);

	for (i = 0; relations [i]; i++) {
		AccessibleRelationType type;
		int                    targets;

		fprintf (stderr, "relation %d\n", i);

		type = AccessibleRelation_getRelationType (relations [i]);
		g_assert (type != SPI_RELATION_NULL);

		targets = AccessibleRelation_getNTargets (relations [i]);
		g_assert (targets != -1);

		AccessibleRelation_unref (relations [i]);
		relations [i] = NULL;
	}
	free (relations);

	if (print_tree) {
		int i;

		for (i = 0; i < print_tree_depth; i++)
			fputc (' ', stderr);
		fputs ("|-> [ ", stderr);
	}

	if (Accessible_isAction (accessible)) {
		tmp = Accessible_getAction (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "At");
		else
			test_action (tmp);
		AccessibleAction_unref (tmp);
	}

	if (Accessible_isApplication (accessible)) {
		tmp = Accessible_getApplication (accessible);
		if (print_tree)
			fprintf (stderr, "Ap");
		else
			test_application (tmp);
		AccessibleApplication_unref (tmp);
	}

	if (Accessible_isComponent (accessible)) {
		tmp = Accessible_getComponent (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "Co");
		else
			test_component (tmp);
		AccessibleComponent_unref (tmp);
	}

	if (Accessible_isEditableText (accessible)) {
		tmp = Accessible_getEditableText (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "Et");
		else
			test_editable_text (tmp);
		AccessibleEditableText_unref (tmp);
	}

	if (Accessible_isHypertext (accessible)) {
		tmp = Accessible_getHypertext (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "Ht");
		AccessibleHypertext_unref (tmp);
	}

	if (Accessible_isImage (accessible)) {
		tmp = Accessible_getImage (accessible);
		g_assert (tmp != NULL);
		if (print_tree) {
			char *desc;

			fprintf (stderr, "Im");

			desc = AccessibleImage_getImageDescription (tmp);
			g_string_append_printf (
				item_str, " image descr: '%s'", desc);
			SPI_freeString (desc);
		} else
			test_image (tmp);

		AccessibleImage_unref (tmp);
	}

	if (Accessible_isSelection (accessible)) {
		tmp = Accessible_getSelection (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "Se");
		AccessibleSelection_unref (tmp);
	}

	if (Accessible_isTable (accessible)) {
		tmp = Accessible_getTable (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "Ta");
		else
			test_table (tmp);
		AccessibleTable_unref (tmp);
	}

	if (Accessible_isText (accessible)) {
		tmp = Accessible_getText (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "Te");
		else {
			if (strcmp (name, TEST_STRING_A_OBJECT) == 0)	
				test_text (tmp);
		}
		AccessibleText_unref (tmp);
	}

	if (Accessible_isValue (accessible)) {
		tmp = Accessible_getValue (accessible);
		g_assert (tmp != NULL);
		if (print_tree)
			fprintf (stderr, "Va");
		else
			test_value (tmp); 
		AccessibleValue_unref (tmp);
	}

	if (print_tree)
		fprintf (stderr, " ] '%s' (%s) - %s: %s\n",
			 name, descr, role_name, item_str->str);

	SPI_freeString (name);
	SPI_freeString (descr);
	SPI_freeString (role_name);
	g_string_free (item_str, TRUE);

	validate_tree (accessible, has_parent, recurse_down);
}