void GsSelect(GR_TIMEOUT timeout) { fd_set rfds; int e; int setsize = 0; struct timeval tout; struct timeval *to; #if NONETWORK int fd; #endif /* perform pre-select duties, if any*/ if(rootwp->psd->PreSelect) rootwp->psd->PreSelect(rootwp->psd); /* Set up the FDs for use in the main select(): */ FD_ZERO(&rfds); if(mouse_fd >= 0) { FD_SET(mouse_fd, &rfds); if (mouse_fd > setsize) setsize = mouse_fd; } if(keyb_fd >= 0) { FD_SET(keyb_fd, &rfds); if (keyb_fd > setsize) setsize = keyb_fd; } #ifdef MW_FEATURE_TWO_KEYBOARDS if(keyb2_fd >= 0) { FD_SET(keyb2_fd, &rfds); if (keyb2_fd > setsize) setsize = keyb2_fd; } #endif #if NONETWORK /* handle registered input file descriptors*/ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset)) continue; FD_SET(fd, &rfds); if (fd > setsize) setsize = fd; } #else /* not NONETWORK */ /* handle client socket connections*/ FD_SET(un_sock, &rfds); if (un_sock > setsize) setsize = un_sock; curclient = root_client; while(curclient) { if(curclient->waiting_for_event && curclient->eventhead) { curclient->waiting_for_event = FALSE; GrGetNextEventWrapperFinish(curclient->id); return; } FD_SET(curclient->id, &rfds); if(curclient->id > setsize) setsize = curclient->id; curclient = curclient->next; } #endif /* NONETWORK */ /* Set up the timeout for the main select(): */ if (timeout == (GR_TIMEOUT) -1L) { /* poll*/ tout.tv_sec = 0; tout.tv_usec = 0; to = &tout; } else { #if MW_FEATURE_TIMERS if(GdGetNextTimeout(&tout, timeout) == TRUE) to = &tout; else #endif /* MW_FEATURE_TIMERS */ to = NULL; } /* Wait for some input on any of the fds in the set or a timeout: */ if((e = select(setsize+1, &rfds, NULL, NULL, to)) > 0) { /* If data is present on the mouse fd, service it: */ if(mouse_fd >= 0 && FD_ISSET(mouse_fd, &rfds)) while(GsCheckMouseEvent()) continue; /* If data is present on the keyboard fd, service it: */ if( (keyb_fd >= 0 && FD_ISSET(keyb_fd, &rfds)) #ifdef MW_FEATURE_TWO_KEYBOARDS || (keyb2_fd >= 0 && FD_ISSET(keyb2_fd, &rfds)) #endif ) while(GsCheckKeyboardEvent()) continue; #if NONETWORK /* check for input on registered file descriptors */ for (fd = 0; fd < regfdmax; fd++) { GR_EVENT_FDINPUT * gp; if (!FD_ISSET(fd, ®fdset) || !FD_ISSET(fd, &rfds)) continue; gp =(GR_EVENT_FDINPUT *)GsAllocEvent(curclient); if(gp) { gp->type = GR_EVENT_TYPE_FDINPUT; gp->fd = fd; } } #else /* not NONETWORK */ /* If a client is trying to connect, accept it: */ if(FD_ISSET(un_sock, &rfds)) GsAcceptClient(); /* If a client is sending us a command, handle it: */ curclient = root_client; while(curclient) { GR_CLIENT *curclient_next; /* curclient may be freed in GsDropClient*/ curclient_next = curclient->next; if(FD_ISSET(curclient->id, &rfds)) GsHandleClient(curclient->id); curclient = curclient_next; } #endif /* NONETWORK */ } else if (e == 0) { #if NONETWORK /* * Timeout has occured. Currently return * a timeout event regardless of whether * client has selected for it. * Note: this will be changed back to GR_EVENT_TYPE_NONE * for the GrCheckNextEvent/LINK_APP_TO_SERVER case */ #if MW_FEATURE_TIMERS if(GdTimeout() == TRUE) #endif { GR_EVENT_GENERAL * gp; gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient); if(gp) gp->type = GR_EVENT_TYPE_TIMEOUT; } #else /* not NONETWORK */ #if MW_FEATURE_TIMERS GdTimeout(); #endif #endif /* NONETWORK */ } else if(errno != EINTR) EPRINTF("Select() call in main failed\n"); }
void GsSelect(void) { fd_set rfds; int e; int setsize = 0; struct timeval to; /* Set up the FDs for use in the main select(): */ FD_ZERO(&rfds); FD_SET(mouse_fd, &rfds); FD_SET(keyb_fd, &rfds); if (mouse_fd > setsize) setsize = mouse_fd; if (keyb_fd > setsize) setsize = keyb_fd; #if NONETWORK /* handle registered input file descriptors*/ if (regfd != -1) { FD_SET(regfd, &rfds); if (regfd > setsize) setsize = regfd; } #else /* handle client socket connections*/ FD_SET(un_sock, &rfds); if (un_sock > setsize) setsize = un_sock; curclient = root_client; while(curclient) { if(curclient->waiting_for_event && curclient->eventhead) { curclient->waiting_for_event = FALSE; GsGetNextEventWrapperFinish(); return; } FD_SET(curclient->id, &rfds); if(curclient->id > setsize) setsize = curclient->id; curclient = curclient->next; } #endif ++setsize; /* Set up the timeout for the main select(): */ to.tv_sec = 0L; to.tv_usec = 10000L; /* Wait for some input on any of the fds in the set or a timeout: */ if((e = select(setsize, &rfds, NULL, NULL, &to)) > 0) { /* If data is present on the mouse fd, service it: */ if(FD_ISSET(mouse_fd, &rfds)) GsCheckMouseEvent(); /* If data is present on the keyboard fd, service it: */ if(FD_ISSET(keyb_fd, &rfds)) GsCheckKeyboardEvent(); #if NONETWORK /* If registered input descriptor, handle it*/ if(regfd != -1 && FD_ISSET(regfd, &rfds)) { GR_EVENT_FDINPUT * gp; gp = (GR_EVENT_FDINPUT *)GsAllocEvent(curclient); if(gp) { gp->type = GR_EVENT_TYPE_FDINPUT; gp->fd = regfd; } } #else /* If a client is trying to connect, accept it: */ if(FD_ISSET(un_sock, &rfds)) GsAcceptClient(); /* If a client is sending us a command, handle it: */ curclient = root_client; while(curclient) { if(FD_ISSET(curclient->id, &rfds)) GsHandleClient(curclient->id); curclient = curclient->next; } #endif } else if(!e) { #if FRAMEBUFFER | BOGL if(fb_CheckVtChange()) GsRedrawScreen(); #endif } else if(errno != EINTR) perror("Select() call in main failed"); }
void GsSelect(GR_TIMEOUT timeout) { fd_set rfds; int e; int setsize = 0; struct timeval tout; struct timeval *to; #if NONETWORK int fd; #endif #if HAVE_VNCSERVER #if VNCSERVER_PTHREADED int dummy; #else rfbClientIteratorPtr i; rfbClientPtr cl; #endif #endif /* X11/SDL perform single update of aggregate screen update region*/ if (scrdev.PreSelect) { /* returns # pending events*/ if (scrdev.PreSelect(&scrdev)) { /* poll for mouse data and service if found*/ while (GsCheckMouseEvent()) continue; /* poll for keyboard data and service if found*/ while (GsCheckKeyboardEvent()) continue; /* events found, return with no sleep*/ return; } } /* Set up the FDs for use in the main select(): */ FD_ZERO(&rfds); if(mouse_fd >= 0) { FD_SET(mouse_fd, &rfds); if (mouse_fd > setsize) setsize = mouse_fd; } if(keyb_fd >= 0) { FD_SET(keyb_fd, &rfds); if (keyb_fd > setsize) setsize = keyb_fd; } #if MW_FEATURE_TWO_KEYBOARDS if(keyb2_fd >= 0) { FD_SET(keyb2_fd, &rfds); if (keyb2_fd > setsize) setsize = keyb2_fd; } #endif #if NONETWORK /* handle registered input file descriptors*/ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset)) continue; FD_SET(fd, &rfds); if (fd > setsize) setsize = fd; } #else /* !NONETWORK */ /* handle client socket connections*/ FD_SET(un_sock, &rfds); if (un_sock > setsize) setsize = un_sock; curclient = root_client; while(curclient) { if(curclient->waiting_for_event && curclient->eventhead) { curclient->waiting_for_event = FALSE; GrGetNextEventWrapperFinish(curclient->id); return; } FD_SET(curclient->id, &rfds); if(curclient->id > setsize) setsize = curclient->id; curclient = curclient->next; } #endif /* NONETWORK */ #if HAVE_VNCSERVER #if VNCSERVER_PTHREADED /* Add file vnc thread fd. This is useful to force handling of events generated by the VNC thread*/ FD_SET( vnc_thread_fd, &(rfds) ); if ( vnc_thread_fd > setsize ) setsize = vnc_thread_fd; #else /* Add all VNC open sockets to nano-X select set */ FD_SET( rfbScreen->listenSock, &(rfds) ); if ( rfbScreen->listenSock > setsize ) setsize = rfbScreen->listenSock; FD_SET( rfbScreen->httpListenSock, &(rfds) ); if ( rfbScreen->httpListenSock > setsize ) setsize = rfbScreen->httpListenSock; i = rfbGetClientIterator(rfbScreen); cl = rfbClientIteratorNext(i); while ( cl ) { if ( cl->sock >= 0 ) { FD_SET( cl->sock, &(rfds) ); if ( cl->sock > setsize ) setsize = cl->sock; } cl = rfbClientIteratorNext(i); } rfbReleaseClientIterator(i); #endif #endif /* HAVE_VNCSERVER*/ /* setup timeval struct for block or poll in select()*/ tout.tv_sec = tout.tv_usec = 0; /* setup for assumed poll*/ to = &tout; int poll = (timeout == (GR_TIMEOUT) -1L); /* timeout = -1 means just poll*/ if (!poll) { #if MW_FEATURE_TIMERS /* get next timer or use passed timeout and convert to timeval struct*/ if (!GdGetNextTimeout(&tout, timeout)) /* no app timers or VTSWITCH?*/ #else if (timeout) /* setup mwin poll timer*/ { /* convert wait timeout to timeval struct*/ tout.tv_sec = timeout / 1000; tout.tv_usec = (timeout % 1000) * 1000; } else #endif { to = NULL; /* no timers, block*/ } } /* some drivers can't block in select as backend is poll based (SDL)*/ if (scrdev.flags & PSF_CANTBLOCK) { #define WAITTIME 100 /* check if would block permanently or timeout > WAITTIME*/ if (to == NULL || tout.tv_sec != 0 || tout.tv_usec > WAITTIME) { /* override timeouts and wait for max WAITTIME ms*/ to = &tout; tout.tv_sec = 0; tout.tv_usec = WAITTIME; } } /* Wait for some input on any of the fds in the set or a timeout*/ #if NONETWORK SERVER_UNLOCK(); /* allow other threads to run*/ #endif e = select(setsize+1, &rfds, NULL, NULL, to); #if NONETWORK SERVER_LOCK(); #endif if(e > 0) /* input ready*/ { /* service mouse file descriptor*/ if(mouse_fd >= 0 && FD_ISSET(mouse_fd, &rfds)) while(GsCheckMouseEvent()) continue; /* service keyboard file descriptor*/ if( (keyb_fd >= 0 && FD_ISSET(keyb_fd, &rfds)) #if MW_FEATURE_TWO_KEYBOARDS || (keyb2_fd >= 0 && FD_ISSET(keyb2_fd, &rfds)) #endif ) while(GsCheckKeyboardEvent()) continue; #if HAVE_VNCSERVER && VNCSERVER_PTHREADED if(vnc_thread_fd >= 0 && FD_ISSET(vnc_thread_fd, &rfds)) /* Read from vnc pipe */ read( vnc_thread_fd, &dummy, sizeof(int)); #endif #if NONETWORK /* check for input on registered file descriptors */ for (fd = 0; fd < regfdmax; fd++) { GR_EVENT_FDINPUT * gp; if (!FD_ISSET(fd, ®fdset) || !FD_ISSET(fd, &rfds)) continue; gp = (GR_EVENT_FDINPUT *)GsAllocEvent(curclient); if(gp) { gp->type = GR_EVENT_TYPE_FDINPUT; gp->fd = fd; } } #else /* !NONETWORK */ /* If a client is trying to connect, accept it: */ if(FD_ISSET(un_sock, &rfds)) GsAcceptClient(); /* If a client is sending us a command, handle it: */ curclient = root_client; while (curclient) { GR_CLIENT *curclient_next; /* curclient may be freed in GsDropClient*/ curclient_next = curclient->next; if(FD_ISSET(curclient->id, &rfds)) GsHandleClient(curclient->id); curclient = curclient_next; } #if HAVE_VNCSERVER && !VNCSERVER_PTHREADED rfbProcessEvents(rfbScreen, 0); #endif #endif /* NONETWORK */ } else if (e == 0) /* timeout*/ { #if NONETWORK /* * Timeout has occured. Currently return a timeout event * regardless of whether client has selected for it. * Note: this will be changed back to GR_EVENT_TYPE_NONE * for the GrCheckNextEvent/LINK_APP_TO_SERVER case */ #if MW_FEATURE_TIMERS if(GdTimeout()) #endif { GR_EVENT_GENERAL * gp; if ((gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient)) != NULL) gp->type = GR_EVENT_TYPE_TIMEOUT; } #else /* !NONETWORK */ #if MW_FEATURE_TIMERS /* check for timer timeouts and service if found*/ GdTimeout(); #endif #endif /* NONETWORK */ } else if(errno != EINTR) EPRINTF("Select() call in main failed\n"); }