/* 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);
}
Exemple #2
0
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);
}
Exemple #3
0
/**
**	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;
	}
    }
}