[comp.unix.programmer] How can I detect waiting characters in a curses application ?

samc@ntpdvp1.UUCP (Sam Christie) (12/06/90)

Would some kind sole tell me the name of the curses function
which checks for input without blocking ? If none exists, then please
read on and help me create one.

I am using Interactive's 386/IX 2.0.2 on a Dell 386.  My application
uses curses for a terminal based user interface.  Using the application,
the user may request that the program perform an operation which takes
considerable time.  Users, being prone to errors as they are, may wish
to abort the operation by pressing the "stop-doing-that,I-didnt-mean-that"
key.  The code is in a loop and could easily test for such a user request.

Something like :

while( !done) {
	/* do a bunch of stuff */

	if ( istypeahead( stdscr)) {   /* <==== what should this say */
		if ( KEY_F(8) == getch( )) break;
	}
}

I wrote an istypeahead function as:

istypeahead()
{
	int i, j, c;

	i =  fcntl( 0, F_GETFL );
	fcntl( 0, F_SETFL, i | O_NDELAY );
	c = getchar();                         /* didn't use getch() here because */
											  I don't know how to ungetch() */
	fcntl( 0, F_SETFL, i & ( ~O_NDELAY ));
	if( EOF == c) return( 0);
	ungetc( c, stdin);
	return( 1);
}

This seems to detect typeahead ok, but curses seems to be lost regarding 
the keys.  I suspect it has something to do with curses' internal buffering.
(I doubt curses uses getchar() or the buffers associated with fopen() )

Any hints ?

-- 
Sam Christie                            Standard Disclaimer Applies
Northern Telecom - DMS-10
Research Triangle Park, NC
EMAIL ...!uunet!mcnc!rti!ntpdvp1!samc                  919/992-3917

hagins@gamecock.rtp.dg.com (Jody Hagins) (12/07/90)

In article <677@ntpdvp1.UUCP>, samc@ntpdvp1.UUCP (Sam Christie) writes:
|> Would some kind sole tell me the name of the curses function
|> which checks for input without blocking ? If none exists, then please
|> read on and help me create one.



From the curses manpages...


nodelay(win, bf)
WINDOW	*win;
bool	bf;

When set, this option causes wgetch() to be a non-blocking call.
If no input is ready, wgetch() returns ERR.  If disabled, wgetch()
hangs until a key is pressed.



-- 

Jody Hagins             
hagins@gamecock.rtp.dg.com    
Data General Corp.      
62 Alexander Dr.        
RTP, N.C.  27709        
(919) 248-6035          

carroll@cs.uiuc.edu (Alan M. Carroll) (12/07/90)

In article <677@ntpdvp1.UUCP>, samc@ntpdvp1.UUCP (Sam Christie) writes:
> Would some kind sole tell me the name of the curses function
> which checks for input without blocking ? If none exists, then please
> read on and help me create one.
> 

Try this. (test by compiling and running. Type and hit return. Works
for me on ISC 2.0.2).

#include <stropts.h>
#include <poll.h>

int istypeahead(fd) int fd;		/* file descriptor */
{
  int n;
  struct pollfd p_fd[1];

  p_fd->fd = fd;
  p_fd->events = POLLIN;

  n = poll(p_fd, 1, 0);
  return n;
}

main()
{
  while (1)
    {
      if (istypeahead(0)) printf("Input waiting\n");
      else printf("No input\n");
      sleep(1);
    }
}

-- 
Alan M. Carroll                "It's psychosomatic. You need a lobotomy.
Epoch Development Team          I'll get a saw."
CS Grad / U of Ill @ Urbana    ...{ucbvax,pur-ee,convex}!cs.uiuc.edu!carroll

boutell@freezer.it.udel.edu (Tom Boutell) (12/07/90)

In article <1990Dec6.234823.2763@ux1.cso.uiuc.edu> carroll@cs.uiuc.edu (Alan M. Carroll) writes:
>Try this. (test by compiling and running. Type and hit return. Works
>for me on ISC 2.0.2).
>
>#include <stropts.h>
>#include <poll.h>
>
>int istypeahead(fd) int fd;		/* file descriptor */
... Lots of good code ...
>}
>
>main()
>{
>  while (1)
>    {
>      if (istypeahead(0)) printf("Input waiting\n");
       Not so good. Or rather, not so portable. I strongly suggets you do
       this instead:
       if (istypeahead(fileno(stdin))) printf("Input waiting\n");
       This is very widely compatible; I've just been through this
       particular mill. Trust me- I know. (-: Of course, it's most
       sensible to save fileno(stdin) to an int and just use
       istypeahead(stdinfd) where stdinfd is the int in question.
>      else printf("No input\n");
>      sleep(1);
>    }
>}

Otherwise very good stuff.


-- 
THE TECHNOLOGY HOUSE: An idea whose time has come!
My girlfriend is a pseudo- aardvark. She is quite insistent on this point.
And remember- when all else fails- and no one else can help-
boutell@freezer.it.udel.edu

jmaynard@thesis1.hsch.utexas.edu (Jay Maynard) (12/11/90)

In article <1990Dec6.201715.5139@dg-rtp.dg.com> hagins@gamecock.rtp.dg.com (Jody Hagins) writes:
>In article <677@ntpdvp1.UUCP>, samc@ntpdvp1.UUCP (Sam Christie) writes:
>|> Would some kind sole tell me the name of the curses function
>|> which checks for input without blocking ? If none exists, then please
>|> read on and help me create one.
>nodelay(win, bf)
>WINDOW	*win;
>bool	bf;
>When set, this option causes wgetch() to be a non-blocking call.
>If no input is ready, wgetch() returns ERR.  If disabled, wgetch()
>hangs until a key is pressed.

There's only one problem with this: it breaks curses' handling of special
keys that return multiple characters, such as the arrow keys on a VT100.

I'm looking for an answer to this one, too; I'm trying to add arrow key
support to dte (a WordStar-compatible editor), and need this kind of
functionality to make dte's screen handling work.
-- 
Jay Maynard, EMT-P, K5ZC, PP-ASEL | Never ascribe to malice that which can
jmaynard@thesis1.hsch.utexas.edu  | adequately be explained by stupidity.
  "...flames are a specific art form of Usenet..." -- Gregory C. Woodbury

staceyc@sco.COM (Stacey Campbell) (12/15/90)

In article <677@ntpdvp1.UUCP> samc@ntpdvp1.UUCP (Sam Christie) writes:
>I am using Interactive's 386/IX 2.0.2 on a Dell 386.
>
>	fcntl( 0, F_SETFL, i | O_NDELAY );

See the curses(3X) man page for the routine nodelay().

>	c = getchar();    /* didn't use getch() here because */
>                         /* I don't know how to ungetch() */

Your version of curses should support ungetch(), so use getch() otherwise,
as you have correctly decided, curses internal character buffering
will get confused.  It should be docced in the Input section of the
curses manual page.