static void control_spi_listener_window_listener_cb (const AccessibleEvent *event, void *user_data) { ControlSpiListener *listener = CONTROL_SPI_LISTENER (user_data); AccessibleEvent_ref (event); g_queue_push_tail(listener->event_queue, (gpointer)event); if (!listener->idle_id) listener->idle_id = g_idle_add (control_spi_listener_process_event, listener); }
static void global_event_callback (const AccessibleEvent *event, void *user_data) { EventLog *log = user_data; if (event == NULL) { log_error (log, FALSE, "Null event arrived"); return; } g_return_if_fail (event != NULL); #ifdef IDLE_LOGGING AccessibleEvent_ref (event); log->event_list = g_list_append (log->event_list, (gpointer) event); if (!log->idle_log) log->idle_log = g_idle_add ((GSourceFunc) idle_do_log, log); #else log_event (log, event); #endif }
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); }
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; }