The halfdelay() input option is broken in PDCurses -- wgetch() is always
either fully blocking or nonblocking. The problem is in pdcurses/getch.c,
in the wgetch() function, after a low-level keyboard read is attempted:

        /* keyboard read leaves value in "key", then: */

        if (w->_nodelay)
        {
                /*
                 * if nodelay and no char, return ERR
                 */
                if (key == -1)
                        return( ERR );
                else if ( ! SP->echo ) {
                        if ( ! (w->_flags & _PAD) ) {
                                if ( is_wintouched(w) )
                                        wrefresh(w);
        }
        else
        {
                if (SP->delaytenths)
                {
                        if (waitingtenths == 0 && key == (-1))
                                return(ERR);
                        if (key == (-1))
                        {
                                waitingtenths--;
                                napms(10);
                                continue;
                        }
                }
        }

The trouble is that the low-level keyboard read function itself depends on
the status of w->_nodelay. When it's true, obviously the "SP->delaytenths"
section will never be reached; but also, when false, the return value in
"key" will never be -1, so although the delay section is reached, it has
no function. The remedy is simply to swap around the conditions: test
SP->delaytenths first, then w->_nodelay. Note that, for halfdelay() to
work then, the window must first be set to nodelay(); since this depends
on a specific window, while halfdelay() is global, I haven't included this
in the patch.

That fixed, there's another problem: nocbreak() does not reset the value
set by halfdelay(), as it's supposed to. This is tricky, because if you
look at nocbreak() in pdcurses/inopts.c, it appears to be resetting it;
but this function is only used in the XCurses port. For the rest,
nocbreak() is defined in curses.h:

 # define nocbreak()             (SP->cbreak = FALSE)

I just changed this to:

 # define nocbreak()             (SP->cbreak = FALSE, SP->delaytenths = 0)

Finally, the pause routine napms() works in Win32 and OS/2 (though the
pause seems overlong in OS/2), but not in DOS, with DJGPP or Turbo C++;
on those platforms it returns immediately. In the case of DJGPP, I found
the explanation in the info page for usleep(), the function PDCurses uses
to implement napms() there:

   Note that, since `usleep' calls `clock' internally, and the latter has
   a 55-msec granularity, any argument less than 55msec will result in a
   pause of random length between 0 and 55 msec. Any argument less than
   11msec (more precisely, less than 11264 microseconds), will always
   result in zero-length pause (because `clock' multiplies the timer count
   by 5).

PDCurses is calling usleep() with a 10ms parameter, so there's no pause. I
haven't attempted to fix this yet. And I haven't yet figured out why the
Turbo C++ routine (based on delay() from TC's dos.h) isn't working.

Patches for the first two problems attached.

-- 
William McBrine <[EMAIL PROTECTED]>
*** pdcurses/getch.c.old        Wed Jan 10 03:27:01 2001
--- pdcurses/getch.c    Sun Mar  3 06:44:06 2002
***************
*** 259,289 ****
                        key = (-1);
  #endif
  
!               if (w->_nodelay)
                {
!                       /*
!                        * if nodelay and no char, return ERR
!                        */
!                       if (key == -1)
!                               return( ERR );
!                       else if ( ! SP->echo ) {
!                               if ( ! (w->_flags & _PAD) ) {
!                                       if ( is_wintouched(w) )
!                                               wrefresh(w);
!                               }
                        }
                }
                else
                {
!                       if (SP->delaytenths)
                        {
!                               if (waitingtenths == 0 && key == (-1))
!                                       return(ERR);
!                               if (key == (-1))
!                               {
!                                       waitingtenths--;
!                                       napms(10);
!                                       continue;
                                }
                        }
                }
--- 259,289 ----
                        key = (-1);
  #endif
  
!               if (SP->delaytenths)
                {
!                       if (waitingtenths == 0 && key == (-1))
!                               return(ERR);
!                       if (key == (-1))
!                       {
!                               waitingtenths--;
!                               napms(10);
!                               continue;
                        }
                }
                else
                {
!                       if (w->_nodelay)
                        {
!                               /*
!                                * if nodelay and no char, return ERR
!                                */
!                               if (key == -1)
!                                       return( ERR );
!                               else if ( ! SP->echo ) {
!                                       if ( ! (w->_flags & _PAD) ) {
!                                               if ( is_wintouched(w) )
!                                                       wrefresh(w);
!                                       }
                                }
                        }
                }
*** curses.h.old        Tue Oct 16 07:03:15 2001
--- curses.h    Sun Mar  3 06:47:05 2002
***************
*** 2070,2076 ****
  #define wstandout(w)            wattrset(w, A_STANDOUT)
  
  #if !defined(UNIX) && !defined(XCURSES)
! # define nocbreak()             (SP->cbreak = FALSE)
  # define cbreak()               (SP->cbreak = TRUE)
  # define nocrmode()             (SP->cbreak = FALSE)
  # define crmode()               (SP->cbreak = TRUE)
--- 2070,2076 ----
  #define wstandout(w)            wattrset(w, A_STANDOUT)
  
  #if !defined(UNIX) && !defined(XCURSES)
! # define nocbreak()             (SP->cbreak = FALSE, SP->delaytenths = 0)
  # define cbreak()               (SP->cbreak = TRUE)
  # define nocrmode()             (SP->cbreak = FALSE)
  # define crmode()               (SP->cbreak = TRUE)

Reply via email to