/* IO notification event for X11 internal connections */ static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { pa_x11_wrapper *w = userdata; pa_assert(m); pa_assert(e); pa_assert(fd >= 0); pa_assert(w); pa_assert(PA_REFCNT_VALUE(w) >= 1); XProcessInternalConnection(w->display, fd); work(w); }
static int do_x_select(int fd, int wr) { int *xconn, xconnnum; int max = fd, i; fd_set rmask, wmask; if (!XInternalConnectionNumbers(display, &xconn, &xconnnum)) { perror("XInternalConnectionNumbers"); exit(1); } FD_ZERO(&rmask); FD_ZERO(&wmask); if (wr) FD_SET(fd, &wmask); else FD_SET(fd, &rmask); for (i = 0; i < xconnnum; i++) { FD_SET(xconn[i], &rmask); if (xconn[i] > max) max = xconn[i]; } i = select(max+1, &rmask, &wmask, NULL, NULL); if (i < 0) { perror("select"); exit(1); } for (i = 0; i < xconnnum; i++) if (FD_ISSET(xconn[i], &rmask)) XProcessInternalConnection(display, xconn[i]); XFree(xconn); process_keystrokes(); if (wr) return FD_ISSET(fd, &wmask); else return FD_ISSET(fd, &rmask); }
/** ** Wait for interactive input event. ** ** Handles X11 events, keyboard, mouse. ** Video interrupt for sync. ** Network messages. ** Sound queue. ** ** We must handle atlast one X11 event ** ** FIXME: the initialition could be moved out of the loop */ global void WaitEventsAndKeepSync(void) { #if 0 int connection; int sound; fd_set readfd; fd_set writefd; int maxfd; sound=0; for( ;; ) { if( XPending(TheDisplay) ) { DoEvent(); } if( VideoInterrupts ) { return; } FD_ZERO(&readfd); maxfd=connection=ConnectionNumber(TheDisplay); FD_SET(connection,&readfd); FD_ZERO(&writefd); #ifndef USE_THREAD if( !SoundOff && (sound=SoundFildes)!=-1 ) { if( sound>maxfd ) { maxfd=sound; } FD_SET(sound,&writefd); } #else if( !SoundOff && !SoundThreadRunning && (sound=SoundFildes)!=-1 ) { if( sound>maxfd ) { maxfd=sound; } FD_SET(sound,&writefd); } #endif if( NetworkFildes!=-1 ) { if( NetworkFildes>maxfd ) { maxfd=NetworkFildes; } FD_SET(NetworkFildes,&readfd); } maxfd=select(maxfd+1,&readfd,&writefd,0,0); if( VideoInterrupts ) { return; } if( maxfd!=-1 ) { #ifndef USE_THREAD if( !SoundOff && sound!=-1 && FD_ISSET(sound,&writefd) ) { WriteSound(); continue; } #else if( !SoundOff && !SoundThreadRunning && sound!=-1 && FD_ISSET(sound,&writefd) ) { WriteSound(); continue; } #endif if( NetworkFildes!=-1 && FD_ISSET(NetworkFildes,&readfd) ) { NetworkEvent(); continue; } DoEvent(); } } #endif struct timeval tv; fd_set rfds; fd_set wfds; int maxfd; int* xfd; int n; int i; int morex; int connection; connection=ConnectionNumber(TheDisplay); for( ;; ) { // // Prepare select // tv.tv_sec=0; tv.tv_usec=0; FD_ZERO(&rfds); FD_ZERO(&wfds); maxfd=0; // // X11 how many events already in que // xfd=NULL; morex=XQLength(TheDisplay); if( !morex ) { // // X11 connections number // maxfd=connection; FD_SET(connection,&rfds); // // Get all X11 internal connections // if( !XInternalConnectionNumbers(TheDisplay,&xfd,&n) ) { DebugLevel0(__FUNCTION__": out of memory\n"); abort(); } for( i=n; i--; ) { FD_SET(xfd[i],&rfds); if( xfd[i]>maxfd ) { maxfd=xfd[i]; } } } // // Network // if( NetworkFildes!=-1 ) { if( NetworkFildes>maxfd ) { maxfd=NetworkFildes; } FD_SET(NetworkFildes,&rfds); } // // Sound // if( !SoundOff && !SoundThreadRunning ) { if( SoundFildes>maxfd ) { maxfd=SoundFildes; } FD_SET(SoundFildes,&wfds); } maxfd=select(maxfd+1,&rfds,&wfds,NULL,morex ? &tv : NULL); // // X11 // if( maxfd>0 ) { if( !morex ) { for( i=n; i--; ) { if( FD_ISSET(xfd[i],&rfds) ) { XProcessInternalConnection(TheDisplay,xfd[i]); } } XFree(xfd); if( FD_ISSET(connection,&rfds) ) { XEventsQueued(TheDisplay,QueuedAfterReading); } morex=XQLength(TheDisplay); } } if( morex ) { // handle new + *OLD* x11 events DoEvent(); } if( maxfd>0 ) { // // Network // if( NetworkFildes!=-1 && FD_ISSET(NetworkFildes,&rfds) ) { NetworkEvent(); } // // Network in sync and time for frame over: return // if( !morex && NetworkInSync && VideoInterrupts ) { return; } // // Sound // if( !SoundOff && !SoundThreadRunning && FD_ISSET(SoundFildes,&wfds) ) { WriteSound(); } } // // Network in sync and time for frame over: return // if( !morex && NetworkInSync && VideoInterrupts ) { return; } } }