// Required by fcitx. Adds our file descriptor (for the tablet) to its // fd_set, so we can get notified about new tablet input void FcitxTabletSetFd(void* arg) { FcitxTablet* tablet = (FcitxTablet*) arg; int fd = tablet->driverInstance->GetDescriptor(tablet->driverData); if(fd > 0) { FD_SET(fd, FcitxInstanceGetReadFDSet(tablet->fcitx)); if(FcitxInstanceGetMaxFD(tablet->fcitx) < fd) FcitxInstanceSetMaxFD(tablet->fcitx, fd); } // also add the timeout FD FD_SET(tablet->timeoutFd, FcitxInstanceGetReadFDSet(tablet->fcitx)); if(FcitxInstanceGetMaxFD(tablet->fcitx) < tablet->timeoutFd) FcitxInstanceSetMaxFD(tablet->fcitx, tablet->timeoutFd); }
void RemoteSetFD(void* arg) { FcitxRemote* remote = (FcitxRemote*) arg; FD_SET(remote->socket_fd, FcitxInstanceGetReadFDSet(remote->owner)); if (FcitxInstanceGetMaxFD(remote->owner) < remote->socket_fd) FcitxInstanceSetMaxFD(remote->owner, remote->socket_fd); }
void CloudPinyinSetFD(void* arg) { FcitxCloudPinyin* cloudpinyin = (FcitxCloudPinyin*) arg; FcitxInstance* instance = cloudpinyin->owner; int maxfd = cloudpinyin->pipeRecv; FD_SET(maxfd, FcitxInstanceGetReadFDSet(instance)); if (maxfd > FcitxInstanceGetMaxFD(instance)) FcitxInstanceSetMaxFD(instance, maxfd); }
void X11SetFD(void* arg) { FcitxX11* x11priv = (FcitxX11*)arg; int fd = ConnectionNumber(x11priv->dpy); FD_SET(fd, FcitxInstanceGetReadFDSet(x11priv->owner)); if (FcitxInstanceGetMaxFD(x11priv->owner) < fd) FcitxInstanceSetMaxFD(x11priv->owner, fd); }
void DBusSetFD(void* arg) { FcitxDBus* dbusmodule = (FcitxDBus*) arg; FcitxInstance* instance = dbusmodule->owner; fd_set *rfds = FcitxInstanceGetReadFDSet(instance); fd_set *wfds = FcitxInstanceGetWriteFDSet(instance); fd_set *efds = FcitxInstanceGetExceptFDSet(instance); DBusUpdateFDSet(dbusmodule->watches, rfds, wfds, efds); }
void DBusProcessEvent(void* arg) { FcitxDBus* dbusmodule = (FcitxDBus*) arg; FcitxInstance* instance = dbusmodule->owner; fd_set *rfds = FcitxInstanceGetReadFDSet(instance); fd_set *wfds = FcitxInstanceGetWriteFDSet(instance); fd_set *efds = FcitxInstanceGetExceptFDSet(instance); DBusProcessEventForWatches(dbusmodule->watches, rfds, wfds, efds); DBusProcessEventForConnection(dbusmodule->conn); DBusProcessEventForConnection(dbusmodule->privconn); }
void CloudPinyinProcessEvent(void* arg) { FcitxCloudPinyin* cloudpinyin = (FcitxCloudPinyin*) arg; FcitxInstance* instance = cloudpinyin->owner; if (!FD_ISSET(cloudpinyin->pipeRecv, FcitxInstanceGetReadFDSet(instance))) return; char c; while (read(cloudpinyin->pipeRecv, &c, sizeof(char)) > 0); pthread_mutex_lock(&cloudpinyin->finishQueueLock); CurlQueue* queue; queue = cloudpinyin->finishQueue; /* this queue header is empty, so the check condition is "next" not null */ while (queue->next != NULL) { /* remove pivot from queue, thus pivot need to be free'd in HandleRequest */ CurlQueue* pivot = queue->next; queue->next = queue->next->next; CloudPinyinHandleRequest(cloudpinyin, pivot); } pthread_mutex_unlock(&cloudpinyin->finishQueueLock); }
// Called when we wake up from select, i.e. the tablet has data to read void FcitxTabletProcess(void* arg) { static struct itimerspec empty_timer = { {0, 0}, {0, 0} }; FcitxTablet* tablet = (FcitxTablet*) arg; int fd = tablet->driverInstance->GetDescriptor(tablet->driverData); // Check we woke up for the right reason if(fd > 0 && FD_ISSET(fd, FcitxInstanceGetReadFDSet(tablet->fcitx))) { { // first read a packet from the raw device int n = 0; const int pktsize = tablet->driverInstance->packet_size; do { n += read(fd, &tablet->driverPacket[n], pktsize - n); } while(n < pktsize); } boolean redraw = false; { // then send it to the driver to convert into events FcitxTabletDriverEvent e; pt_t pt; while((e = tablet->driverInstance->GetEvent(tablet->driverData, tablet->driverPacket, &pt)) != EV_NONE) { // if the tablet did anything, cancel the timer timerfd_settime(tablet->timeoutFd, 0, &empty_timer, NULL); switch(e) { case EV_PENDOWN: if(tablet->timeoutCommitPending) { FcitxInstanceProcessKey(tablet->fcitx, FCITX_PRESS_KEY, 0, FcitxKey_VoidSymbol, IME_COMMIT); tablet->timeoutCommitPending = false; } break; case EV_PENUP: { // push an invalid (end-of-stroke) point pt_t p = PT_INVALID; PushCoordinate(tablet, p); // get the IME to re-run the recognition engine FcitxInstanceProcessKey(tablet->fcitx, FCITX_PRESS_KEY, 0, FcitxKey_VoidSymbol, IME_RECOGNISE); // start the stroke commit timer timerfd_settime(tablet->timeoutFd, 0, &tablet->delay, NULL); } break; case EV_POINT: { // If it's not shown already, show the character drawing window if(tablet->strokesPtr > tablet->strokesBuffer && PT_ISVALID(tablet->strokesPtr[-1]) && PT_ISVALID(pt)) { //we have at least 2 valid new points // draw the line, scaling for the size of the window XDrawLine(tablet->xDisplay, tablet->xWindow, tablet->xGC, tablet->strokesPtr[-1].x * (float) tablet->xWidth / (float) tablet->driverInstance->x_max, tablet->strokesPtr[-1].y * (float) tablet->xHeight / (float) tablet->driverInstance->y_max, pt.x * (float) tablet->xWidth / (float) tablet->driverInstance->x_max, pt.y * (float) tablet->xHeight / (float) tablet->driverInstance->y_max); redraw = true; } PushCoordinate(tablet, pt); } break; default: FcitxLog(ERROR, "Driver returned unknown event: %d", e); break; } } } if(redraw) { // draw the stroke on the screen // If it's not shown already, map the win XMapWindow(tablet->xDisplay, tablet->xWindow); XFlush(tablet->xDisplay); } FD_CLR(fd, FcitxInstanceGetReadFDSet(tablet->fcitx)); } if(FD_ISSET(tablet->timeoutFd, FcitxInstanceGetReadFDSet(tablet->fcitx))) { // the timer expired. Set the flag so that the next pendown will commit the most likely character tablet->timeoutCommitPending = true; timerfd_settime(tablet->timeoutFd, 0, &empty_timer, NULL); FD_CLR(tablet->timeoutFd, FcitxInstanceGetReadFDSet(tablet->fcitx)); } }