Subject:
implementing a polling touchscreen driver
From:
Sean Machin ####@####.####
Date:
27 Oct 2005 02:35:52 +0100
Message-Id: <43602E47.10508@yahoo.com>
Hi Greg & Others,
I'm trying to get my touchscreen hardware working with Nano-X, with some
success. I already had some code
for a Linux driver written by my predecessor, it doesn't map the
touchpad to a device
in /dev, rather it sets up an interrupt handler to set a flag when the
screen
has been pressed, then require callers to call an ioctl() to get the X,Y
coords.
My embedded distribution has Microwindows Version 0.89pre7 so that's the
version I'm using.
I made some modifications to the supplied uClinux-CLEOPATRA driver, it
seemed
fairly close to my needs. I #defined CLEOPATRA to be 1 in
nanox/srvmain.c so that the polling in my mouse
driver is called instead of the GsSelect that does a select on the mouse
file descriptor,
see code below.
When I start nano-X I do have the mouse pointer tracking the touchscreen
presses correctly.
The problem is that after adding that touchpad driver, client programs
do not seem to display
at all. I cannot see how any window events are processed by the
polling GsSelect?
There seems to be a chunk of functionality in the true select based
GsSelect function
for extra event processing.
Can anyone advise on the correct way to get a polling touchscreen driver
to work, or
should I go back and modify my driver to map the touchscreen to an entry
in /dev
and go with the select() based reading? Are there any real advantages
to having the driver
work from /dev instead of being polled?
Thanks,
Sean
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
#elif MSDOS | _MINIX | CLEOPATRA
void
GsSelect(GR_TIMEOUT timeout)
{
/* If mouse data present, service it*/
if(mousedev.Poll())
while(GsCheckMouseEvent())
continue;
/* If keyboard data present, service it*/
if(kbddev.Poll())
while(GsCheckKeyboardEvent())
continue;
}
#elif UNIX && defined(HAVESELECT) && !CLEOPATRA
void
GsSelect(GR_TIMEOUT timeout)
{
fd_set rfds;
int e;
int setsize = 0;
struct timeval tout, *to;
/* 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);
// in our case mouse_fd = 1, keyb_fd = -2
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 NONETWORK
/* handle registered input file descriptors*/
if (regfd != -1) {
FD_SET(regfd, &rfds);
if (regfd > setsize) setsize = regfd;
}
#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(GdGetNextTimeout(&tout, timeout) == TRUE)
to = &tout;
else to = NULL;
/* Wait for some input on any of the fds in the set or a timeout: */
// select returns 0 if timeout, -ve for error, else no. descriptors
changed
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))
while(GsCheckKeyboardEvent())
continue;
#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 /* 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) {
printf("select got timeout\n");
#if NONETWORK
/*
* Timeout has occured. Currently return
* a timeout event regardless of whether
* client has selected for it.
*/
if(GdTimeout() == TRUE) {
GR_EVENT_GENERAL * gp;
gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient);
if(gp)
gp->type = GR_EVENT_TYPE_TIMEOUT;
}
#else /* not NONETWORK */
GdTimeout();
#endif /* NONETWORK */
} else
if(errno != EINTR)
EPRINTF("Select() call in main failed\n");
}
#endif /* UNIX && defined(HAVESELECT)*/