NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/45791: libcurses - getnstr erase character weirdness



>Number:         45791
>Category:       lib
>Synopsis:       libcurses - getnstr erase character weirdness
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jan 06 15:05:00 +0000 2012
>Originator:     Nat Sloss
>Release:        NetBSD 5.0.1
>Organization:
>Environment:
NetBSD beast 5.0.1 NetBSD 5.0.1 (BEAST) #94: Thu Jan  5 04:19:56 EST 2012  
build@beast:/home/build/NetBSD-5.0.1_source_tree/usr/src/sys/arch/i386/compile/BEAST
 i386

>Description:
Functions getnstr and similar display the erase character backspace incorrectly 
from a text terminal.

On NetBSD 5.0.1 backspace moves forward, on current 5.99.58 it displays a ^ not 
a circumflex but an up arrow kind of symbol.

Tabs also cannot be deleted.
>How-To-Repeat:
Write a function that uses getnstr for instance:

#include <stdio.h>
#include <curses.h>

int main() {
    char buff[10]
    initscr();
    mvprintw( 24, 0, "Sample prompt:" );
    fflush( stdout );
    refresh();

    fflush( stdin );
    getnstr( buff, 5 );

    endwin();

    return 0;
}

Compile the example above.

Input a character and hit backspace and you will see the weird behavior.  Also 
entering a character then pressing tab and then hit backspace.  You will notice 
that you cant delete the character the backspace only goes back so far.

Then try "Control-H" repeatedly from a text terminal and you will be able to 
delete the prompt.






>Fix:
I patched get str.c adding a new variables xpos and asciimin.

xpos contains the current x position for inputted characters.

asciimin is the value of ascii 'space'.

This patch also displays tabs and less than asciimin characters as single 
spaces to make it easier to delete them.  It fixes the backspace and 
"Control-H" anomalies for wscons, konsole and xterm.

--- getstr.c.orig       2007-05-29 01:01:55.000000000 +1000
+++ getstr.c    2012-01-03 04:17:46.000000000 +1100
@@ -160,13 +160,14 @@
 int
 __wgetnstr(WINDOW *win, char *str, int n)
 {
-       char *ostr, ec, kc;
-       int c, oldx, remain;
+       char *ostr, ec, kc, asciimin;
+       int c, oldx, xpos, remain;

        ostr = str;
        ec = erasechar();
        kc = killchar();
-       oldx = win->curx;
+       asciimin = 0x20;
+       oldx = xpos = win->curx;
        _DIAGASSERT(n == -1 || n > 1);
        remain = n - 1;

@@ -182,17 +183,25 @@
                        *str = '\0';
                        if (str != ostr) {
                                if ((char) c == ec) {
-                                       mvwaddch(win, win->cury, win->curx,
+                                       mvwaddch(win, win->cury, xpos,
                                            ' ');
-                                       wmove(win, win->cury, win->curx - 1);
+                                       if (xpos > oldx)
+                                           mvwaddch(win, win->cury, xpos - 1,
+                                               ' ');
+                                       if (win->curx > xpos - 1)
+                                           wmove(win, win->cury, xpos - 1);
+
+                                       xpos--;
                                }
                                if (c == KEY_BACKSPACE || c == KEY_LEFT) {
                                        /* getch() displays the key sequence */
-                                       mvwaddch(win, win->cury, win->curx - 1,
-                                           ' ');
-                                       mvwaddch(win, win->cury, win->curx - 2,
+                                       mvwaddch(win, win->cury, win->curx,
                                            ' ');
-                                       wmove(win, win->cury, win->curx - 1);
+                                       mvwaddch(win, win->cury, win->curx - 1,
+                                           ' ');
+                                       if (win->curx > xpos)
+                                           wmove(win, win->cury, xpos - 1);
+                                       xpos--;
                                }
                                str--;
                                if (n != -1) {
@@ -200,11 +209,13 @@
                                        remain++;
                                }
                        } else {        /* str == ostr */
-                               if (c == KEY_BACKSPACE || c == KEY_LEFT)
+                               if (c == ec || c == KEY_BACKSPACE || c == 
KEY_LEFT)
                                        /* getch() displays the other keys */
-                                       mvwaddch(win, win->cury, win->curx - 1,
-                                           ' ');
+                                       if (win->curx > oldx)
+                                           mvwaddch(win, win->cury,
+                                               win->curx - 1, ' ');
                                wmove(win, win->cury, oldx);
+                               xpos = oldx;
                        }
                } else if (c == kc) {
                        *str = '\0';
@@ -229,15 +240,21 @@
                        wmove(win, win->cury, oldx);
                } else if (c >= KEY_MIN && c <= KEY_MAX) {
                        /* getch() displays these characters */
-                       mvwaddch(win, win->cury, win->curx - 1, ' ');
-                       wmove(win, win->cury, win->curx - 1);
+                       mvwaddch(win, win->cury, xpos, ' ');
+                       wmove(win, win->cury, xpos);
                } else {
+                       if ((c < asciimin) && remain) {
+                               mvwaddch(win, win->cury, xpos, ' ');
+                               wmove(win, win->cury, xpos + 1);
+                       }
+
                        if (remain) {
                                str++;
+                               xpos++;
                                remain--;
                        } else {
-                               mvwaddch(win, win->cury, win->curx - 1, ' ');
-                               wmove(win, win->cury, win->curx - 1);
+                               mvwaddch(win, win->cury, xpos, ' ');
+                               wmove(win, win->cury, xpos);
                        }
                }
        }


The only key it has trouble with is the escape key it moves forward a single 
space as I made it do but it erases the previous character I think it's a getch 
issue and did not want to change it.

I hope my patch is appropriate and that it helps.

Regards,

Nat.



Home | Main Index | Thread Index | Old Index