예제 #1
0
파일: winmain.c 프로젝트: OPSF/uClinux
void
MwSelect(void)
{
	fd_set	rfds;
	fd_set	wfds;
	fd_set	efds;
	int 	fd;
	int 	e;
	int	setsize = 0;
	UINT	timeout;
	struct timeval to;

	/* perform pre-select duties, if any*/
	if(scrdev.PreSelect)
		scrdev.PreSelect(&scrdev);

	/* Set up the FDs for use in the main select(): */
	FD_ZERO(&rfds);
	FD_ZERO(&wfds);
	FD_ZERO(&efds);

	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;
	}

	/* handle registered file descriptors */
	fd = userregfd_head;
	while (fd != -1) {
		if (userregfd[fd].read) FD_SET(fd, &rfds);
		if (userregfd[fd].write) FD_SET(fd, &wfds);
		if (userregfd[fd].except) FD_SET(fd, &efds);
		if(fd > setsize) setsize = fd;
		fd = userregfd[fd].next;
	}

	++setsize;

	/* Set up the timeout for the main select().  If
	 * the mouse is captured we're probably moving a window,
	 * so poll quickly to allow other windows to repaint while
	 * checking for more event input.
	 */
	if(dragwp)
		timeout = to.tv_sec = to.tv_usec = 0L;
	else {
		timeout = MwGetNextTimeoutValue();	/* returns ms*/
#if ANIMATEPALETTE
		if(fade < 100)
			timeout = 40;
#endif
if (!timeout) timeout = 10;	/* temp kluge required for mdemo to run ok*/
#if MW_FEATURE_TIMERS
		GdGetNextTimeout(&to, timeout);
#else /* if ! MW_FEATURE_TIMERS */
		to.tv_sec = timeout / 1000;
		to.tv_usec = (timeout % 1000) * 1000;
#endif /* ! MW_FEATURE_TIMERS */
	}

	/* Wait for some input on any of the fds in the set or a timeout: */
	if((e = select(setsize, &rfds, &wfds, &efds, &to)) > 0) {
		
		/* If data is present on the mouse fd, service it: */
		if(mouse_fd >= 0 && FD_ISSET(mouse_fd, &rfds))
			while(MwCheckMouseEvent())
				continue;

		/* If data is present on the keyboard fd, service it: */
		if(keyb_fd >= 0 && FD_ISSET(keyb_fd, &rfds))
			while(MwCheckKeyboardEvent())
				continue;

		/* If registered descriptor, handle it */
		fd = userregfd_head;
		while (fd != -1) {
			if (userregfd[fd].read && FD_ISSET(fd, &rfds))
				PostMessage(userregfd[fd].read, WM_FDINPUT, fd, 0);
			if (userregfd[fd].write && FD_ISSET(fd, &wfds))
				PostMessage(userregfd[fd].write, WM_FDOUTPUT, fd, 0);
			if (userregfd[fd].except && FD_ISSET(fd, &efds))
				PostMessage(userregfd[fd].except, WM_FDEXCEPT, fd, 0);
			fd = userregfd[fd].next;
		}
	} 
	else if(e == 0) {
		/* timeout has occured*/
#if MW_FEATURE_TIMERS
		if(GdTimeout() == FALSE)
			return;
#endif /* MW_FEATURE_TIMERS */
#if ANIMATEPALETTE
		if(fade <= 100) {
			setfadelevel(&scrdev, fade);
			fade += 5;
		}
#endif
		MwHandleTimers();
	} else
		if(errno != EINTR)
			EPRINTF("Select() call in main failed\n");
}
예제 #2
0
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, &regfdset))
			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, &regfdset)  ||  !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");
}
예제 #3
0
void
GsSelect (GR_TIMEOUT timeout)
{
	struct MW_UID_MESSAGE m;
	long uid_timeout;
	GR_EVENT_GENERAL *gp;
	int rc;
#if MW_FEATURE_TIMERS
	struct timeval tout;
#endif

	/* perform pre-select duties, if any*/
	if (scrdev.PreSelect)
		scrdev.PreSelect(&scrdev);

	/* let's make sure that the type is invalid */
	m.type = MV_UID_INVALID;

	/* wait up for events */
	if (timeout == (GR_TIMEOUT) -1)
		uid_timeout = 0;
	else {
#if MW_FEATURE_TIMERS
		if (GdGetNextTimeout(&tout, timeout))
			uid_timeout = tout.tv_sec * 1000 + (tout.tv_usec + 500) / 1000;
		else
#endif
		{
			if (timeout == 0)
				uid_timeout = (unsigned long) -1;
			else
				uid_timeout = timeout;
		}
	}
	rc = uid_read_message (&m, uid_timeout);

	/* return if timed-out or something went wrong */
	if (rc < 0)
	{
		if (errno != ETIMEDOUT)
				EPRINTF(" rc= %d, errno=%d\n", rc, errno);
		else
		{
#if MW_FEATURE_TIMERS
			/* check for timer timeouts and service if found*/
			if (GdTimeout())
#else
			if (timeout != 0)
#endif
			{
				/*
		 		 * Timeout has occured. Currently return a timeout event
		 		 * regardless of whether client has selected for it.
				 */
				if ((gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient)) != NULL)
					gp->type = GR_EVENT_TYPE_TIMEOUT;
			}
		}
		return;
	}

	/* let's pass the event up to Microwindows */
	switch (m.type) {
	case MV_UID_REL_POS:	/* Mouse or Touch Screen event */
	case MV_UID_ABS_POS:
		m_mou = m;
		while (GsCheckMouseEvent())
			continue;
		break;
	case MV_UID_KBD:	/* KBD event */
		m_kbd = m;
		GsCheckKeyboardEvent ();
		break;
	case MV_UID_TIMER:	/* Microwindows does nothing with these.. */
	case MV_UID_INVALID:
	default:
	        break;
	}
}
예제 #4
0
void 
GsSelect(GR_TIMEOUT timeout)
{
	int numevents = 0;
	GR_TIMEOUT waittime = 0;
	GR_EVENT_GENERAL *gp;

#if MW_FEATURE_TIMERS
	struct timeval tout;
	if (timeout != (GR_TIMEOUT)-1L)
		GdGetNextTimeout(&tout, timeout);	/* set initial mainloop timeout*/
#endif
#if EMSCRIPTEN
	if (timeout == (GR_TIMEOUT)-1L)
		timeout = 1;				/* need to give up some CPU in GdDelay even on poll*/
#endif
	/* input gathering loop */
	while (1)
	{
		/* perform single update of aggregate screen update region*/
		if(scrdev.PreSelect)
			scrdev.PreSelect(&scrdev);

		/* poll for mouse data and service if found*/
		while (GsCheckMouseEvent())
			if (++numevents > 10)
				break;				/* don't handle too many events at one shot*/

		/* poll for keyboard data and service if found*/
		while (GsCheckKeyboardEvent())
			if (++numevents > 10)
				break;				/* don't handle too many events at one shot*/
		
		/* did we handle any input or were we just polling?*/
		if (numevents || timeout == (GR_TIMEOUT)-1L)
			return;					/* yes - return without sleeping*/

		/* give up time-slice & sleep for a bit */
		GdDelay(WAITTIME);
		waittime += WAITTIME; 

		/* have we timed out? */
		if (waittime >= timeout)
		{
#if MW_FEATURE_TIMERS
			/* check for timer timeouts and service if found*/
			if (GdTimeout())
#else
			/* special case: polling when timeout == 0 -- don't send timeout event */
			if (timeout != 0)
#endif
			{
				/* Timeout has occured.  
				 * Currently return a timeout event regardless of whether client 
				 * has selected for it.
				 */
				if ((gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient)) != NULL)
					gp->type = GR_EVENT_TYPE_TIMEOUT;
			}
			return;
		}
	}
}
예제 #5
0
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, &regfdset))
			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, &regfdset)  ||  !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");
}