static gboolean
control_spi_listener_process_event (gpointer data)
{
    AccessibleEvent *event;
    ControlSpiListener *listener = CONTROL_SPI_LISTENER (data);

    while (g_queue_is_empty(listener->event_queue) == FALSE) {
        event = (AccessibleEvent *)g_queue_pop_head(listener->event_queue);

        if (strcmp (event->type, "window:activate") == 0) {
            if (listener->root)
                Accessible_unref (listener->root);
            Accessible_ref (event->source);
            listener->root = event->source;
        }

        AccessibleEvent_unref (event);
    }

    control_spi_listener_free_actions_list (listener);
    control_spi_listener_build_actions_list (listener, listener->root, 0);
    control_spi_listener_dump_actions_list (listener);

    g_signal_emit (listener,
                   control_spi_listener_signals[SIGNAL_CHANGED], 0, NULL);

    listener->idle_id = 0;

    return FALSE;
}
Exemple #2
0
static gboolean
idle_do_log (EventLog *log)
{
	GList *l, *events;

	events = log->event_list;
	log->event_list = NULL;

	for (l = events; l; l = l->next) {
		AccessibleEvent *event = l->data;
		log_event (log, event);
		AccessibleEvent_unref (event);
	}
	g_list_free (events);

	log->idle_log = 0;
	
	return FALSE;
}
static void
cspi_event (CSpiEventListener    *listener,
	    AccessibleEvent *event)
{
  GList *l;
  CSpiEventListener *clistener = (CSpiEventListener *) listener;
  InternalEvent     *ievent;
  AccessibleEvent   *aevent;
  
  ievent = g_new0(InternalEvent, 1);
  ievent->event.type    = g_strdup (event->type);
  ievent->event.source  = event->source;
  ievent->event.detail1 = event->detail1;
  ievent->event.detail2 = event->detail2;
  ievent->event.v_type = event->v_type;
  if (event->v_type == EVENT_DATA_STRING)
  {
    ievent->event.v.text = g_strdup (event->v.text);
  }
  else memcpy (&ievent->event.v, &event->v, sizeof(event->v));
  ievent->id            = _e_id++;
  ievent->magic         = SPI_INTERNAL_EVENT_MAGIC;
  ievent->ref_count     = 0;
  aevent = (AccessibleEvent *)ievent;
  Accessible_ref (aevent->source);
  AccessibleEvent_ref (aevent);

  /* FIXME: re-enterancy hazard on this list */
  for (l = clistener->callbacks; l; l = l->next)
    {
      EventHandler *eh = l->data;
      /* cast hides our private stuff from client handlers */
      eh->cb.event (aevent, eh->user_data);
    }

  AccessibleEvent_unref (aevent);
}
Exemple #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;
}