diff options
| author | blymn <blymn@NetBSD.org> | 2007-05-28 15:01:53 +0000 |
|---|---|---|
| committer | blymn <blymn@NetBSD.org> | 2007-05-28 15:01:53 +0000 |
| commit | e124de36d8a3bb2fd90b77ec25eb7736f29ee44d (patch) | |
| tree | 0dac708fd51eee66b5194f8e69d6fe165e953031 /lib/libcurses | |
| parent | 599840187d9b53fe3353daa7f2892b387a1c2f29 (diff) | |
Merge in wide curses code done as a Summer of Code project by
Ruibiao Qiu.
Diffstat (limited to 'lib/libcurses')
54 files changed, 3300 insertions, 995 deletions
diff --git a/lib/libcurses/EXAMPLES/Makefile b/lib/libcurses/EXAMPLES/Makefile index 7eb7912fc2b..b3759fdc514 100644 --- a/lib/libcurses/EXAMPLES/Makefile +++ b/lib/libcurses/EXAMPLES/Makefile @@ -1,5 +1,15 @@ -#$Id: Makefile,v 1.1 2007/01/21 11:38:59 blymn Exp $ +#$Id: Makefile,v 1.2 2007/05/28 15:01:58 blymn Exp $ #$Log: Makefile,v $ +#Revision 1.2 2007/05/28 15:01:58 blymn +#Merge in wide curses code done as a Summer of Code project by +#Ruibiao Qiu. +# +#Revision 1.1.2.2 2007/01/31 10:08:47 blymn +#Fix up build errors. +# +#Revision 1.1.2.1 2007/01/21 12:05:54 blymn +#Merge wide curses. +# #Revision 1.1 2007/01/21 11:38:59 blymn #Wide curses merge # @@ -26,10 +36,10 @@ CFLAGS+= -g all: wcview nwview ccview tcview ncview ex1 wcview: view.c - gcc -DHAVE_WCHAR -o wcview view.c -I.. $(CFLAGS) -lwcurses -Wl,-rpath,.. -L.. + gcc -DHAVE_WCHAR -o wcview view.c -I.. $(CFLAGS) -lcurses -Wl,-rpath,.. -L.. nwview: view.c - gcc -DHAVE_WCHAR -o nwview view.c -DNCURSES -I/usr/pkg/include $(CFLAGS) -lncursesw -Wl,-rpath,/usr/pkg/lib -L/usr/pkg/lib + gcc -DHAVE_WCHAR -o nwview view.c -DNCURSES -I/usr/pkg/include $(CFLAGS) -lcurses -Wl,-rpath,/usr/pkg/lib -L/usr/pkg/lib ccview: view.c gcc -o ccview view.c -I.. $(CFLAGS) -lcurses -Wl,-rpath,.. -L.. @@ -41,3 +51,4 @@ ncview: view.c gcc -o ncview view.c -I/usr/pkg/include -DNCURSES -L/usr/pkg/lib -Wl,-rpath,/usr/pkg/lib $(CFLAGS) -lncurses ex1: ex1.c + gcc -DHAVE_WCHAR -o ex1 ex1.c -I.. $(CFLAGS) -lcurses -Wl,-rpath,.. -L.. diff --git a/lib/libcurses/EXAMPLES/ex1.c b/lib/libcurses/EXAMPLES/ex1.c index e8d743503a3..e71ed33d023 100644 --- a/lib/libcurses/EXAMPLES/ex1.c +++ b/lib/libcurses/EXAMPLES/ex1.c @@ -1,4 +1,4 @@ -/* $NetBSD: ex1.c,v 1.4 2003/08/07 16:44:26 agc Exp $ */ +/* $NetBSD: ex1.c,v 1.5 2007/05/28 15:01:58 blymn Exp $ */ /* * Copyright (c) 1992, 1993 @@ -42,28 +42,92 @@ static char sccsid[] = "@(#)ex1.c 8.1 (Berkeley) 6/4/93"; #include <sys/types.h> #include <curses.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <signal.h> +#include <locale.h> +#include <assert.h> +#define YSIZE 4 +#define XSIZE 30 -#define YSIZE 10 -#define XSIZE 20 - -int quit(); +void quit( int ); main() { - int i, j, c; + int i, j, c, n = 0, ac = 0; size_t len; char id[100]; FILE *fp; char *s; + cchar_t cc, ncc, cstr[ 128 ], icc, icstr[ 128 ], bcc; + int wc_on = 0, wgc_on = 0; + char mbs[] = "大"; + char mbstr[] = "大学之道,在明明德,在亲民,在止于至善。 (Liji)"; + wchar_t wstr[ 128 ], owstr[ 4 ], gwstr[ 128 ], iwstr[ 128 ]; + int wslen = 0; + wint_t wc; + char nostr[ 128 ]; + attr_t al[ 15 ] = { WA_BLINK, + WA_BOLD, + WA_DIM, + WA_LOW, + WA_TOP, + WA_INVIS, + WA_HORIZONTAL, + WA_VERTICAL, + WA_LEFT, + WA_RIGHT, + WA_PROTECT, + WA_REVERSE, + WA_STANDOUT, + WA_UNDERLINE }; + + fprintf( stderr, "Current locale: %s\n", setlocale(LC_ALL, "")); + if (( wslen = mbstowcs( &cc.vals[ 0 ], mbs, strlen( mbs ))) < 0 ) { + fprintf( stderr, "mbstowcs() failed\n" ); + return -1; + } + fprintf( stderr, "WC string length: %d\n", wslen ); + fprintf( stderr, "WC width: %d\n", wcwidth( cc.vals[ 0 ])); + cc.elements = ncc.elements = 8; + cc.attributes = ncc.attributes = 0; + ncc.vals[ 0 ] = 0xda00; + cc.vals[ 1 ] = ncc.vals[ 1 ] = 0xda01; + cc.vals[ 2 ] = ncc.vals[ 2 ] = 0xda02; + cc.vals[ 3 ] = ncc.vals[ 3 ] = 0xda03; + cc.vals[ 4 ] = ncc.vals[ 4 ] = 0xda04; + cc.vals[ 5 ] = ncc.vals[ 5 ] = 0xda05; + cc.vals[ 6 ] = ncc.vals[ 6 ] = 0xda06; + cc.vals[ 7 ] = ncc.vals[ 7 ] = 0xda07; + + if (( wslen = mbstowcs( wstr, mbstr, strlen( mbstr ))) < 0 ) { + fprintf( stderr, "mbstowcs() failed\n" ); + return -1; + } + + for ( i = 0; i < wslen; i++ ) { + cstr[ i ].vals[ 0 ] = wstr[ i ]; + } + cstr[ wslen ].vals[ 0 ] = 0; + + bcc.elements = 8; + bcc.attributes = 0; + bcc.vals[ 0 ] = L'_'; + bcc.vals[ 1 ] = 0xda01; + bcc.vals[ 2 ] = 0xda02; + bcc.vals[ 3 ] = 0xda03; + bcc.vals[ 4 ] = 0xda04; + bcc.vals[ 5 ] = 0xda05; + bcc.vals[ 6 ] = 0xda06; + bcc.vals[ 7 ] = 0xda07; initscr(); /* Always call initscr() first */ signal(SIGINT, quit); /* Make sure wou have a 'cleanup' fn */ crmode(); /* We want cbreak mode */ noecho(); /* We want to have control of chars */ delwin(stdscr); /* Create our own stdscr */ - stdscr = newwin(YSIZE, XSIZE, 10, 35); + stdscr = newwin(YSIZE, XSIZE, 1, 1); flushok(stdscr, TRUE); /* Enable flushing of stdout */ scrollok(stdscr, TRUE); /* Enable scrolling */ erase(); /* Initially, clear the screen */ @@ -71,30 +135,201 @@ main() standout(); move(0,0); while (1) { - c = getchar(); - switch(c) { - case 'q': /* Quit on 'q' */ - quit(); - break; - case 's': /* Go into standout mode on 's' */ - standout(); - break; - case 'e': /* Exit standout mode on 'e' */ - standend(); - break; - case 'r': /* Force a refresh on 'r' */ - wrefresh(curscr); - break; - default: /* By default output the character */ - addch(c); - refresh(); - } + if ( !wgc_on ) { + c = getchar(); + switch(c) { + case 'q': /* Quit on 'q' */ + quit( 0 ); + break; + case 'p': + keypad( stdscr, TRUE ); + break; + case 'P': + keypad( stdscr, FALSE ); + break; + case 'g': + wgc_on = 1; + echo(); + break; + case 'b': + get_wstr( gwstr ); + move( 1, 0 ); + addstr( "Input:" ); + addwstr( gwstr ); + refresh(); + break; + case 'h': + move( 0, 0 ); + in_wch( &icc ); + move( 1, 0 ); + add_wch( &icc ); + refresh(); + break; + case 'y': + move( 0, 0 ); + in_wchstr( icstr ); + move( 1, 0 ); + add_wchstr( icstr ); + refresh(); + break; + case 'u': + move( 0, 0 ); + inwstr( iwstr ); + move( 1, 0 ); + addwstr( iwstr ); + refresh(); + break; + case 'i': + move( 0, 0 ); + hline_set( &cc, 20 ); + move( 0, 0 ); + vline_set( &cc, 20 ); + refresh(); + break; + case 'o': + clrtobot(); + refresh(); + break; + case 's': /* Go into standout mode on 's' */ + standout(); + break; + case 'e': /* Exit standout mode on 'e' */ + standend(); + break; + case 'r': /* Force a refresh on 'r' */ + wrefresh(curscr); + break; + case 'w': /* Turn on/off add_wch() tests */ + wc_on = 1 - wc_on; + break; + case 'd': + add_wchstr(( const cchar_t *)&cstr ); + refresh(); + break; + case 'c': + addwstr(( const wchar_t *)&wstr ); + refresh(); + break; + case 'z': + move( 0, 1 ); + if ( wc_on ) + add_wch( &cc ); + else + addch( c ); + refresh(); + break; + case 'x': + move( 0, 3 ); + if ( wc_on ) + add_wch( &cc ); + else + addch( c ); + refresh(); + break; + case 'n': + add_wch( &ncc ); + refresh(); + break; + case 'm': + //border( 0, 0, 0, 0, 0, 0, 0, 0 ); + border_set( NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + refresh(); + break; + case 'j': + box_set( stdscr, &cc, &cc ); + refresh(); + break; + case 'k': + erase(); + refresh(); + break; + case '1': + move( 0, 0 ); + clrtoeol(); + refresh(); + break; + case '2': + move( 0, 0 ); + sprintf( nostr, "Orig:%x", al[ ac ]); + addstr( nostr ); + ac = ( ac + 1 ) % 16; + bcc.attributes = al[ ac ]; + bkgrnd( &bcc ); + move( 1, 0 ); + sprintf( nostr, "New:%x", al[ ac ]); + //addstr( nostr ); + insstr( nostr ); + refresh(); + break; + case 'v': + if ( wc_on ) + ins_wch( &cc ); + else + insch( c ); + refresh(); + break; + case 'f': + ins_wstr(( const wchar_t *)&wstr ); + refresh(); + break; + case 't': + for ( i = 0; i < 4; i++ ) { + owstr[ i ] = wstr[ i + 5 ]; + wstr[ i + 5 ] = i + 0xda05; + } + ins_wstr(( const wchar_t *)&wstr ); + refresh(); + for ( i = 0; i < 4; i++ ) + wstr[ i + 5 ] = owstr[ i ]; + break; + default: /* By default output the character */ + if ( wc_on ) + add_wch( &cc ); + else { + if ( c < 0x7F ) + addch( c ); + else { + addstr( keyname( c )); + } + } + refresh(); + } + } else { + get_wch( &wc ); + switch ( wc ) { + case L'w': + wgc_on = 0; + noecho(); + break; + case L'q': + quit( 0 ); + break; + case L't': + notimeout( stdscr, TRUE ); + break; + case L'T': + notimeout( stdscr, FALSE ); + break; + case L'd': + nodelay( stdscr, TRUE ); + break; + case L'D': + nodelay( stdscr, FALSE ); + break; + case L'p': + keypad( stdscr, TRUE ); + break; + case L'P': + keypad( stdscr, FALSE ); + break; + default: + break; + } + } } } - -int -quit() +void quit( int sig ) { erase(); /* Terminate by erasing the screen */ refresh(); @@ -102,9 +337,6 @@ quit() delwin(curscr); /* Return storage */ delwin(stdscr); putchar('\n'); - exit(0); + exit( sig ); } - - - diff --git a/lib/libcurses/EXAMPLES/view.c b/lib/libcurses/EXAMPLES/view.c index b0a56b75925..74df2a83d21 100644 --- a/lib/libcurses/EXAMPLES/view.c +++ b/lib/libcurses/EXAMPLES/view.c @@ -23,7 +23,7 @@ * scroll operation worked, and the refresh() code only had to do a * partial repaint. * - * $Id: view.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ + * $Id: view.c,v 1.2 2007/05/28 15:01:58 blymn Exp $ */ #include <stdlib.h> @@ -72,6 +72,7 @@ static bool try_color = FALSE; static char *fname; static CURSES_CH_T **my_lines; static CURSES_CH_T **lptr; +static unsigned num_lines; static void usage(void) { @@ -232,6 +233,7 @@ int main(int argc, char *argv[]) } /* slurp the file */ + num_lines = 0; for (lptr = &my_lines[0]; (lptr - my_lines) < MAXLINES; lptr++) { char temp[BUFSIZ], *s, *d; int col; @@ -263,6 +265,7 @@ int main(int argc, char *argv[]) #endif } *lptr = ch_dup(temp); + num_lines++; } (void) fclose(fp); length = lptr - my_lines; @@ -506,14 +509,16 @@ static void show_all(const char *tag) printw("%3ld:", (long) (lptr + i - my_lines)); clrtoeol(); if ((s = lptr[i - 1]) != 0) { - int len = ch_len(s); - if (len > shift) { + if (i < num_lines) { + int len = ch_len(s); + if (len > shift) { #ifdef HAVE_WCHAR - add_wchstr(s + shift); + add_wchstr(s + shift); #else - addchstr(s + shift); + addchstr(s + shift); #endif - } + } + } } } setscrreg(1, LINES - 1); diff --git a/lib/libcurses/Makefile b/lib/libcurses/Makefile index 80b5806b87d..3848f6553cc 100644 --- a/lib/libcurses/Makefile +++ b/lib/libcurses/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.52 2004/04/21 06:24:32 jdc Exp $ +# $NetBSD: Makefile,v 1.53 2007/05/28 15:01:53 blymn Exp $ # @(#)Makefile 8.2 (Berkeley) 1/2/94 .include <bsd.own.mk> @@ -7,6 +7,7 @@ CPPFLAGS+=#-DTFILE=\"/dev/ttyp0\" CPPFLAGS+=-I${.CURDIR} -I${NETBSDSRCDIR}/lib/libterm .if defined(DEBUG_CURSES) CFLAGS+=-g +CPPFLAGS+=-g .if defined(FULL_DEBUG) CPPFLAGS+=-DDEBUG .endif @@ -14,6 +15,7 @@ CPPFLAGS+=-DDEBUG .if defined(SMALL) CPPFLAGS+=-DSMALL .endif +COPTS+=-Wuninitialized -Wstrict-prototypes -Wmissing-prototypes LIB= curses SRCS= acs.c addbytes.c addch.c addchnstr.c addnstr.c attributes.c \ background.c bell.c border.c box.c clear.c clearok.c clrtobot.c \ @@ -43,6 +45,13 @@ CPPFLAGS+=-DCM_N -DCM_GT -DCM_B -DCM_D SRCS+= termcap.c tgoto.c tputs.c .PATH: ${NETBSDSRCDIR}/lib/libterm +.if !defined(DISABLE_WCHAR) +CPPFLAGS+=-DHAVE_WCHAR +SRCS+= cchar.c add_wch.c add_wchstr.c addwstr.c echo_wchar.c ins_wch.c \ + insstr.c ins_wstr.c get_wch.c get_wstr.c in_wch.c in_wchstr.c \ + inwstr.c +.endif + MLINKS+= curses_addch.3 addch.3 curses_addchstr.3 addchnstr.3 \ curses_addchstr.3 addchstr.3 curses_addstr.3 addnstr.3 \ curses_addstr.3 addstr.3 \ diff --git a/lib/libcurses/acs.c b/lib/libcurses/acs.c index 5e80f71036c..6118bbc6c4f 100644 --- a/lib/libcurses/acs.c +++ b/lib/libcurses/acs.c @@ -1,4 +1,4 @@ -/* $NetBSD: acs.c,v 1.12 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: acs.c,v 1.13 2007/05/28 15:01:53 blymn Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -38,13 +38,19 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: acs.c,v 1.12 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: acs.c,v 1.13 2007/05/28 15:01:53 blymn Exp $"); #endif /* not lint */ #include "curses.h" #include "curses_private.h" chtype _acs_char[NUM_ACS]; +#ifdef HAVE_WCHAR +#include <locale.h> +#include <string.h> + +cchar_t _wacs_char[ NUM_ACS ]; +#endif /* HAVE_WCHAR */ /* * __init_acs -- @@ -112,7 +118,7 @@ __init_acs(SCREEN *screen) if (screen->tc_eA != NULL) t_puts(screen->cursesi_genbuf, screen->tc_eA, 0, - __cputchar_args, screen->outfd); + __cputchar_args, screen->outfd); out: for (count=0; count < NUM_ACS; count++) @@ -127,3 +133,127 @@ _cursesi_reset_acs(SCREEN *screen) for (count=0; count < NUM_ACS; count++) _acs_char[count]= screen->acs_char[count]; } + +#ifdef HAVE_WCHAR +/* + * __init_wacs -- + * Fill in the ACS characters. The 'ac' termcap entry is a list of + * character pairs - ACS definition then terminal representation. + */ +void +__init_wacs(SCREEN *screen) +{ + int count; + char *aofac; /* Address of 'ac' */ + unsigned char acs, term; + char *lstr; + + /* Default value '+' for all ACS characters */ + for (count=0; count < NUM_ACS; count++) { + _wacs_char[ count ].vals[ 0 ] = ( wchar_t )btowc( '+' ); + _wacs_char[ count ].attributes = 0; + _wacs_char[ count ].elements = 1; + } + + /* Add the SUSv2 defaults (those that are not '+') */ + lstr = setlocale( LC_ALL, "" ); + if ((lstr != NULL) && !strcasestr( lstr, "UTF-8" )) { +#ifdef DEBUG + __CTRACE(__CTRACE_INIT, "__init_wacs: setting defaults\n" ); +#endif /* DEBUG */ + WACS_RARROW = ( wchar_t )btowc( '>' ); + WACS_LARROW = ( wchar_t )btowc( '<' ); + WACS_UARROW = ( wchar_t )btowc( '^' ); + WACS_DARROW = ( wchar_t )btowc( 'v' ); + WACS_BLOCK = ( wchar_t )btowc( '#' ); + WACS_CKBOARD = ( wchar_t )btowc( ':' ); + WACS_DEGREE = ( wchar_t )btowc( 39 ); /* ' */ + WACS_PLMINUS = ( wchar_t )btowc( '#' ); + WACS_BOARD = ( wchar_t )btowc( '#' ); + WACS_LANTERN = ( wchar_t )btowc( '#' ); + WACS_HLINE = ( wchar_t )btowc( '-' ); + WACS_S1 = ( wchar_t )btowc( '-' ); + WACS_S9 = ( wchar_t )btowc( '_' ); + WACS_VLINE = ( wchar_t )btowc( '|' ); + WACS_BULLET = ( wchar_t )btowc( 'o' ); + } else { + /* Unicode defaults */ +#ifdef DEBUG + __CTRACE(__CTRACE_INIT, + "__init_wacs: setting Unicode defaults\n" ); +#endif /* DEBUG */ + WACS_RARROW = 0x2192; + WACS_LARROW = 0x2190; + WACS_UARROW = 0x2192; + WACS_DARROW = 0x2193; + WACS_BLOCK = 0x25ae; + WACS_DIAMOND = 0x25c6; + WACS_CKBOARD = 0x2592; + WACS_DEGREE = 0x00b0; + WACS_PLMINUS = 0x00b1; + WACS_BOARD = 0x2592; + WACS_LANTERN = 0x2603; + WACS_LRCORNER = 0x2518; + WACS_URCORNER = 0x2510; + WACS_ULCORNER = 0x250c; + WACS_LLCORNER = 0x2514; + WACS_PLUS = 0x253c; + WACS_HLINE = 0x2500; + WACS_S1 = 0x23ba; + WACS_S9 = 0x23bd; + WACS_LTEE = 0x251c; + WACS_RTEE = 0x2524; + WACS_BTEE = 0x2534; + WACS_TTEE = 0x252c; + WACS_VLINE = 0x2502; + WACS_BULLET = 0x00b7; + } + + if (screen->tc_ac == NULL) { +#ifdef DEBUG + __CTRACE(__CTRACE_INIT, + "__init_wacs: no alternative characters\n" ); +#endif /* DEBUG */ + goto out; + } + + aofac = screen->tc_ac; + + while (*aofac != '\0') { + if ((acs = *aofac) == '\0') + return; + if (++aofac == '\0') + return; + if ((term = *aofac) == '\0') + return; + /* Only add characters 1 to 127 */ + if (acs < NUM_ACS) { + _wacs_char[acs].vals[ 0 ] = term; + _wacs_char[acs].attributes |= WA_ALTCHARSET; + } + aofac++; +#ifdef DEBUG + __CTRACE(__CTRACE_INIT, "__init_wacs: %c = %c\n", acs, term); +#endif + } + + if (screen->tc_eA != NULL) + t_puts(screen->cursesi_genbuf, screen->tc_eA, 0, + __cputchar_args, screen->outfd); + +out: + for (count=0; count < NUM_ACS; count++) + memcpy(&screen->wacs_char[count], &_wacs_char[count], + sizeof(cchar_t)); +} + +void +_cursesi_reset_wacs(SCREEN *screen) +{ + int count; + + for (count=0; count < NUM_ACS; count++) + memcpy( &_wacs_char[count], &screen->wacs_char[count], + sizeof( cchar_t )); +} +#endif /* HAVE_WCHAR */ diff --git a/lib/libcurses/add_wch.c b/lib/libcurses/add_wch.c index 97a6b89755f..50a08c4e371 100644 --- a/lib/libcurses/add_wch.c +++ b/lib/libcurses/add_wch.c @@ -1,4 +1,4 @@ -/* $NetBSD: add_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: add_wch.c,v 1.2 2007/05/28 15:01:53 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,12 +36,15 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: add_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: add_wch.c,v 1.2 2007/05/28 15:01:53 blymn Exp $"); #endif /* not lint */ #include <stdlib.h> #include "curses.h" #include "curses_private.h" +#ifdef DEBUG +#include <assert.h> +#endif /* * add_wch -- @@ -104,256 +107,18 @@ wadd_wch(WINDOW *win, const cchar_t *wch) #ifndef HAVE_WCHAR return ERR; #else - int x = win->curx, y = win->cury, sx = 0, ex = 0, cw = 0, i = 0, - newx = 0; - __LDATA *lp = &win->lines[y]->line[x], *tp = NULL; - nschar_t *np = NULL, *tnp = NULL; + int x = win->curx, y = win->cury; __LINE *lnp = NULL; - cchar_t cc; #ifdef DEBUG + int i; + for (i = 0; i < win->maxy; i++) { assert(win->lines[i]->sentinel == SENTINEL_VALUE); } - __CTRACE("[wadd_wch]win(%p)", win); + __CTRACE(__CTRACE_INPUT, "wadd_wch: win(%p)", win); #endif - - /* special characters handling */ lnp = win->lines[y]; - switch (wch->vals[0]) { - case L'\b': - if (--x < 0) - x = 0; - win->curx = x; - return OK; - case L'\r': - win->curx = 0; - return OK; - case L'\n': - wclrtoeol(win); - x = win->curx; - y = win->cury; - x = 0; - lnp->flags &= ~__ISPASTEOL; - if (y == win->scr_b) { - if (!(win->flags & __SCROLLOK)) - return ERR; - win->cury = y; - win->curx = x; - scroll(win); - y = win->cury; - x = win->curx; - } else { - y++; - } - win->curx = x; - win->cury = y; - return OK; - case L'\t': - cc.vals[0] = L' '; - cc.elements = 1; - cc.attributes = win->wattr; - for (i = 0; i < 8 - (x % 8); i++) { - if (wadd_wch(win, &cc) == ERR) - return ERR; - } - return OK; - } - - /* check for non-spacing character */ - if (!wcwidth(wch->vals[0])) { - cw = WCOL(*lp); - if (cw < 0) { - lp += cw; - x += cw; - } - for (i = 0; i < wch->elements; i++) { - if (!(np = (nschar_t *) malloc(sizeof(nschar_t)))) - return ERR;; - np->ch = wch->vals[i]; - np->next = lp->nsp; - lp->nsp = np; - } - lnp->flags |= __ISDIRTY; - newx = x + win->ch_off; - if (newx < *lnp->firstchp) - *lnp->firstchp = newx; - if (newx > *lnp->lastchp) - *lnp->lastchp = newx; - __touchline(win, y, x, x); - return OK; - } - /* check for new line first */ - if (lnp->flags & __ISPASTEOL) { - x = 0; - lnp->flags &= ~__ISPASTEOL; - if (y == win->scr_b) { - if (!(win->flags & __SCROLLOK)) - return ERR; - win->cury = y; - win->curx = x; - scroll(win); - y = win->cury; - x = win->curx; - } else { - y++; - } - lnp = win->lines[y]; - lp = &win->lines[y]->line[x]; - } - /* clear out the current character */ - cw = WCOL(*lp); - if (cw >= 0) { - sx = x; - } else { - for (sx = x - 1; sx >= max(x + cw, 0); sx--) { -#ifdef DEBUG - __CTRACE("[wadd_wch]clear current char (%d,%d)", - y, sx); -#endif /* DEBUG */ - tp = &win->lines[y]->line[sx]; - tp->ch = (wchar_t) btowc((int) win->bch); - if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) - return ERR; - - tp->attr = win->battr; - SET_WCOL(*tp, 1); - } - sx = x + cw; - lnp->flags |= __ISDIRTY; - newx = sx + win->ch_off; - if (newx < *lnp->firstchp) - *lnp->firstchp = newx; - } - - /* check for enough space before the end of line */ - cw = wcwidth(wch->vals[0]); - if (cw > win->maxx - x) { -#ifdef DEBUG - __CTRACE("[wadd_wch]clear EOL (%d,%d)", y, x); -#endif /* DEBUG */ - lnp->flags |= __ISDIRTY; - newx = x + win->ch_off; - if (newx < *lnp->firstchp) - *lnp->firstchp = newx; - for (tp = lp; x < win->maxx; tp++, x++) { - tp->ch = (wchar_t) btowc((int) win->bch); - if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) - return ERR; - tp->attr = win->battr; - SET_WCOL(*tp, 1); - } - newx = win->maxx - 1 + win->ch_off; - if (newx > *lnp->lastchp) - *lnp->lastchp = newx; - __touchline(win, y, sx, (int) win->maxx - 1); - sx = x = 0; - if (y == win->scr_b) { - if (!(win->flags & __SCROLLOK)) - return ERR; - win->curx = x; - win->cury = y; - scroll(win); - x = win->curx; - y = win->cury; - } else { - y++; - } - lp = &win->lines[y]->line[0]; - lnp = win->lines[y]; - } - win->cury = y; - - /* add spacing character */ -#ifdef DEBUG - __CTRACE("[wadd_wch]add character (%d,%d)%x", - y, x, wch->vals[0]); -#endif /* DEBUG */ - lnp->flags |= __ISDIRTY; - newx = x + win->ch_off; - if (newx < *lnp->firstchp) - *lnp->firstchp = newx; - if (lp->nsp) { - np = lp->nsp; - while (np) { - tnp = np->next; - free(np); - np = tnp; - } - lp->nsp = NULL; - } - lp->ch = wch->vals[0]; - lp->attr = wch->attributes & WA_ATTRIBUTES; - SET_WCOL(*lp, cw); - if (wch->elements > 1) { - for (i = 1; i < wch->elements; i++) { - np = (nschar_t *)malloc(sizeof(nschar_t)); - if (!np) - return ERR;; - np->ch = wch->vals[i]; - np->next = lp->nsp; -#ifdef DEBUG - __CTRACE("[wadd_wch]add non-spacing char 0x%x", - np->ch); -#endif /* DEBUG */ - lp->nsp = np; - } - } -#ifdef DEBUG - __CTRACE("[wadd_wch]non-spacing list header: %p\n", lp->nsp); - __CTRACE("[wadd_wch]add rest columns (%d:%d)\n", - sx + 1, sx + cw - 1); -#endif /* DEBUG */ - for (tp = lp + 1, x = sx + 1; x - sx <= cw - 1; tp++, x++) { - if (tp->nsp) { - np = tp->nsp; - while (np) { - tnp = np->next; - free(np); - np = tnp; - } - tp->nsp = NULL; - } - tp->ch = wch->vals[0]; - tp->attr = wch->attributes & WA_ATTRIBUTES; - SET_WCOL(*tp, sx - x); - } - if (x == win->maxx) { - lnp->flags |= __ISPASTEOL; - newx = win->maxx - 1 + win->ch_off; - if (newx > *lnp->lastchp) - *lnp->lastchp = newx; - __touchline(win, y, sx, (int) win->maxx - 1); - win->curx = sx; - } else { - win->curx = x; - - /* clear the remining of the current characer */ - if (x && x < win->maxx) { - ex = sx + cw; - tp = &win->lines[y]->line[ex]; - while (ex < win->maxx && WCOL(*tp) < 0) { -#ifdef DEBUG - __CTRACE("[wadd_wch]clear remaining of current char (%d,%d)", - y, ex); -#endif /* DEBUG */ - tp->ch = (wchar_t) btowc((int) win->bch); - if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) - return ERR; - tp->attr = win->battr; - SET_WCOL(*tp, 1); - tp++, ex++; - } - newx = ex - 1 + win->ch_off; - if (newx > *lnp->lastchp) - *lnp->lastchp = newx; - __touchline(win, y, sx, ex - 1); - } - } - -#ifdef DEBUG - __CTRACE("add_wch: %d : 0x%x\n", lp->ch, lp->attr); -#endif /* DEBUG */ - return OK; + return _cursesi_addwchar(win, &lnp, &y, &x, wch); #endif /* HAVE_WCHAR */ } diff --git a/lib/libcurses/add_wchstr.c b/lib/libcurses/add_wchstr.c index 620ded9dbb1..d2e6eabd3ef 100644 --- a/lib/libcurses/add_wchstr.c +++ b/lib/libcurses/add_wchstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: add_wchstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: add_wchstr.c,v 1.2 2007/05/28 15:01:53 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: add_wchstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: add_wchstr.c,v 1.2 2007/05/28 15:01:53 blymn Exp $"); #endif /* not lint */ #include <stdlib.h> @@ -174,8 +174,8 @@ wadd_wchnstr(WINDOW *win, const cchar_t *wchstr, int n) __LINE *lnp; #ifdef DEBUG - __CTRACE("wadd_wchnstr: win = %p, wchstr = %p, n = %d\n", - win, wchstr, n); + __CTRACE(__CTRACE_INPUT, + "wadd_wchnstr: win = %p, wchstr = %p, n = %d\n", win, wchstr, n); #endif if (!wchstr) @@ -190,7 +190,7 @@ wadd_wchnstr(WINDOW *win, const cchar_t *wchstr, int n) else for (chp = wchstr, cnt = 0; chp->vals[0]; chp++, ++cnt); #ifdef DEBUG - __CTRACE("[wadd_wchnstr]len=%d", cnt); + __CTRACE(__CTRACE_INPUT, "wadd_wchnstr: len=%d\n", cnt); #endif /* DEBUG */ chp = wchstr; x = win->curx; @@ -227,15 +227,17 @@ wadd_wchnstr(WINDOW *win, const cchar_t *wchstr, int n) /* add characters in the string */ ex = x; while (cnt) { + x = ex; wc = chp->vals[0]; #ifdef DEBUG - __CTRACE("[wadd_wchnstr]adding %x", wc); + __CTRACE(__CTRACE_INPUT, "wadd_wchnstr: adding %x", wc); #endif /* DEBUG */ - cw = wcwidth(wc); + cw = wcwidth(wc); if (cw) { /* spacing character */ #ifdef DEBUG - __CTRACE(" as a spacing char(width=%d)\n", cw); + __CTRACE(__CTRACE_INPUT, + " as a spacing char(width=%d)\n", cw); #endif /* DEBUG */ if (cw > win->maxx - ex) { /* clear to EOL */ @@ -278,6 +280,11 @@ wadd_wchnstr(WINDOW *win, const cchar_t *wchstr, int n) } } lp++, ex++; +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "wadd_wchnstr: ex = %d, x = %d, cw = %d\n", + ex, x, cw); +#endif /* DEBUG */ while (ex - x <= cw - 1) { np = lp->nsp; if (np) { @@ -296,7 +303,8 @@ wadd_wchnstr(WINDOW *win, const cchar_t *wchstr, int n) } else { /* non-spacing character */ #ifdef DEBUG - __CTRACE("[wadd_wchnstr]as non-spacing char"); + __CTRACE(__CTRACE_INPUT, + "wadd_wchnstr: as non-spacing char"); #endif /* DEBUG */ for (i = 0; i < chp->elements; i++) { np = (nschar_t *)malloc(sizeof(nschar_t)); @@ -311,7 +319,7 @@ wadd_wchnstr(WINDOW *win, const cchar_t *wchstr, int n) } #ifdef DEBUG for (i = sx; i < ex; i++) { - __CTRACE("[wadd_wchnstr](%d,%d)=(%x,%x,%p)\n", + __CTRACE(__CTRACE_INPUT, "wadd_wchnstr: (%d,%d)=(%x,%x,%p)\n", win->cury, i, win->lines[win->cury]->line[i].ch, win->lines[win->cury]->line[i].attr, win->lines[win->cury]->line[i].nsp); diff --git a/lib/libcurses/addbytes.c b/lib/libcurses/addbytes.c index 162c407fe65..11a43734150 100644 --- a/lib/libcurses/addbytes.c +++ b/lib/libcurses/addbytes.c @@ -1,4 +1,4 @@ -/* $NetBSD: addbytes.c,v 1.31 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: addbytes.c,v 1.32 2007/05/28 15:01:53 blymn Exp $ */ /* * Copyright (c) 1987, 1993, 1994 @@ -34,10 +34,11 @@ #if 0 static char sccsid[] = "@(#)addbytes.c 8.4 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: addbytes.c,v 1.31 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: addbytes.c,v 1.32 2007/05/28 15:01:53 blymn Exp $"); #endif #endif /* not lint */ +#include <stdlib.h> #include "curses.h" #include "curses_private.h" #ifdef DEBUG @@ -46,6 +47,8 @@ __RCSID("$NetBSD: addbytes.c,v 1.31 2007/01/21 13:25:36 jdc Exp $"); #define SYNCH_IN {y = win->cury; x = win->curx;} #define SYNCH_OUT {win->cury = y; win->curx = x;} +#define PSYNCH_IN {*y = win->cury; *x = win->curx;} +#define PSYNCH_OUT {win->cury = *y; win->curx = *x;} #ifndef _CURSES_USE_MACROS @@ -101,141 +104,476 @@ mvwaddbytes(WINDOW *win, int y, int x, const char *bytes, int count) int __waddbytes(WINDOW *win, const char *bytes, int count, attr_t attr) { - static char blanks[] = " "; - int c, newx, x, y; - attr_t attributes; + int x, y, err; __LINE *lp; +#ifdef HAVE_WCHAR + int n; + cchar_t cc; + wchar_t wc; +#else + int c; +#endif #ifdef DEBUG int i; for (i = 0; i < win->maxy; i++) { assert(win->lines[i]->sentinel == SENTINEL_VALUE); } + + __CTRACE(__CTRACE_INPUT, "ADDBYTES: add %d bytes\n", count); #endif - + + err = OK; SYNCH_IN; lp = win->lines[y]; - while (count--) { + while (count > 0) { +#ifndef HAVE_WCHAR c = *bytes++; #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "ADDBYTES('%c', %x) at (%d, %d)\n", c, attr, y, x); #endif - switch (c) { - case '\t': - SYNCH_OUT; - if (waddbytes(win, blanks, 8 - (x % 8)) == ERR) - return (ERR); - SYNCH_IN; + err = _cursesi_addbyte(win, &lp, &y, &x, c, attr); + count--; +#else + /* + * For wide character support only, try and convert the + * given string into a wide character - we do this because + * this is how ncurses behaves (not that I think this is + * actually the correct thing to do but if we don't do it + * a lot of things that rely on this behaviour will break + * and we will be blamed). If the conversion succeeds + * then we eat the n characters used to make the wide char + * from the string. + */ + n = mbtowc(&wc, bytes, count); + if (n == 0) break; + else if (n < 0) { /* not a valid conversion just eat a char */ + wc = *bytes; + n = 1; + } + + +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "ADDBYTES WIDE(0x%x [%s], %x) at (%d, %d), ate %d bytes\n", + (unsigned) wc, unctrl((unsigned) wc), attr, y, x, n); +#endif + cc.vals[0] = wc; + cc.elements = 1; + cc.attributes = attr; + err = _cursesi_addwchar(win, &lp, &y, &x, &cc); + bytes += n; + count -= n; +#endif + } + + SYNCH_OUT; + +#ifdef DEBUG + for (i = 0; i < win->maxy; i++) { + assert(win->lines[i]->sentinel == SENTINEL_VALUE); + } +#endif + + return (err); +} - default: +/* + * _cursesi_addbyte - + * Internal function to add a byte and update the row and column + * positions as appropriate. This function is only used in the narrow + * character version of curses. + */ +int +_cursesi_addbyte(WINDOW *win, __LINE **lp, int *y, int *x, int c, + attr_t attr) +{ + static char blanks[] = " "; + int newx; + attr_t attributes; + + switch (c) { + case '\t': + PSYNCH_OUT; + if (waddbytes(win, blanks, 8 - (*x % 8)) == ERR) + return (ERR); + PSYNCH_IN; + break; + + default: #ifdef DEBUG - __CTRACE(__CTRACE_INPUT, "ADDBYTES(%p, %d, %d)\n", - win, y, x); + __CTRACE(__CTRACE_INPUT, "ADDBYTES(%p, %d, %d)\n", + win, *y, *x); #endif - if (lp->flags & __ISPASTEOL) { - newline: - x = 0; - lp->flags &= ~__ISPASTEOL; - if (y == win->scr_b) { + if ((*lp)->flags & __ISPASTEOL) { + newline: + *x = 0; + (*lp)->flags &= ~__ISPASTEOL; + if (*y == win->scr_b) { #ifdef DEBUG - __CTRACE(__CTRACE_INPUT, - "ADDBYTES - on bottom " - "of scrolling region\n"); + __CTRACE(__CTRACE_INPUT, + "ADDBYTES - on bottom " + "of scrolling region\n"); #endif - if (!(win->flags & __SCROLLOK)) - return ERR; - SYNCH_OUT; - scroll(win); - SYNCH_IN; - } else { - y++; - } - lp = win->lines[y]; - if (c == '\n') - break; + if (!(win->flags & __SCROLLOK)) + return ERR; + PSYNCH_OUT; + scroll(win); + PSYNCH_IN; + } else { + (*y)++; } + *lp = win->lines[*y]; + if (c == '\n') + break; + } - attributes = (win->wattr | attr) & - (__ATTRIBUTES & ~__COLOR); - if (attr & __COLOR) - attributes |= attr & __COLOR; - else if (win->wattr & __COLOR) - attributes |= win->wattr & __COLOR; + attributes = (win->wattr | attr) & + (__ATTRIBUTES & ~__COLOR); + if (attr & __COLOR) + attributes |= attr & __COLOR; + else if (win->wattr & __COLOR) + attributes |= win->wattr & __COLOR; #ifdef DEBUG - __CTRACE(__CTRACE_INPUT, - "ADDBYTES: 1: y = %d, x = %d, firstch = %d, " - "lastch = %d\n", - y, x, *win->lines[y]->firstchp, - *win->lines[y]->lastchp); + __CTRACE(__CTRACE_INPUT, + "ADDBYTES: 1: y = %d, x = %d, firstch = %d, " + "lastch = %d\n", + *y, *x, *win->lines[*y]->firstchp, + *win->lines[*y]->lastchp); #endif - /* - * Always update the change pointers. Otherwise, - * we could end up not displaying 'blank' characters - * when overlapping windows are displayed. - */ - newx = x + win->ch_off; - lp->flags |= __ISDIRTY; - /* - * firstchp/lastchp are shared between - * parent window and sub-window. - */ - if (newx < *lp->firstchp) - *lp->firstchp = newx; - if (newx > *lp->lastchp) - *lp->lastchp = newx; + /* + * Always update the change pointers. Otherwise, + * we could end up not displaying 'blank' characters + * when overlapping windows are displayed. + */ + newx = *x + win->ch_off; + (*lp)->flags |= __ISDIRTY; + /* + * firstchp/lastchp are shared between + * parent window and sub-window. + */ + if (newx < *(*lp)->firstchp) + *(*lp)->firstchp = newx; + if (newx > *(*lp)->lastchp) + *(*lp)->lastchp = newx; #ifdef DEBUG - __CTRACE(__CTRACE_INPUT, - "ADDBYTES: change gives f/l: %d/%d [%d/%d]\n", - *lp->firstchp, *lp->lastchp, - *lp->firstchp - win->ch_off, - *lp->lastchp - win->ch_off); + __CTRACE(__CTRACE_INPUT, + "ADDBYTES: change gives f/l: %d/%d [%d/%d]\n", + *(*lp)->firstchp, *(*lp)->lastchp, + *(*lp)->firstchp - win->ch_off, + *(*lp)->lastchp - win->ch_off); #endif - if (win->bch != ' ' && c == ' ') - lp->line[x].ch = win->bch; - else - lp->line[x].ch = c; - if (attributes & __COLOR) - lp->line[x].attr = - attributes | (win->battr & ~__COLOR); - else - lp->line[x].attr = attributes | win->battr; - if (x == win->maxx - 1) - lp->flags |= __ISPASTEOL; - else - x++; + if (win->bch != ' ' && c == ' ') + (*lp)->line[*x].ch = win->bch; + else + (*lp)->line[*x].ch = c; + + if (attributes & __COLOR) + (*lp)->line[*x].attr = + attributes | (win->battr & ~__COLOR); + else + (*lp)->line[*x].attr = attributes | win->battr; + + if (*x == win->maxx - 1) + (*lp)->flags |= __ISPASTEOL; + else + (*x)++; #ifdef DEBUG - __CTRACE(__CTRACE_INPUT, - "ADDBYTES: 2: y = %d, x = %d, firstch = %d, " - "lastch = %d\n", - y, x, *win->lines[y]->firstchp, - *win->lines[y]->lastchp); + __CTRACE(__CTRACE_INPUT, + "ADDBYTES: 2: y = %d, x = %d, firstch = %d, " + "lastch = %d\n", + *y, *x, *win->lines[*y]->firstchp, + *win->lines[*y]->lastchp); #endif - break; - case '\n': - SYNCH_OUT; - wclrtoeol(win); - SYNCH_IN; - goto newline; - case '\r': - x = 0; - continue; - case '\b': - if (--x < 0) - x = 0; - break; + break; + case '\n': + PSYNCH_OUT; + wclrtoeol(win); + PSYNCH_IN; + goto newline; + case '\r': + *x = 0; + break; + case '\b': + if (--(*x) < 0) + *x = 0; + break; + } + + return (OK); +} + +/* + * _cursesi_addwchar - + * Internal function to add a wide character and update the row + * and column positions. + */ +int +_cursesi_addwchar(WINDOW *win, __LINE **lnp, int *y, int *x, + const cchar_t *wch) +{ +#ifndef HAVE_WCHAR + return (ERR); +#else + int sx = 0, ex = 0, cw = 0, i = 0, newx = 0; + __LDATA *lp = &win->lines[*y]->line[*x], *tp = NULL; + nschar_t *np = NULL; + cchar_t cc; + attr_t attributes; + + /* special characters handling */ + switch (wch->vals[0]) { + case L'\b': + if (--*x < 0) + *x = 0; + win->curx = *x; + return OK; + case L'\r': + win->curx = 0; + return OK; + case L'\n': + wclrtoeol(win); + PSYNCH_IN; + *x = 0; + (*lnp)->flags &= ~__ISPASTEOL; + if (*y == win->scr_b) { + if (!(win->flags & __SCROLLOK)) + return ERR; + PSYNCH_OUT; + scroll(win); + PSYNCH_IN; + } else { + (*y)++; } + PSYNCH_OUT; + return OK; + case L'\t': + cc.vals[0] = L' '; + cc.elements = 1; + cc.attributes = win->wattr; + for (i = 0; i < 8 - (*x % 8); i++) { + if (wadd_wch(win, &cc) == ERR) + return ERR; + } + return OK; } - SYNCH_OUT; - + + /* check for non-spacing character */ + if (!wcwidth(wch->vals[0])) { #ifdef DEBUG - for (i = 0; i < win->maxy; i++) { - assert(win->lines[i]->sentinel == SENTINEL_VALUE); + __CTRACE(__CTRACE_INPUT, + "_cursesi_addwchar: char '%c' is non-spacing\n", + wch->vals[0]); +#endif /* DEBUG */ + cw = WCOL(*lp); + if (cw < 0) { + lp += cw; + *x += cw; + } + for (i = 0; i < wch->elements; i++) { + if (!(np = (nschar_t *) malloc(sizeof(nschar_t)))) + return ERR;; + np->ch = wch->vals[i]; + np->next = lp->nsp; + lp->nsp = np; + } + (*lnp)->flags |= __ISDIRTY; + newx = *x + win->ch_off; + if (newx < *(*lnp)->firstchp) + *(*lnp)->firstchp = newx; + if (newx > *(*lnp)->lastchp) + *(*lnp)->lastchp = newx; + __touchline(win, *y, *x, *x); + return OK; } -#endif + /* check for new line first */ + if ((*lnp)->flags & __ISPASTEOL) { + *x = 0; + (*lnp)->flags &= ~__ISPASTEOL; + if (*y == win->scr_b) { + if (!(win->flags & __SCROLLOK)) + return ERR; + PSYNCH_OUT; + scroll(win); + PSYNCH_IN; + } else { + (*y)++; + } + (*lnp) = win->lines[*y]; + lp = &win->lines[*y]->line[*x]; + } + /* clear out the current character */ + cw = WCOL(*lp); + if (cw >= 0) { + sx = *x; + } else { + for (sx = *x - 1; sx >= max(*x + cw, 0); sx--) { +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "_cursesi_addwchar: clear current char (%d,%d)\n", + *y, sx); +#endif /* DEBUG */ + tp = &win->lines[*y]->line[sx]; + tp->ch = (wchar_t) btowc((int) win->bch); + if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) + return ERR; - return (OK); + tp->attr = win->battr; + SET_WCOL(*tp, 1); + } + sx = *x + cw; + (*lnp)->flags |= __ISDIRTY; + newx = sx + win->ch_off; + if (newx < *(*lnp)->firstchp) + *(*lnp)->firstchp = newx; + } + + /* check for enough space before the end of line */ + cw = wcwidth(wch->vals[0]); + if (cw > win->maxx - *x) { +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "_cursesi_addwchar: clear EOL (%d,%d)\n", + *y, *x); +#endif /* DEBUG */ + (*lnp)->flags |= __ISDIRTY; + newx = *x + win->ch_off; + if (newx < *(*lnp)->firstchp) + *(*lnp)->firstchp = newx; + for (tp = lp; *x < win->maxx; tp++, (*x)++) { + tp->ch = (wchar_t) btowc((int) win->bch); + if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) + return ERR; + tp->attr = win->battr; + SET_WCOL(*tp, 1); + } + newx = win->maxx - 1 + win->ch_off; + if (newx > *(*lnp)->lastchp) + *(*lnp)->lastchp = newx; + __touchline(win, *y, sx, (int) win->maxx - 1); + sx = *x = 0; + if (*y == win->scr_b) { + if (!(win->flags & __SCROLLOK)) + return ERR; + PSYNCH_OUT; + scroll(win); + PSYNCH_IN; + } else { + (*y)++; + } + lp = &win->lines[*y]->line[0]; + (*lnp) = win->lines[*y]; + } + win->cury = *y; + + /* add spacing character */ +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "_cursesi_addwchar: add character (%d,%d) 0x%x\n", + *y, *x, wch->vals[0]); +#endif /* DEBUG */ + (*lnp)->flags |= __ISDIRTY; + newx = *x + win->ch_off; + if (newx < *(*lnp)->firstchp) + *(*lnp)->firstchp = newx; + if (lp->nsp) { + __cursesi_free_nsp(lp->nsp); + lp->nsp = NULL; + } + + lp->ch = wch->vals[0]; + + attributes = (win->wattr | wch->attributes) + & (WA_ATTRIBUTES & ~__COLOR); + if (wch->attributes & __COLOR) + attributes |= wch->attributes & __COLOR; + else if (win->wattr & __COLOR) + attributes |= win->wattr & __COLOR; + if (attributes & __COLOR) + lp->attr = attributes | (win->battr & ~__COLOR); + else + lp->attr = attributes | win->battr; + + SET_WCOL(*lp, cw); + +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x\n", + lp->ch, lp->attr); +#endif /* DEBUG */ + + if (wch->elements > 1) { + for (i = 1; i < wch->elements; i++) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR;; + np->ch = wch->vals[i]; + np->next = lp->nsp; +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "_cursesi_addwchar: add non-spacing char 0x%x\n", np->ch); +#endif /* DEBUG */ + lp->nsp = np; + } + } +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: non-spacing list header: %p\n", + lp->nsp); + __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add rest columns (%d:%d)\n", + sx + 1, sx + cw - 1); +#endif /* DEBUG */ + for (tp = lp + 1, *x = sx + 1; *x - sx <= cw - 1; tp++, (*x)++) { + if (tp->nsp) { + __cursesi_free_nsp(tp->nsp); + tp->nsp = NULL; + } + tp->ch = wch->vals[0]; + tp->attr = lp->attr & WA_ATTRIBUTES; + /* Mark as "continuation" cell */ + tp->attr |= __WCWIDTH; + } + if (*x == win->maxx) { + (*lnp)->flags |= __ISPASTEOL; + newx = win->maxx - 1 + win->ch_off; + if (newx > *(*lnp)->lastchp) + *(*lnp)->lastchp = newx; + __touchline(win, *y, sx, (int) win->maxx - 1); + win->curx = sx; + } else { + win->curx = *x; + + /* clear the remining of the current characer */ + if (*x && *x < win->maxx) { + ex = sx + cw; + tp = &win->lines[*y]->line[ex]; + while (ex < win->maxx && WCOL(*tp) < 0) { +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "_cursesi_addwchar: clear " + "remaining of current char (%d,%d)nn", + *y, ex); +#endif /* DEBUG */ + tp->ch = (wchar_t) btowc((int) win->bch); + if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) + return ERR; + tp->attr = win->battr; + SET_WCOL(*tp, 1); + tp++, ex++; + } + newx = ex - 1 + win->ch_off; + if (newx > *(*lnp)->lastchp) + *(*lnp)->lastchp = newx; + __touchline(win, *y, sx, ex - 1); + } + } + +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "add_wch: %d : 0x%x\n", lp->ch, lp->attr); +#endif /* DEBUG */ + return OK; +#endif } diff --git a/lib/libcurses/addch.c b/lib/libcurses/addch.c index b7166ceb793..abcce626aa2 100644 --- a/lib/libcurses/addch.c +++ b/lib/libcurses/addch.c @@ -1,4 +1,4 @@ -/* $NetBSD: addch.c,v 1.14 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: addch.c,v 1.15 2007/05/28 15:01:53 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)addch.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: addch.c,v 1.14 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: addch.c,v 1.15 2007/05/28 15:01:53 blymn Exp $"); #endif #endif /* not lint */ @@ -87,14 +87,36 @@ mvwaddch(WINDOW *win, int y, int x, chtype ch) int waddch(WINDOW *win, chtype ch) { +#ifdef HAVE_WCHAR + cchar_t cc; +#else __LDATA buf; +#endif +#ifdef HAVE_WCHAR + cc.vals[0] = ch & __CHARTEXT; + cc.elements = 1; + cc.attributes = ch & __ATTRIBUTES; +#else buf.ch = (wchar_t) ch & __CHARTEXT; buf.attr = (attr_t) ch & __ATTRIBUTES; +#endif + #ifdef DEBUG +#ifdef HAVE_WCHAR + __CTRACE(__CTRACE_INPUT, + "addch: %d : 0x%x (adding char as wide char)\n", + cc.vals[0], cc.attributes); +#else __CTRACE(__CTRACE_INPUT, "addch: %d : 0x%x\n", buf.ch, buf.attr); #endif +#endif + +#ifdef HAVE_WCHAR + return (wadd_wch(win, &cc)); +#else return (__waddch(win, &buf)); +#endif } int diff --git a/lib/libcurses/addnstr.c b/lib/libcurses/addnstr.c index 3cab16e3f07..33c4c832d7d 100644 --- a/lib/libcurses/addnstr.c +++ b/lib/libcurses/addnstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: addnstr.c,v 1.11 2003/08/07 16:44:18 agc Exp $ */ +/* $NetBSD: addnstr.c,v 1.12 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)addnstr.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: addnstr.c,v 1.11 2003/08/07 16:44:18 agc Exp $"); +__RCSID("$NetBSD: addnstr.c,v 1.12 2007/05/28 15:01:54 blymn Exp $"); #endif #endif /* not lint */ @@ -135,10 +135,14 @@ waddnstr(WINDOW *win, const char *s, int n) size_t len; const char *p; +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "ADDNSTR: win %p, length %d\n", + win, n); +#endif /* * behavior changed from traditional BSD curses, for better XCURSES * conformance. - * + * * BSD curses: if (n > 0) then "at most n", else "len = strlen(s)" * ncurses: if (n >= 0) then "at most n", else "len = strlen(s)" * XCURSES: if (n != -1) then "at most n", else "len = strlen(s)" diff --git a/lib/libcurses/addwstr.c b/lib/libcurses/addwstr.c index a766e954408..0a433a1c7a0 100644 --- a/lib/libcurses/addwstr.c +++ b/lib/libcurses/addwstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: addwstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: addwstr.c,v 1.2 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: addwstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: addwstr.c,v 1.2 2007/05/28 15:01:54 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -178,7 +178,7 @@ waddnwstr(WINDOW *win, const wchar_t *s, int n) else len = wcslen(s); #ifdef DEBUG - __CTRACE("[waddnwstr]string len=%d\n", len ); + __CTRACE(__CTRACE_INPUT, "waddnwstr: string len=%ld\n", (long) len); #endif /* DEBUG */ p = s; @@ -190,7 +190,7 @@ waddnwstr(WINDOW *win, const wchar_t *s, int n) if ( wadd_wch( win, &cc ) == ERR ) return ERR; #ifdef DEBUG - __CTRACE("[waddnwstr](%x,%x,%d) added\n", + __CTRACE(__CTRACE_INPUT, "waddnwstr: (%x,%x,%d) added\n", cc.vals[ 0 ], cc.attributes, cc.elements ); #endif /* DEBUG */ p++, len--; diff --git a/lib/libcurses/attributes.c b/lib/libcurses/attributes.c index 92b9bd08dba..b5011e16c71 100644 --- a/lib/libcurses/attributes.c +++ b/lib/libcurses/attributes.c @@ -1,4 +1,4 @@ -/* $NetBSD: attributes.c,v 1.14 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: attributes.c,v 1.15 2007/05/28 15:01:54 blymn Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: attributes.c,v 1.14 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: attributes.c,v 1.15 2007/05/28 15:01:54 blymn Exp $"); #endif /* not lint */ #include "curses.h" @@ -146,8 +146,13 @@ wattr_get(WINDOW *win, attr_t *attr, short *pair, void *opt) #ifdef DEBUG __CTRACE(__CTRACE_ATTR, "wattr_get: win %p\n", win); #endif - if (attr != NULL) + if (attr != NULL) { *attr = win->wattr; +#ifdef HAVE_WCHAR + *attr &= WA_ATTRIBUTES; +#endif + } + if (pair != NULL) *pair = PAIR_NUMBER(win->wattr); return OK; @@ -181,6 +186,20 @@ wattr_on(WINDOW *win, attr_t attr, void *opt) win->wattr |= __PROTECT; if (attr & __REVERSE && __tc_mr != NULL) win->wattr |= __REVERSE; +#ifdef HAVE_WCHAR + if (attr & WA_LOW && __tc_Xo != NULL) + win->wattr |= WA_LOW; + if (attr & WA_TOP && __tc_Xt != NULL) + win->wattr |= WA_TOP; + if (attr & WA_LEFT && __tc_Xl != NULL) + win->wattr |= WA_LEFT; + if (attr & WA_RIGHT && __tc_Xr != NULL) + win->wattr |= WA_RIGHT; + if (attr & WA_HORIZONTAL && __tc_Xh != NULL) + win->wattr |= WA_HORIZONTAL; + if (attr & WA_VERTICAL && __tc_Xv != NULL) + win->wattr |= WA_VERTICAL; +#endif /* HAVE_WCHAR */ } if (attr & __STANDOUT) wstandout(win); @@ -219,6 +238,20 @@ wattr_off(WINDOW *win, attr_t attr, void *opt) win->wattr &= ~__PROTECT; if (attr & __REVERSE) win->wattr &= ~__REVERSE; +#ifdef HAVE_WCHAR + if (attr & WA_LOW) + win->wattr &= ~WA_LOW; + if (attr & WA_TOP) + win->wattr &= ~WA_TOP; + if (attr & WA_LEFT) + win->wattr &= ~WA_LEFT; + if (attr & WA_RIGHT) + win->wattr &= ~WA_RIGHT; + if (attr & WA_HORIZONTAL) + win->wattr &= ~WA_HORIZONTAL; + if (attr & WA_VERTICAL) + win->wattr &= ~WA_VERTICAL; +#endif /* HAVE_WCHAR */ } if (attr & __STANDOUT) wstandend(win); @@ -235,7 +268,6 @@ wattr_off(WINDOW *win, attr_t attr, void *opt) * wattr_set -- * Set attributes and color pair on stdscr */ -/* ARGSUSED */ int wattr_set(WINDOW *win, attr_t attr, short pair, void *opt) { @@ -243,14 +275,13 @@ wattr_set(WINDOW *win, attr_t attr, short pair, void *opt) __CTRACE(__CTRACE_ATTR, "wattr_set: win %p, attr %08x, pair %d\n", win, attr, pair); #endif - wattr_on(win, attr, NULL); - wattr_off(win, (~attr & ~__COLOR) | ((attr & __COLOR) ? 0 : __COLOR), - NULL); + wattr_off(win, __ATTRIBUTES, opt); /* - * This overwrites any colour setting from the attributes + * This overwrites any colour setting from the attributes * and is compatible with ncurses. */ - __wcolor_set(win, (attr_t) COLOR_PAIR(pair)); + attr = (attr & ~__COLOR) | COLOR_PAIR(pair); + wattr_on(win, attr, opt); return OK; } @@ -258,7 +289,6 @@ wattr_set(WINDOW *win, attr_t attr, short pair, void *opt) * wattron -- * Test and set attributes. */ - int wattron(WINDOW *win, int attr) { @@ -292,10 +322,8 @@ wattrset(WINDOW *win, int attr) #ifdef DEBUG __CTRACE(__CTRACE_ATTR, "wattrset: win %p, attr %08x\n", win, attr); #endif + wattr_off(win, __ATTRIBUTES, NULL); wattr_on(win, (attr_t) attr, NULL); - wattr_off(win, - (attr_t) (~attr & ~__COLOR) | ((attr & __COLOR) ? 0 : __COLOR), - NULL); return OK; } diff --git a/lib/libcurses/background.c b/lib/libcurses/background.c index e4c9ae777e4..372c1f27753 100644 --- a/lib/libcurses/background.c +++ b/lib/libcurses/background.c @@ -1,4 +1,4 @@ -/* $NetBSD: background.c,v 1.10 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: background.c,v 1.11 2007/05/28 15:01:54 blymn Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -38,9 +38,10 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: background.c,v 1.10 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: background.c,v 1.11 2007/05/28 15:01:54 blymn Exp $"); #endif /* not lint */ +#include <stdlib.h> #include "curses.h" #include "curses_private.h" @@ -126,7 +127,7 @@ wbkgd(WINDOW *win, chtype ch) /* * getbkgd -- * Get current background attributes. - */ + */ chtype getbkgd(WINDOW *win) { @@ -139,3 +140,150 @@ getbkgd(WINDOW *win) return ((chtype) ((win->bch & A_CHARTEXT) | battr)); } + +int bkgrnd(const cchar_t *wch) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return wbkgrnd( stdscr, wch ); +#endif /* HAVE_WCHAR */ +} + +void bkgrndset(const cchar_t *wch) +{ +#ifdef HAVE_WCHAR + wbkgrndset( stdscr, wch ); +#endif /* HAVE_WCHAR */ +} + +int getbkgrnd(cchar_t *wch) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return wgetbkgrnd( stdscr, wch ); +#endif /* HAVE_WCHAR */ +} + +int wbkgrnd(WINDOW *win, const cchar_t *wch) +{ +#ifndef HAVE_WCHAR + return ERR; +#else +/* int y, x, i; */ + attr_t battr; +/* nschar_t *np, *tnp, *pnp; */ + +#ifdef DEBUG + __CTRACE(__CTRACE_ATTR, "wbkgrnd: (%p), '%s', %x\n", + win, (char *) wunctrl(wch), wch->attributes); +#endif + + /* ignore multi-column characters */ + if ( !wch->elements || wcwidth( wch->vals[ 0 ]) > 1 ) + return ERR; + + /* Background attributes (check colour). */ + battr = wch->attributes & WA_ATTRIBUTES; + if (__using_color && !( battr & __COLOR)) + battr |= __default_color; + + win->battr = battr; + wbkgrndset(win, wch); + __touchwin(win); + return OK; +#endif /* HAVE_WCHAR */ +} + +void wbkgrndset(WINDOW *win, const cchar_t *wch) +{ +#ifdef HAVE_WCHAR + attr_t battr; + nschar_t *np, *tnp; + int i; + +#ifdef DEBUG + __CTRACE(__CTRACE_ATTR, "wbkgrndset: (%p), '%s', %x\n", + win, (char *) wunctrl(wch), wch->attributes); +#endif + + /* ignore multi-column characters */ + if ( !wch->elements || wcwidth( wch->vals[ 0 ]) > 1 ) + return; + + /* Background character. */ + tnp = np = win->bnsp; + if ( wcwidth( wch->vals[ 0 ])) + win->bch = wch->vals[ 0 ]; + else { + if ( !np ) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return; + np->next = NULL; + win->bnsp = np; + } + np->ch = wch->vals[ 0 ]; + tnp = np; + np = np->next; + } + /* add non-spacing characters */ + if ( wch->elements > 1 ) { + for ( i = 1; i < wch->elements; i++ ) { + if ( !np ) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return; + np->next = NULL; + if ( tnp ) + tnp->next = np; + else + win->bnsp = np; + } + np->ch = wch->vals[ i ]; + tnp = np; + np = np->next; + } + } + /* clear the old non-spacing characters */ + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + + /* Background attributes (check colour). */ + battr = wch->attributes & WA_ATTRIBUTES; + if (__using_color && !( battr & __COLOR)) + battr |= __default_color; + win->battr = battr; + SET_BGWCOL((*win), 1); +#endif /* HAVE_WCHAR */ +} + +int wgetbkgrnd(WINDOW *win, cchar_t *wch) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + nschar_t *np; + + /* Background attributes (check colour). */ + wch->attributes = win->battr & WA_ATTRIBUTES; + if (__using_color && (( wch->attributes & __COLOR ) + == __default_color)) + wch->attributes &= ~__default_color; + wch->vals[ 0 ] = win->bch; + wch->elements = 1; + np = win->bnsp; + if (np) { + while ( np && wch->elements < CURSES_CCHAR_MAX ) { + wch->vals[ wch->elements++ ] = np->ch; + np = np->next; + } + } + + return OK; +#endif /* HAVE_WCHAR */ +} diff --git a/lib/libcurses/border.c b/lib/libcurses/border.c index 1d77226433c..b94f8d377bf 100644 --- a/lib/libcurses/border.c +++ b/lib/libcurses/border.c @@ -1,4 +1,4 @@ -/* $NetBSD: border.c,v 1.9 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: border.c,v 1.10 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -38,9 +38,12 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: border.c,v 1.9 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: border.c,v 1.10 2007/05/28 15:01:54 blymn Exp $"); #endif /* not lint */ +#include <stdlib.h> +#include <string.h> + #include "curses.h" #include "curses_private.h" @@ -48,7 +51,7 @@ __RCSID("$NetBSD: border.c,v 1.9 2007/01/21 13:25:36 jdc Exp $"); /* * border -- - * Draw a border around stdscr using the specified + * Draw a border around stdscr using the specified * delimiting characters. */ int @@ -56,7 +59,7 @@ border(chtype left, chtype right, chtype top, chtype bottom, chtype topleft, chtype topright, chtype botleft, chtype botright) { return wborder(stdscr, left, right, top, bottom, topleft, topright, - botleft, botright); + botleft, botright); } #endif @@ -138,12 +141,20 @@ wborder(WINDOW *win, chtype left, chtype right, chtype top, chtype bottom, win->lines[i]->line[0].attr = (attr_t) left & __ATTRIBUTES; win->lines[i]->line[endx].ch = (wchar_t) right & __CHARTEXT; win->lines[i]->line[endx].attr = (attr_t) right & __ATTRIBUTES; +#ifdef HAVE_WCHAR + SET_WCOL(win->lines[i]->line[0], 1); + SET_WCOL(win->lines[i]->line[endx], 1); +#endif } for (i = 1; i < endx; i++) { fp[i].ch = (wchar_t) top & __CHARTEXT; fp[i].attr = (attr_t) top & __ATTRIBUTES; lp[i].ch = (wchar_t) bottom & __CHARTEXT; lp[i].attr = (attr_t) bottom & __ATTRIBUTES; +#ifdef HAVE_WCHAR + SET_WCOL(fp[i], 1); + SET_WCOL(lp[i], 1); +#endif } /* Corners */ @@ -157,7 +168,421 @@ wborder(WINDOW *win, chtype left, chtype right, chtype top, chtype bottom, lp[0].attr = (attr_t) botleft & __ATTRIBUTES; lp[endx].ch = (wchar_t) botright & __CHARTEXT; lp[endx].attr = (attr_t) botright & __ATTRIBUTES; +#ifdef HAVE_WCHAR + SET_WCOL(fp[0], 1); + SET_WCOL(fp[endx], 1); + SET_WCOL(lp[0], 1); + SET_WCOL(lp[endx], 1); +#endif + } + __touchwin(win); + return (OK); +} + +int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts, + const cchar_t *bs, const cchar_t *tl, const cchar_t *tr, + const cchar_t *bl, const cchar_t *br) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br); +#endif /* HAVE_WCHAR */ +} + +int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, + const cchar_t *ts, const cchar_t *bs, + const cchar_t *tl, const cchar_t *tr, + const cchar_t *bl, const cchar_t *br) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + int endy, endx, i, j, k, cw, pcw, tlcw, blcw, trcw, brcw; + cchar_t left, right, bottom, top, topleft, topright, botleft, botright; + nschar_t *np, *tnp; + + if ( ls && wcwidth( ls->vals[ 0 ])) + memcpy( &left, ls, sizeof( cchar_t )); + else + setcchar( &left, &WACS_VLINE, win->wattr, 0, NULL ); + if ( rs && wcwidth( rs->vals[ 0 ])) + memcpy( &right, rs, sizeof( cchar_t )); + else + setcchar( &right, &WACS_VLINE, win->wattr, 0, NULL ); + if ( ts && wcwidth( ts->vals[ 0 ])) + memcpy( &top, ts, sizeof( cchar_t )); + else + setcchar( &top, &WACS_HLINE, win->wattr, 0, NULL ); + if ( bs && wcwidth( bs->vals[ 0 ])) + memcpy( &bottom, bs, sizeof( cchar_t )); + else + setcchar( &bottom, &WACS_HLINE, win->wattr, 0, NULL ); + if ( tl && wcwidth( tl->vals[ 0 ])) + memcpy( &topleft, tl, sizeof( cchar_t )); + else + setcchar( &topleft, &WACS_ULCORNER, win->wattr, 0, NULL ); + if ( tr && wcwidth( tr->vals[ 0 ])) + memcpy( &topright, tr, sizeof( cchar_t )); + else + setcchar( &topright, &WACS_URCORNER, win->wattr, 0, NULL ); + if ( bl && wcwidth( bl->vals[ 0 ])) + memcpy( &botleft, bl, sizeof( cchar_t )); + else + setcchar( &botleft, &WACS_LLCORNER, win->wattr, 0, NULL ); + if ( br && wcwidth( br->vals[ 0 ])) + memcpy( &botright, br, sizeof( cchar_t )); + else + setcchar( &botright, &WACS_LRCORNER, win->wattr, 0, NULL ); + +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n", + left.vals[0], left.attributes ); + __CTRACE(__CTRACE_INPUT, "wborder_set: right = %c, 0x%x\n", + right.vals[0], right.attributes ); + __CTRACE(__CTRACE_INPUT, "wborder_set: top = %c, 0x%x\n", + top.vals[0], top.attributes ); + __CTRACE(__CTRACE_INPUT, "wborder_set: bottom = %c, 0x%x\n", + bottom.vals[0], bottom.attributes ); + __CTRACE(__CTRACE_INPUT, "wborder_set: topleft = %c, 0x%x\n", + topleft.vals[0], topleft.attributes ); + __CTRACE(__CTRACE_INPUT, "wborder_set: topright = %c, 0x%x\n", + topright.vals[0], topright.attributes ); + __CTRACE(__CTRACE_INPUT, "wborder_set: botleft = %c, 0x%x\n", + botleft.vals[0], botleft.attributes ); + __CTRACE(__CTRACE_INPUT, "wborder_set: botright = %c, 0x%x\n", + botright.vals[0], botright.attributes ); +#endif + + /* Merge window attributes */ + left.attributes |= (left.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + right.attributes |= (right.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + top.attributes |= (top.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + bottom.attributes |= (bottom.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + topleft.attributes |= (topleft.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + topright.attributes |= (topright.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + botleft.attributes |= (botleft.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + botright.attributes |= (botright.attributes & __COLOR) ? + (win->wattr & ~__COLOR) : win->wattr; + + endx = win->maxx - 1; + endy = win->maxy - 1; + + /* Sides */ + for (i = 1; i < endy; i++) { + /* left border */ + cw = wcwidth( left.vals[ 0 ]); + for ( j = 0; j < cw; j++ ) { + win->lines[i]->line[j].ch = left.vals[ 0 ]; + win->lines[i]->line[j].attr = left.attributes; + np = win->lines[i]->line[j].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[i]->line[j].nsp = NULL; + } + if ( j ) + SET_WCOL( win->lines[i]->line[j], -j ); + else { + SET_WCOL( win->lines[i]->line[j], cw ); + if ( left.elements > 1 ) { + for (k = 1; k < left.elements; k++) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR; + np->ch = left.vals[ k ]; + np->next = win->lines[i]->line[j].nsp; + win->lines[i]->line[j].nsp + = np; + } + } + } + } + for ( j = cw; WCOL( win->lines[i]->line[j]) < 0; j++ ) { +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "wborder_set: clean out partial char[%d]", j); +#endif /* DEBUG */ + win->lines[i]->line[j].ch = ( wchar_t )btowc(win->bch); + if (_cursesi_copy_nsp(win->bnsp, + &win->lines[i]->line[j]) == ERR) + return ERR; + SET_WCOL( win->lines[i]->line[j], 1 ); + } + /* right border */ + cw = wcwidth( right.vals[ 0 ]); + pcw = WCOL( win->lines[i]->line[endx - cw]); + for ( j = endx - cw + 1; j <= endx; j++ ) { + win->lines[i]->line[j].ch = right.vals[ 0 ]; + win->lines[i]->line[j].attr = right.attributes; + np = win->lines[i]->line[j].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[i]->line[j].nsp = NULL; + } + if ( j == endx - cw + 1 ) { + SET_WCOL( win->lines[i]->line[j], cw ); + if ( right.elements > 1 ) { + for (k = 1; k < right.elements; k++) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR; + np->ch = right.vals[ k ]; + np->next = win->lines[i]->line[j].nsp; + win->lines[i]->line[j].nsp + = np; + } + } + } else + SET_WCOL( win->lines[i]->line[j], + endx - cw + 1 - j ); + } + if ( pcw != 1 ) { +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, + "wborder_set: clean out partial chars[%d:%d]", + endx - cw + pcw, endx - cw ); +#endif /* DEBUG */ + k = pcw < 0 ? endx -cw + pcw : endx - cw; + for ( j = endx - cw; j >= k; j-- ) { + win->lines[i]->line[j].ch + = (wchar_t)btowc(win->bch); + if (_cursesi_copy_nsp(win->bnsp, + &win->lines[i]->line[j]) == ERR) + return ERR; + win->lines[i]->line[j].attr = win->battr; + SET_WCOL( win->lines[i]->line[j], 1 ); + } + } + } + tlcw = wcwidth( topleft.vals[ 0 ]); + blcw = wcwidth( botleft.vals[ 0 ]); + trcw = wcwidth( topright.vals[ 0 ]); + brcw = wcwidth( botright.vals[ 0 ]); + /* upper border */ + cw = wcwidth( top.vals[ 0 ]); + for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) { + for ( j = 0; j < cw; j++ ) { + win->lines[ 0 ]->line[i + j].ch = top.vals[ 0 ]; + win->lines[ 0 ]->line[i + j].attr = top.attributes; + np = win->lines[ 0 ]->line[i + j].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[ 0 ]->line[i + j].nsp = NULL; + } + if ( j ) + SET_WCOL( win->lines[ 0 ]->line[ i + j ], -j ); + else { + SET_WCOL( win->lines[ 0 ]->line[ i + j ], cw ); + if ( top.elements > 1 ) { + for ( k = 1; k < top.elements; k++ ) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR; + np->ch = top.vals[ k ]; + np->next = win->lines[0]->line[i + j].nsp; + win->lines[0]->line[i + j].nsp + = np; + } + } + } + } + } + while ( i <= endx - trcw ) { + win->lines[0]->line[i].ch = + ( wchar_t )btowc(( int ) win->bch ); + if (_cursesi_copy_nsp(win->bnsp, + &win->lines[0]->line[i]) == ERR) + return ERR; + win->lines[ 0 ]->line[ i ].attr = win->battr; + SET_WCOL( win->lines[ 0 ]->line[ i ], 1 ); + i++; + } + /* lower border */ + for (i = blcw; i <= min( endx - cw, endx - brcw ); i += cw ) { + for ( j = 0; j < cw; j++ ) { + win->lines[ endy ]->line[i + j].ch = bottom.vals[ 0 ]; + win->lines[endy]->line[i + j].attr = bottom.attributes; + np = win->lines[ endy ]->line[i + j].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[ endy ]->line[i + j].nsp = NULL; + } + if ( j ) + SET_WCOL( win->lines[endy]->line[i + j], -j); + else { + SET_WCOL( win->lines[endy]->line[i + j], cw ); + if ( bottom.elements > 1 ) { + for ( k = 1; k < bottom.elements; + k++ ) { + if ( !( np = ( nschar_t *)malloc( sizeof( nschar_t )))) + return ERR; + np->ch = bottom.vals[ k ]; + np->next = win->lines[endy]->line[i + j].nsp; + win->lines[endy]->line[i + j].nsp = np; + } + } + } + } + } + while ( i <= endx - brcw ) { + win->lines[endy]->line[i].ch = + (wchar_t)btowc((int) win->bch ); + if (_cursesi_copy_nsp(win->bnsp, + &win->lines[endy]->line[i]) == ERR) + return ERR; + win->lines[ endy ]->line[ i ].attr = win->battr; + SET_WCOL( win->lines[ endy ]->line[ i ], 1 ); + i++; + } + + /* Corners */ + if (!(win->maxx == LINES && win->maxy == COLS && + (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { + for ( i = 0; i < tlcw; i++ ) { + win->lines[ 0 ]->line[i].ch = topleft.vals[ 0 ]; + win->lines[ 0 ]->line[i].attr = topleft.attributes; + np = win->lines[ 0 ]->line[i].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[ 0 ]->line[i].nsp = NULL; + } + if ( i ) + SET_WCOL( win->lines[ 0 ]->line[ i ], -i ); + else { + SET_WCOL( win->lines[ 0 ]->line[ i ], tlcw ); + if ( topleft.elements > 1 ) { + for ( k = 1; k < topleft.elements; + k++ ) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR; + np->ch = topleft.vals[ k ]; + np->next = win->lines[ 0 ]->line[i].nsp; + win->lines[ 0 ]->line[i].nsp + = np; + } + } + } + } + for ( i = endx - trcw + 1; i <= endx; i++ ) { + win->lines[ 0 ]->line[i].ch = topright.vals[ 0 ]; + win->lines[ 0 ]->line[i].attr = topright.attributes; + np = win->lines[ 0 ]->line[i].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[ 0 ]->line[i].nsp = NULL; + } + if ( i == endx - trcw + 1 ) { + SET_WCOL( win->lines[ 0 ]->line[ i ], trcw ); + if ( topright.elements > 1 ) { + for ( k = 1; k < topright.elements; + k++ ) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR; + np->ch = topright.vals[ k ]; + np->next = win->lines[0]->line[i].nsp; + win->lines[ 0 ]->line[i].nsp + = np; + } + } + } else + SET_WCOL( win->lines[ 0 ]->line[ i ], + endx - trcw + 1 - i ); + } + for ( i = 0; i < blcw; i++ ) { + win->lines[ endy ]->line[i].ch = botleft.vals[ 0 ]; + win->lines[ endy ]->line[i].attr = botleft.attributes; + np = win->lines[ endy ]->line[i].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[ endy ]->line[i].nsp = NULL; + } + if ( i ) + SET_WCOL( win->lines[endy]->line[i], -i ); + else { + SET_WCOL( win->lines[endy]->line[i], blcw ); + if ( botleft.elements > 1 ) { + for ( k = 1; k < botleft.elements; + k++ ) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR; + np->ch = botleft.vals[ k ]; + np->next = win->lines[endy]->line[i].nsp; + win->lines[endy]->line[i].nsp + = np; + } + } + } + } + for ( i = endx - brcw + 1; i <= endx; i++ ) { + win->lines[ endy ]->line[i].ch = botright.vals[ 0 ]; + win->lines[ endy ]->line[i].attr = botright.attributes; + np = win->lines[ endy ]->line[i].nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + win->lines[ endy ]->line[i].nsp = NULL; + } + if ( i == endx - brcw + 1 ) { + SET_WCOL( win->lines[ endy ]->line[ i ], + brcw ); + if ( botright.elements > 1 ) { + for ( k = 1; k < botright.elements; k++ ) { + np = (nschar_t *)malloc(sizeof(nschar_t)); + if (!np) + return ERR; + np->ch = botright.vals[ k ]; + np->next = win->lines[endy]->line[i].nsp; + win->lines[endy]->line[i].nsp + = np; + } + } + } else + SET_WCOL( win->lines[ endy ]->line[ i ], + endx - brcw + 1 - i ); + } } __touchwin(win); return (OK); +#endif /* HAVE_WCHAR */ } diff --git a/lib/libcurses/box.c b/lib/libcurses/box.c index 0627dbbd7e6..9ffe7106a5b 100644 --- a/lib/libcurses/box.c +++ b/lib/libcurses/box.c @@ -1,4 +1,4 @@ -/* $NetBSD: box.c,v 1.13 2003/08/07 16:44:19 agc Exp $ */ +/* $NetBSD: box.c,v 1.14 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)box.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: box.c,v 1.13 2003/08/07 16:44:19 agc Exp $"); +__RCSID("$NetBSD: box.c,v 1.14 2007/05/28 15:01:54 blymn Exp $"); #endif #endif /* not lint */ @@ -48,5 +48,15 @@ __RCSID("$NetBSD: box.c,v 1.13 2003/08/07 16:44:19 agc Exp $"); int box(WINDOW *win, chtype vert, chtype hor) { - return (wborder (win, vert, vert, hor, hor, 0, 0, 0, 0)); + return (wborder(win, vert, vert, hor, hor, 0, 0, 0, 0)); +} + +int +box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return wborder_set(win, verch, verch, horch, horch, NULL, NULL, NULL, NULL); +#endif /* HAVE_WCHAR */ } diff --git a/lib/libcurses/cchar.c b/lib/libcurses/cchar.c index 0d1ce8bd9f8..a1df461311e 100644 --- a/lib/libcurses/cchar.c +++ b/lib/libcurses/cchar.c @@ -1,4 +1,4 @@ -/* $NetBSD: cchar.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: cchar.c,v 1.2 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: cchar.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: cchar.c,v 1.2 2007/05/28 15:01:54 blymn Exp $"); #endif /* not lint */ #include <string.h> diff --git a/lib/libcurses/clrtobot.c b/lib/libcurses/clrtobot.c index f4201d36720..0cd74f82a10 100644 --- a/lib/libcurses/clrtobot.c +++ b/lib/libcurses/clrtobot.c @@ -1,4 +1,4 @@ -/* $NetBSD: clrtobot.c,v 1.18 2006/02/05 17:39:52 jdc Exp $ */ +/* $NetBSD: clrtobot.c,v 1.19 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,10 +34,11 @@ #if 0 static char sccsid[] = "@(#)clrtobot.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: clrtobot.c,v 1.18 2006/02/05 17:39:52 jdc Exp $"); +__RCSID("$NetBSD: clrtobot.c,v 1.19 2007/05/28 15:01:54 blymn Exp $"); #endif #endif /* not lint */ +#include <stdlib.h> #include "curses.h" #include "curses_private.h" @@ -83,14 +84,28 @@ wclrtobot(WINDOW *win) for (y = starty; y < win->maxy; y++) { minx = -1; end = &win->lines[y]->line[win->maxx]; - for (sp = &win->lines[y]->line[startx]; sp < end; sp++) + for (sp = &win->lines[y]->line[startx]; sp < end; sp++) { +#ifndef HAVE_WCHAR if (sp->ch != win->bch || sp->attr != attr) { +#else + if (sp->ch != (wchar_t)btowc((int) win->bch) || + (sp->attr & WA_ATTRIBUTES) != 0 || sp->nsp) { +#endif /* HAVE_WCHAR */ maxx = sp; if (minx == -1) minx = sp - win->lines[y]->line; - sp->ch = win->bch; sp->attr = attr; +#ifdef HAVE_WCHAR + sp->ch = ( wchar_t )btowc(( int ) win->bch); + if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) + return ERR; + SET_WCOL( *sp, 1 ); +#else + sp->ch = win->bch; +#endif /* HAVE_WCHAR */ } + } + if (minx != -1) __touchline(win, y, minx, maxx - win->lines[y]->line); startx = 0; diff --git a/lib/libcurses/clrtoeol.c b/lib/libcurses/clrtoeol.c index 8ce3fddc9b2..a683aa60f4f 100644 --- a/lib/libcurses/clrtoeol.c +++ b/lib/libcurses/clrtoeol.c @@ -1,4 +1,4 @@ -/* $NetBSD: clrtoeol.c,v 1.22 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: clrtoeol.c,v 1.23 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,10 +34,11 @@ #if 0 static char sccsid[] = "@(#)clrtoeol.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: clrtoeol.c,v 1.22 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: clrtoeol.c,v 1.23 2007/05/28 15:01:54 blymn Exp $"); #endif #endif /* not lint */ +#include <stdlib.h> #include "curses.h" #include "curses_private.h" @@ -86,17 +87,30 @@ wclrtoeol(WINDOW *win) else attr = 0; for (sp = maxx; sp < end; sp++) +#ifndef HAVE_WCHAR if (sp->ch != win->bch || sp->attr != attr) { +#else + if (sp->ch != ( wchar_t )btowc(( int ) win->bch ) || + (sp->attr & WA_ATTRIBUTES) != attr || sp->nsp + || (WCOL(*sp) < 0)) { +#endif /* HAVE_WCHAR */ maxx = sp; if (minx == -1) minx = sp - win->lines[y]->line; - sp->ch = win->bch; sp->attr = attr; +#ifdef HAVE_WCHAR + sp->ch = ( wchar_t )btowc(( int ) win->bch); + if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) + return ERR; + SET_WCOL( *sp, 1 ); +#else + sp->ch = win->bch; +#endif /* HAVE_WCHAR */ } #ifdef DEBUG - __CTRACE(__CTRACE_ERASE, "CLRTOEOL: minx = %d, maxx = %d, " + __CTRACE(__CTRACE_ERASE, "CLRTOEOL: y = %d, minx = %d, maxx = %d, " "firstch = %d, lastch = %d\n", - minx, (int) (maxx - win->lines[y]->line), + y, minx, (int) (maxx - win->lines[y]->line), *win->lines[y]->firstchp, *win->lines[y]->lastchp); #endif /* Update firstch and lastch for the line. */ diff --git a/lib/libcurses/copywin.c b/lib/libcurses/copywin.c index 91b52995bb1..39daa666156 100644 --- a/lib/libcurses/copywin.c +++ b/lib/libcurses/copywin.c @@ -1,4 +1,4 @@ -/* $NetBSD: copywin.c,v 1.12 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: copywin.c,v 1.13 2007/05/28 15:01:54 blymn Exp $ */ /*- * Copyright (c) 1998-1999 Brett Lymn @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: copywin.c,v 1.12 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: copywin.c,v 1.13 2007/05/28 15:01:54 blymn Exp $"); #endif /* not lint */ #include <ctype.h> @@ -54,6 +54,10 @@ int copywin(const WINDOW *srcwin, WINDOW *dstwin, { int dcol; __LDATA *sp, *end; +#ifdef HAVE_WCHAR + cchar_t cc; + nschar_t *np; +#endif /* HAVE_WCHAR */ /* overwrite() and overlay() can come here with -ve srcwin coords */ if (sminrow < 0) { @@ -100,6 +104,18 @@ int copywin(const WINDOW *srcwin, WINDOW *dstwin, for (; dminrow <= dmaxrow; sminrow++, dminrow++) { sp = &srcwin->lines[sminrow]->line[smincol]; end = sp + dmaxcol - dmincol; +#ifdef HAVE_WCHAR + cc.vals[ 0 ] = sp->ch; + cc.attributes = sp->attr; + cc.elements = 1; + np = sp->nsp; + if (np) { + while ( np && cc.elements <= CURSES_CCHAR_MAX ) { + cc.vals[ cc.elements++ ] = np->ch; + np = np->next; + } + } +#endif /* HAVE_WCHAR */ if (dooverlay) { for (dcol = dmincol; sp <= end; dcol++, sp++) { /* XXX: Perhaps this should check for the @@ -107,13 +123,21 @@ int copywin(const WINDOW *srcwin, WINDOW *dstwin, */ if (!isspace(sp->ch)) { wmove(dstwin, dminrow, dcol); +#ifndef HAVE_WCHAR __waddch(dstwin, sp); +#else + wadd_wch( dstwin, &cc ); +#endif /* HAVE_WCHAR */ } } } else { wmove(dstwin, dminrow, dmincol); for (; sp <= end; sp++) { +#ifndef HAVE_WCHAR __waddch(dstwin, sp); +#else + wadd_wch( dstwin, &cc ); +#endif /* HAVE_WCHAR */ } } } diff --git a/lib/libcurses/cr_put.c b/lib/libcurses/cr_put.c index e5223753ce8..2b1e04ba2df 100644 --- a/lib/libcurses/cr_put.c +++ b/lib/libcurses/cr_put.c @@ -1,4 +1,4 @@ -/* $NetBSD: cr_put.c,v 1.24 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: cr_put.c,v 1.25 2007/05/28 15:01:54 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)cr_put.c 8.3 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: cr_put.c,v 1.24 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: cr_put.c,v 1.25 2007/05/28 15:01:54 blymn Exp $"); #endif #endif /* not lint */ @@ -75,8 +75,7 @@ __mvcur(int ly, int lx, int y, int x, int in_refresh) { #ifdef DEBUG __CTRACE(__CTRACE_OUTPUT, - "mvcur: moving cursor from (%d, %d) to (%d, %d)\n", - ly, lx, y, x); + "mvcur: moving cursor from (%d, %d) to (%d, %d)\n", ly, lx, y, x); #endif destcol = x; destline = y; @@ -88,11 +87,14 @@ __mvcur(int ly, int lx, int y, int x, int in_refresh) static void fgoto(in_refresh) - int in_refresh; + int in_refresh; { - int c, l; + int c, l; char cgp[128]; +#ifdef DEBUG + __CTRACE(__CTRACE_OUTPUT, "fgoto: in_refresh=%d\n", in_refresh); +#endif /* DEBUG */ if (destcol >= COLS) { destline += destcol / COLS; destcol %= COLS; @@ -166,6 +168,9 @@ fgoto(in_refresh) * Need this condition due to inconsistent behavior * of backspace on the last column. */ +#ifdef DEBUG + __CTRACE(__CTRACE_OUTPUT, "fgoto: cgp=%s\n", cgp); +#endif /* DEBUG */ if (outcol != COLS - 1 && plod((int) strlen(cgp), in_refresh) > 0) plod(0, in_refresh); @@ -181,13 +186,16 @@ fgoto(in_refresh) * Hard thing here is using home cursor on really deficient terminals. * Otherwise just use cursor motions, hacking use of tabs and overtabbing * and backspace. + * + * XXX this needs to be revisited for wide characters since we may output + * XXX more than one byte for a character. */ static int plodcnt, plodflg; static int plodput(c) - int c; + int c; { if (plodflg) --plodcnt; @@ -198,10 +206,14 @@ plodput(c) static int plod(cnt, in_refresh) - int cnt, in_refresh; + int cnt, in_refresh; { - int i, j, k, soutcol, soutline; + int i, j, k, soutcol, soutline; +#ifdef DEBUG + __CTRACE(__CTRACE_OUTPUT, "plod: cnt=%d, in_refresh=%d\n", + cnt, in_refresh); +#endif /* DEBUG */ plodcnt = plodflg = cnt; soutcol = outcol; soutline = outline; @@ -390,11 +402,32 @@ dontcr:while (outline < destline) { if (plodflg) /* Avoid a complex calculation. */ plodcnt--; else { +#ifndef HAVE_WCHAR i = curscr->lines[outline]->line[outcol].ch & __CHARTEXT; if (curscr->lines[outline]->line[outcol].attr == curscr->wattr) __cputchar(i); +#else + if ((curscr->lines[outline]->line[outcol].attr + & WA_ATTRIBUTES) + == curscr->wattr ) { + if (WCOL(curscr->lines[outline]->line[outcol]) > 0) { + __cputwchar(curscr->lines[outline]->line[outcol].ch); + __cursesi_putnsp(curscr->lines[outline]->line[outcol].nsp, + outline, + outcol); +#ifdef DEBUG + __CTRACE(__CTRACE_OUTPUT, + "plod: (%d,%d)WCOL(%d), " + "putwchar(%x)\n", + outline, outcol, + WCOL(curscr->lines[outline]->line[outcol]), + curscr->lines[outline]->line[outcol].ch); +#endif /* DEBUG */ + } + } +#endif /* HAVE_WCHAR */ else goto nondes; } @@ -412,6 +445,9 @@ out: if (plodflg) { outcol = soutcol; outline = soutline; } +#ifdef DEBUG + __CTRACE(__CTRACE_OUTPUT, "plod: returns %d\n", plodcnt); +#endif /* DEBUG */ return (plodcnt); } /* @@ -421,9 +457,9 @@ out: if (plodflg) { */ static int tabcol(col, ts) - int col, ts; + int col, ts; { - int offset; + int offset; if (col >= COLS) { offset = COLS * (col / COLS); diff --git a/lib/libcurses/curses.c b/lib/libcurses/curses.c index c39f0c5f0ae..1fcee10c828 100644 --- a/lib/libcurses/curses.c +++ b/lib/libcurses/curses.c @@ -1,4 +1,4 @@ -/* $NetBSD: curses.c,v 1.21 2003/08/07 16:44:20 agc Exp $ */ +/* $NetBSD: curses.c,v 1.22 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -30,21 +30,23 @@ */ #include <sys/cdefs.h> +#include <stdlib.h> #ifndef lint #if 0 static char sccsid[] = "@(#)curses.c 8.3 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: curses.c,v 1.21 2003/08/07 16:44:20 agc Exp $"); +__RCSID("$NetBSD: curses.c,v 1.22 2007/05/28 15:01:55 blymn Exp $"); #endif #endif /* not lint */ #include "curses.h" +#include "curses_private.h" /* Private. */ int __echoit = 1; /* If stty indicates ECHO. */ int __pfast; int __rawmode = 0; /* If stty indicates RAW mode. */ -int __noqch = 0; +int __noqch = 0; /* If terminal doesn't have * insert/delete line capabilities * for quick change on refresh. @@ -76,6 +78,11 @@ char *__tc_ac, *__tc_AB, *__tc_ae, *__tc_AF, *__tc_AL, *__tc_uc, *__tc_ue, *__tc_UP, *__tc_up, *__tc_us, *__tc_vb, *__tc_ve, *__tc_vi, *__tc_vs; +#ifdef HAVE_WCHAR +char *__tc_Xh, *__tc_Xl, *__tc_Xo, *__tc_Xr, *__tc_Xt, + *__tc_Xv; +#endif /* HAVE_WCHAR */ + /* * Public. * @@ -96,3 +103,88 @@ const char *Def_term = "unknown"; /* Default terminal type. */ char __GT; /* Gtty indicates tabs. */ char __NONL; /* Term can't hack LF doing a CR. */ char __UPPERCASE; /* Terminal is uppercase only. */ + +#ifdef HAVE_WCHAR +/* + * Copy the non-spacing character list (src_nsp) to the given character, + * allocate or free storage as required. + */ +int +_cursesi_copy_nsp(nschar_t *src_nsp, struct __ldata *ch) +{ + nschar_t *np, *tnp, *pnp; + + pnp = NULL; + np = src_nsp; + if (np) { + tnp = ch->nsp; + while (np) { + if (tnp) { + tnp->ch = np->ch; + pnp = tnp; + tnp = tnp->next; + } else { + tnp = (nschar_t *)malloc(sizeof(nschar_t)); + if (!tnp) + return ERR; + tnp->ch = np->ch; + pnp->next = tnp; + tnp->next = NULL; + pnp = tnp; + tnp = NULL; + } + np = np->next; + } + np = tnp; + if (np) { + pnp->next = NULL; + __cursesi_free_nsp(np); + } + } else { + if (ch->nsp) { + __cursesi_free_nsp(ch->nsp); + ch->nsp = NULL; + } + } + + return OK; +} + +/* + * Free the storage associated with a non-spacing character - traverse the + * linked list until all storage is done. + */ +void +__cursesi_free_nsp(nschar_t *inp) +{ + nschar_t *tnp, *np; + + np = inp; + if (np) { + while (np) { + tnp = np->next; + free(np); + np = tnp; + } + } +} + +/* + * Traverse all the cells in the given window free'ing the non-spacing + * character storage. + */ +void +__cursesi_win_free_nsp(WINDOW *win) +{ + int i, j; + __LDATA *sp; + + for (i = 0; i < win->maxy; i++) { + for (sp = win->lines[i]->line, j = 0; j < win->maxx; + j++, sp++) { + __cursesi_free_nsp(sp->nsp); + } + } +} + +#endif diff --git a/lib/libcurses/curses.h b/lib/libcurses/curses.h index d4c8393fab9..a5e5fe1a428 100644 --- a/lib/libcurses/curses.h +++ b/lib/libcurses/curses.h @@ -1,4 +1,4 @@ -/* $NetBSD: curses.h,v 1.87 2005/08/09 02:33:38 christos Exp $ */ +/* $NetBSD: curses.h,v 1.88 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -29,6 +29,12 @@ * SUCH DAMAGE. * * @(#)curses.h 8.5 (Berkeley) 4/29/95 + * + * Modified by Ruibiao Qiu <ruibiao@arl.wustl.edu,ruibiao@gmail.com> 2005 + * to add wide character support + * - Add complex character structure (cchar_t) + * - Add definitions of wide character routines + * - Add KEY_CODE_YES */ #ifndef _CURSES_H_ @@ -48,6 +54,23 @@ typedef wchar_t chtype; typedef wchar_t attr_t; +#ifdef HAVE_WCHAR +/* + * The complex character structure required by the X/Open reference to be used in + * functions such as in_wchstr(). It includes a string of up to 8 wide characters + * and its length, an attribute, and a color-pair. + */ +#define CURSES_CCHAR_MAX 8 +#define CCHARW_MAX 5 +typedef struct { + attr_t attributes; /* character attributes */ + unsigned elements; /* number of wide char in vals[] */ + wchar_t vals[CURSES_CCHAR_MAX]; /* wide chars including non-spacing */ +} cchar_t; +#else +typedef chtype cchar_t; +#endif /* HAVE_WCHAR */ + /* C++ already defines bool. */ #ifndef __cplusplus typedef char bool; @@ -181,6 +204,7 @@ typedef char bool; #define KEY_MOUSE 0x199 /* Mouse event has occurred */ #define KEY_RESIZE 0x200 /* Resize event has occurred */ #define KEY_MAX 0x240 /* maximum extended key value */ +#define KEY_CODE_YES 0x241 /* A function key pressed */ #include <unctrl.h> @@ -229,6 +253,25 @@ typedef struct __screen SCREEN; #define A_CHARTEXT __CHARTEXT #define A_COLOR __COLOR +#ifdef HAVE_WCHAR +#define WA_ATTRIBUTES 0x03ffffff /* Wide character attributes mask */ +#define WA_ALTCHARSET __ALTCHARSET /* Alternate character set */ +#define WA_BLINK __BLINK /* Blinking */ +#define WA_BOLD __BOLD /* Extra bright or bold */ +#define WA_DIM __DIM /* Half bright */ +#define WA_PROTECT __PROTECT /* Protected */ +#define WA_REVERSE __REVERSE /* Reverse video */ +#define WA_STANDOUT __STANDOUT /* Best highlighting mode */ +#define WA_UNDERLINE __UNDERSCORE /* Underlining */ +#define WA_INVIS 0x00000001 /* Invisible */ +#define WA_LOW 0x00000002 /* Low highlight */ +#define WA_TOP 0x00000004 /* Top highlight */ +#define WA_HORIZONTAL 0x00000008 /* Horizontal highlight */ +#define WA_VERTICAL 0x00000010 /* Vertical highlight */ +#define WA_LEFT 0x00000020 /* Left highlight */ +#define WA_RIGHT 0x00000040 /* Right highlight */ +#endif /* HAVE_WCHAR */ + /* * Alternate character set definitions */ @@ -267,6 +310,36 @@ extern chtype _acs_char[NUM_ACS]; #define ACS_VLINE _acs_char[__UC_CAST('x')] #define ACS_BULLET _acs_char[__UC_CAST('~')] +#ifdef HAVE_WCHAR +extern cchar_t _wacs_char[NUM_ACS]; + +#define WACS_RARROW _wacs_char[(unsigned char)'+'].vals[0] +#define WACS_LARROW _wacs_char[(unsigned char)','].vals[0] +#define WACS_UARROW _wacs_char[(unsigned char)'-'].vals[0] +#define WACS_DARROW _wacs_char[(unsigned char)'.'].vals[0] +#define WACS_BLOCK _wacs_char[(unsigned char)'0'].vals[0] +#define WACS_DIAMOND _wacs_char[(unsigned char)'`'].vals[0] +#define WACS_CKBOARD _wacs_char[(unsigned char)'a'].vals[0] +#define WACS_DEGREE _wacs_char[(unsigned char)'f'].vals[0] +#define WACS_PLMINUS _wacs_char[(unsigned char)'g'].vals[0] +#define WACS_BOARD _wacs_char[(unsigned char)'h'].vals[0] +#define WACS_LANTERN _wacs_char[(unsigned char)'i'].vals[0] +#define WACS_LRCORNER _wacs_char[(unsigned char)'j'].vals[0] +#define WACS_URCORNER _wacs_char[(unsigned char)'k'].vals[0] +#define WACS_ULCORNER _wacs_char[(unsigned char)'l'].vals[0] +#define WACS_LLCORNER _wacs_char[(unsigned char)'m'].vals[0] +#define WACS_PLUS _wacs_char[(unsigned char)'n'].vals[0] +#define WACS_HLINE _wacs_char[(unsigned char)'q'].vals[0] +#define WACS_S1 _wacs_char[(unsigned char)'o'].vals[0] +#define WACS_S9 _wacs_char[(unsigned char)'s'].vals[0] +#define WACS_LTEE _wacs_char[(unsigned char)'t'].vals[0] +#define WACS_RTEE _wacs_char[(unsigned char)'u'].vals[0] +#define WACS_BTEE _wacs_char[(unsigned char)'v'].vals[0] +#define WACS_TTEE _wacs_char[(unsigned char)'w'].vals[0] +#define WACS_VLINE _wacs_char[(unsigned char)'x'].vals[0] +#define WACS_BULLET _wacs_char[(unsigned char)'~'].vals[0] +#endif /* HAVE_WCHAR */ + /* System V compatibility */ #define ACS_SBBS ACS_LRCORNER #define ACS_BBSS ACS_URCORNER @@ -698,9 +771,135 @@ int wunderend(WINDOW *); int wunderscore(WINDOW *); int wvline(WINDOW *, chtype, int); +int insnstr(const char *, int); +int insstr(const char *); +int mvinsnstr(int, int, const char *, int); +int mvinsstr(int, int, const char *); +int mvwinsnstr(WINDOW *, int, int, const char *, int); +int mvwinsstr(WINDOW *, int, int, const char *); +int winsnstr(WINDOW *, const char *, int); +int winsstr(WINDOW *, const char *); + +/* wide character support routines */ +/* return ERR when HAVE_WCHAR is not defined */ +/* add */ +int add_wch(const cchar_t *); +int wadd_wch(WINDOW *, const cchar_t *); +int mvadd_wch(int, int, const cchar_t *); +int mvwadd_wch(WINDOW *, int, int, const cchar_t *); + +int add_wchnstr(const cchar_t *, int); +int add_wchstr(const cchar_t *); +int wadd_wchnstr(WINDOW *, const cchar_t *, int); +int wadd_wchstr(WINDOW *, const cchar_t *); +int mvadd_wchnstr(int, int, const cchar_t *, int); +int mvadd_wchstr(int, int, const cchar_t *); +int mvwadd_wchnstr(WINDOW *, int, int, const cchar_t *, int); +int mvwadd_wchstr(WINDOW *, int, int, const cchar_t *); + +int addnwstr(const wchar_t *, int); +int addwstr(const wchar_t *); +int mvaddnwstr(int, int x, const wchar_t *, int); +int mvaddwstr(int, int x, const wchar_t *); +int mvwaddnwstr(WINDOW *, int, int, const wchar_t *, int); +int mvwaddwstr(WINDOW *, int, int, const wchar_t *); +int waddnwstr(WINDOW *, const wchar_t *, int); +int waddwstr(WINDOW *, const wchar_t *); + +int echo_wchar(const cchar_t *); +int wecho_wchar(WINDOW *, const cchar_t *); +int pecho_wchar(WINDOW *, const cchar_t *); + +/* insert */ +int ins_wch(const cchar_t *); +int wins_wch(WINDOW *, const cchar_t *); +int mvins_wch(int, int, const cchar_t *); +int mvwins_wch(WINDOW *, int, int, const cchar_t *); + +int ins_nwstr(const wchar_t *, int); +int ins_wstr(const wchar_t *); +int mvins_nwstr(int, int, const wchar_t *, int); +int mvins_wstr(int, int, const wchar_t *); +int mvwins_nwstr(WINDOW *, int, int, const wchar_t *, int); +int mvwins_wstr(WINDOW *, int, int, const wchar_t *); +int wins_nwstr(WINDOW *, const wchar_t *, int); +int wins_wstr(WINDOW *, const wchar_t *); + +/* input */ +int get_wch(wint_t *); +int unget_wch(const wchar_t); +int mvget_wch(int, int, wint_t *); +int mvwget_wch(WINDOW *, int, int, wint_t *); +int wget_wch(WINDOW *, wint_t *); + +int getn_wstr(wchar_t *, int); +int get_wstr(wchar_t *); +int mvgetn_wstr(int, int, wchar_t *, int); +int mvget_wstr(int, int, wchar_t *); +int mvwgetn_wstr(WINDOW *, int, int, wchar_t *, int); +int mvwget_wstr(WINDOW *, int, int, wchar_t *); +int wgetn_wstr(WINDOW *, wchar_t *, int); +int wget_wstr(WINDOW *, wchar_t *); + +int in_wch(cchar_t *); +int mvin_wch(int, int, cchar_t *); +int mvwin_wch(WINDOW *, int, int, cchar_t *); +int win_wch(WINDOW *, cchar_t *); + +int in_wchnstr(cchar_t *, int); +int in_wchstr(cchar_t *); +int mvin_wchnstr(int, int, cchar_t *, int); +int mvin_wchstr(int, int, cchar_t *); +int mvwin_wchnstr(WINDOW *, int, int, cchar_t *, int); +int mvwin_wchstr(WINDOW *, int, int, cchar_t *); +int win_wchnstr(WINDOW *, cchar_t *, int); +int win_wchstr(WINDOW *, cchar_t *); + +int innwstr(wchar_t *, int); +int inwstr(wchar_t *); +int mvinnwstr(int, int, wchar_t *, int); +int mvinwstr(int, int, wchar_t *); +int mvwinnwstr(WINDOW *, int, int, wchar_t *, int); +int mvwinwstr(WINDOW *, int, int, wchar_t *); +int winnwstr(WINDOW *, wchar_t *, int); +int winwstr(WINDOW *, wchar_t *); + +/* cchar handlgin */ +int setcchar(cchar_t *, const wchar_t *, const attr_t, short, const void *); +int getcchar(const cchar_t *, wchar_t *, attr_t *, short *, void *); + +/* misc */ +char *key_name( wchar_t ); +int border_set(const cchar_t *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *); +int wborder_set(WINDOW *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *, const cchar_t *); +int box_set(WINDOW *, const cchar_t *, const cchar_t *); +int erasewchar(wchar_t *); +int killwchar(wchar_t *); +int hline_set(const cchar_t *, int); +int mvhline_set(int, int, const cchar_t *, int); +int mvvline_set(int, int, const cchar_t *, int); +int mvwhline_set(WINDOW *, int, int, const cchar_t *, int); +int mvwvline_set(WINDOW *, int, int, const cchar_t *, int); +int vline_set(const cchar_t *, int); +int whline_set(WINDOW *, const cchar_t *, int); +int wvline_set(WINDOW *, const cchar_t *, int); +int bkgrnd(const cchar_t *); +void bkgrndset(const cchar_t *); +int getbkgrnd(cchar_t *); +int wbkgrnd(WINDOW *, const cchar_t *); +void wbkgrndset(WINDOW *, const cchar_t *); +int wgetbkgrnd(WINDOW *, cchar_t *); + /* Private functions that are needed for user programs prototypes. */ int __cputchar(int); int __waddbytes(WINDOW *, const char *, int, attr_t); +#ifdef HAVE_WCHAR +int __cputwchar( wchar_t ); +#endif /* HAVE_WCHAR */ __END_DECLS #endif /* !_CURSES_H_ */ diff --git a/lib/libcurses/curses_private.h b/lib/libcurses/curses_private.h index 8df543ce834..f06fab464f7 100644 --- a/lib/libcurses/curses_private.h +++ b/lib/libcurses/curses_private.h @@ -1,4 +1,4 @@ -/* $NetBSD: curses_private.h,v 1.39 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: curses_private.h,v 1.40 2007/05/28 15:01:55 blymn Exp $ */ /*- * Copyright (c) 1998-2000 Brett Lymn @@ -29,6 +29,16 @@ * */ +/* Modified by Ruibiao Qiu <ruibiao@arl.wustl.edu,ruibiao@gmail.com> + * to add support for wide characters + * Changes: + * - Add a compiler variable HAVE_WCHAR for wide character only code + * - Add a pointer to liked list of non-spacing characters in __ldata + * and the macro to access the width field in the attribute field + * - Add a circular input character buffer in __screen to handle wide + * character input (used in get_wch()) + */ + #include <termios.h> /* Private structure definitions for curses. */ @@ -59,6 +69,19 @@ extern char *__tc_ac, *__tc_AB, *__tc_ae, *__tc_AF, *__tc_AL, *__tc_uc, *__tc_ue, *__tc_UP, *__tc_up, *__tc_us, *__tc_vb, *__tc_ve, *__tc_vi, *__tc_vs; +#ifdef HAVE_WCHAR +extern char *__tc_Xh, *__tc_Xl, *__tc_Xo, *__tc_Xr, *__tc_Xt, + *__tc_Xv; +/* + * Add a list of non-spacing characters to each spacing + * character in a singly linked list + */ +typedef struct nschar_t { + wchar_t ch; /* Non-spacing character */ + struct nschar_t *next; /* Next non-spacing character */ +} nschar_t; +#endif /* HAVE_WCHAR */ + /* * A window an array of __LINE structures pointed to by the 'lines' pointer. * A line is an array of __LDATA structures pointed to by the 'line' pointer. @@ -73,14 +96,31 @@ extern char *__tc_ac, *__tc_AB, *__tc_ae, *__tc_AF, *__tc_AL, struct __ldata { wchar_t ch; /* Character */ attr_t attr; /* Attributes */ +#ifdef HAVE_WCHAR + nschar_t *nsp; /* Foreground non-spacing character pointer */ +#endif /* HAVE_WCHAR */ }; +#ifdef HAVE_WCHAR +/* macros to extract the width of a wide character */ +#define __WCWIDTH 0xfc000000 +#define WCW_SHIFT 26 +#define WCOL(wc) ((((unsigned) (wc).attr) >> WCW_SHIFT ) > MB_LEN_MAX ? ((int)(((unsigned) (wc).attr ) >> WCW_SHIFT )) - 64 : ((int)(((unsigned) (wc).attr ) >> WCW_SHIFT))) +#define SET_WCOL(c, w) do { \ + ((c).attr) = ((((c).attr) & WA_ATTRIBUTES ) | ((w) << WCW_SHIFT )); \ +} while(/*CONSTCOND*/0) +#define BGWCOL(wc) ((((wc).battr) >> WCW_SHIFT ) > MB_LEN_MAX ? (((wc).battr ) >> WCW_SHIFT ) - 64 : (((wc).battr ) >> WCW_SHIFT )) +#define SET_BGWCOL(c, w) do { \ + ((c).battr) = ((((c).battr) & WA_ATTRIBUTES ) | ((w) << WCW_SHIFT )); \ +} while(/*CONSTCOND*/0) +#endif /* HAVE_WCHAR */ + #define __LDATASIZE (sizeof(__LDATA)) struct __line { #ifdef DEBUG #define SENTINEL_VALUE 0xaac0ffee - + unsigned int sentinel; /* try to catch line overflows */ #endif #define __ISDIRTY 0x01 /* Line is dirty. */ @@ -125,11 +165,20 @@ struct __window { /* Window structure. */ int pbegy, pbegx, sbegy, sbegx, smaxy, smaxx; /* Saved prefresh() values */ +#ifdef HAVE_WCHAR + nschar_t *bnsp; /* Background non-spacing char list */ +#endif /* HAVE_WCHAR */ }; /* Set of attributes unset by 'me' - 'mb', 'md', 'mh', 'mk', 'mp' and 'mr'. */ +#ifndef HAVE_WCHAR #define __TERMATTR \ (__REVERSE | __BLINK | __DIM | __BOLD | __BLANK | __PROTECT) +#else +#define __TERMATTR \ + (__REVERSE | __BLINK | __DIM | __BOLD | __BLANK | __PROTECT \ + | WA_TOP | WA_LOW | WA_LEFT | WA_RIGHT | WA_HORIZONTAL | WA_VERTICAL) +#endif /* HAVE_WCHAR */ struct __winlist { struct __window *winp; /* The window. */ @@ -203,10 +252,18 @@ struct __screen { *tc_SF, *tc_Sf, *tc_sf, *tc_so, *tc_sp, *tc_SR, *tc_sr, *tc_ta, *tc_te, *tc_ti, *tc_uc, *tc_ue, *tc_UP, *tc_up, *tc_us, +#ifndef HAVE_WCHAR *tc_vb, *tc_ve, *tc_vi, *tc_vs; +#else + *tc_vb, *tc_ve, *tc_vi, *tc_vs, *tc_Xh, + *tc_Xl, *tc_Xo, *tc_Xr, *tc_Xt, *tc_Xv; +#endif /* HAVE_WCHAR */ char CA; int str_count; chtype acs_char[NUM_ACS]; +#ifdef HAVE_WCHAR + cchar_t wacs_char[ NUM_ACS ]; +#endif /* HAVE_WCHAR */ struct __color colours[MAX_COLORS]; struct __pair colour_pairs[MAX_PAIRS]; attr_t nca; @@ -247,6 +304,15 @@ struct __screen { int notty; int half_delay; int resized; +#ifdef HAVE_WCHAR +#define MB_LEN_MAX 8 +#define MAX_CBUF_SIZE MB_LEN_MAX + int cbuf_head; /* header to cbuf */ + int cbuf_tail; /* tail to cbuf */ + int cbuf_cur; /* the current char in cbuf */ + mbstate_t sp; /* wide char processing state */ + char cbuf[ MAX_CBUF_SIZE ]; /* input character buffer */ +#endif /* HAVE_WCHAR */ }; @@ -281,6 +347,11 @@ void __cputchar_args(char, void *); void _cursesi_free_keymap(keymap_t *); int _cursesi_gettmode(SCREEN *); void _cursesi_reset_acs(SCREEN *); +int _cursesi_addbyte(WINDOW *, __LINE **, int *, int *, int , attr_t); +int _cursesi_addwchar(WINDOW *, __LINE **, int *, int *, const cchar_t *); +#ifdef HAVE_WCHAR +void _cursesi_reset_wacs(SCREEN *); +#endif /* HAVE_WCHAR */ void _cursesi_resetterm(SCREEN *); int _cursesi_setterm(char *, SCREEN *); int __delay(void); @@ -289,6 +360,15 @@ u_int __hash_more(const void *, size_t, u_int); void __id_subwins(WINDOW *); void __init_getch(SCREEN *); void __init_acs(SCREEN *); +#ifdef HAVE_WCHAR +void __init_get_wch(SCREEN *); +void __init_wacs(SCREEN *); +void __cputwchar_args( wchar_t, void * ); +int _cursesi_copy_nsp(nschar_t *, struct __ldata *); +void __cursesi_free_nsp(nschar_t *); +void __cursesi_win_free_nsp(WINDOW *); +void __cursesi_putnsp(nschar_t *, const int, const int); +#endif /* HAVE_WCHAR */ char *__longname(char *, char *); /* Original BSD version */ int __mvcur(int, int, int, int, int); WINDOW *__newwin(SCREEN *, int, int, int, int, int); @@ -319,6 +399,9 @@ void __unsetattr(int); void __unset_color(WINDOW *win); int __waddch(WINDOW *, __LDATA *); int __wgetnstr(WINDOW *, char *, int); +#ifdef HAVE_WCHAR +int __wgetn_wstr(WINDOW *, wchar_t *, int); +#endif /* HAVE_WCHAR */ void __winch_signal_handler(int); /* Private #defines. */ diff --git a/lib/libcurses/delch.c b/lib/libcurses/delch.c index 442aa3581df..bf99f7a148d 100644 --- a/lib/libcurses/delch.c +++ b/lib/libcurses/delch.c @@ -1,4 +1,4 @@ -/* $NetBSD: delch.c,v 1.19 2006/02/05 17:39:52 jdc Exp $ */ +/* $NetBSD: delch.c,v 1.20 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,11 +34,12 @@ #if 0 static char sccsid[] = "@(#)delch.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: delch.c,v 1.19 2006/02/05 17:39:52 jdc Exp $"); +__RCSID("$NetBSD: delch.c,v 1.20 2007/05/28 15:01:55 blymn Exp $"); #endif #endif /* not lint */ #include <string.h> +#include <stdlib.h> #include "curses.h" #include "curses_private.h" @@ -56,7 +57,7 @@ delch(void) /* * mvdelch -- - * Do a delete-char on the line at (y, x) on stdscr. + * Do a delete-char on the line at (y, x) on stdscr. */ int mvdelch(int y, int x) @@ -66,7 +67,7 @@ mvdelch(int y, int x) /* * mvwdelch -- - * Do a delete-char on the line at (y, x) of the given window. + * Do a delete-char on the line at (y, x) of the given window. */ int mvwdelch(WINDOW *win, int y, int x) @@ -88,6 +89,7 @@ wdelch(WINDOW *win) { __LDATA *end, *temp1, *temp2; +#ifndef HAVE_WCHAR end = &win->lines[win->cury]->line[win->maxx - 1]; temp1 = &win->lines[win->cury]->line[win->curx]; temp2 = temp1 + 1; @@ -96,10 +98,53 @@ wdelch(WINDOW *win) temp1++, temp2++; } temp1->ch = win->bch; + if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) + return ERR; if (__using_color && win != curscr) temp1->attr = win->battr & __COLOR; else temp1->attr = 0; + SET_WCOL( *temp1, 1 ); __touchline(win, (int) win->cury, (int) win->curx, (int) win->maxx - 1); return (OK); +#else + int cw, sx; + nschar_t *np, *tnp; + + end = &win->lines[win->cury]->line[win->maxx - 1]; + sx = win->curx; + temp1 = &win->lines[win->cury]->line[win->curx]; + cw = WCOL( *temp1 ); + if ( cw < 0 ) { + temp1 += cw; + sx += cw; + cw = WCOL( *temp1 ); + } + np = temp1->nsp; + if (np) { + while ( np ) { + tnp = np->next; + free( np ); + np = tnp; + } + temp1->nsp = NULL; + } + if ( sx + cw < win->maxx ) { + temp2 = temp1 + cw; + while ( temp1 < end - ( cw - 1 )) { + ( void )memcpy( temp1, temp2, sizeof( __LDATA )); + temp1++, temp2++; + } + } + while ( temp1 <= end ) { + temp1->ch = ( wchar_t )btowc(( int ) win->bch ); + temp1->attr = 0; + if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) + return ERR; + SET_WCOL(*temp1, 1); + temp1++; + } + __touchline(win, (int) win->cury, sx, (int) win->maxx - 1); + return (OK); +#endif /* HAVE_WCHAR */ } diff --git a/lib/libcurses/delwin.c b/lib/libcurses/delwin.c index cf368650cfa..b8a95b09075 100644 --- a/lib/libcurses/delwin.c +++ b/lib/libcurses/delwin.c @@ -1,4 +1,4 @@ -/* $NetBSD: delwin.c,v 1.15 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: delwin.c,v 1.16 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)delwin.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: delwin.c,v 1.15 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: delwin.c,v 1.16 2007/05/28 15:01:55 blymn Exp $"); #endif #endif /* not lint */ @@ -57,6 +57,13 @@ delwin(WINDOW *win) #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "delwin(%p)\n", win); #endif + /* + * Free any storage used by non-spacing characters in the window. + */ +#ifdef HAVE_WCHAR + __cursesi_win_free_nsp(win); +#endif + if (win->orig == NULL) { /* * If we are the original window, delete the space for all diff --git a/lib/libcurses/echo_wchar.c b/lib/libcurses/echo_wchar.c index 3244f00b6a5..a7a9e7cd604 100644 --- a/lib/libcurses/echo_wchar.c +++ b/lib/libcurses/echo_wchar.c @@ -1,4 +1,4 @@ -/* $NetBSD: echo_wchar.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: echo_wchar.c,v 1.2 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: echo_wchar.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: echo_wchar.c,v 1.2 2007/05/28 15:01:55 blymn Exp $"); #endif /* not lint */ #include "curses.h" diff --git a/lib/libcurses/erase.c b/lib/libcurses/erase.c index ffd341a7bb3..879612fb9a3 100644 --- a/lib/libcurses/erase.c +++ b/lib/libcurses/erase.c @@ -1,4 +1,4 @@ -/* $NetBSD: erase.c,v 1.22 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: erase.c,v 1.23 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,10 +34,12 @@ #if 0 static char sccsid[] = "@(#)erase.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: erase.c,v 1.22 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: erase.c,v 1.23 2007/05/28 15:01:55 blymn Exp $"); #endif #endif /* not lint */ +#include <stdlib.h> + #include "curses.h" #include "curses_private.h" @@ -78,9 +80,21 @@ werase(WINDOW *win) start = win->lines[y]->line; end = &start[win->maxx]; for (sp = start; sp < end; sp++) +#ifndef HAVE_WCHAR if (sp->ch != win->bch || sp->attr != 0) { - sp->ch = win->bch; +#else + if (sp->ch != ( wchar_t )btowc(( int ) win->bch ) || + (sp->attr & WA_ATTRIBUTES) != 0 || sp->nsp) { +#endif /* HAVE_WCHAR */ sp->attr = attr; +#ifdef HAVE_WCHAR + sp->ch = ( wchar_t )btowc(( int ) win->bch); + if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) + return ERR; + SET_WCOL( *sp, 1 ); +#else + sp->ch = win->bch; +#endif /* HAVE_WCHAR */ } } /* diff --git a/lib/libcurses/get_wch.c b/lib/libcurses/get_wch.c index f688513fbcc..ece5584a137 100644 --- a/lib/libcurses/get_wch.c +++ b/lib/libcurses/get_wch.c @@ -1,4 +1,4 @@ -/* $NetBSD: get_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: get_wch.c,v 1.2 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: get_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: get_wch.c,v 1.2 2007/05/28 15:01:55 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -48,6 +48,7 @@ __RCSID("$NetBSD: get_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); #include "keymap.h" static short wstate; /* state of the wcinkey function */ +extern short state; /* storage declared in getch.c */ /* prototypes for private functions */ static int inkey(wchar_t *wc, int to, int delay); @@ -122,8 +123,8 @@ inkey(wchar_t *wc, int to, int delay) k = (wchar_t) c; #ifdef DEBUG - __CTRACE("inkey (wstate normal) got '%s'\n", - unctrl(k)); + __CTRACE(__CTRACE_INPUT, + "inkey (wstate normal) got '%s'\n", unctrl(k)); #endif inbuf[ *end ] = k; @@ -131,8 +132,9 @@ inkey(wchar_t *wc, int to, int delay) *working = *start; wstate = INKEY_ASSEMBLING; /* go to assembling state */ #ifdef DEBUG - __CTRACE("[inkey]NORM=>ASSEMBLING:start(%d),current(%d),end(%d)\n", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: NORM=>ASSEMBLING: start(%d), " + "current(%d), end(%d)\n", *start, *working, *end); #endif /* DEBUG */ } else if (wstate == INKEY_BACKOUT) { k = inbuf[*working]; @@ -141,8 +143,10 @@ inkey(wchar_t *wc, int to, int delay) /* if so, switch to assembling */ wstate = INKEY_ASSEMBLING; #ifdef DEBUG - __CTRACE("[inkey]BACKOUT=>ASSEMBLING, start(%d),current(%d),end(%d)\n", - *start, *working, *end); + __CTRACE(__CTRACE_INPUT, + "inkey: BACKOUT=>ASSEMBLING, start(%d), " + "current(%d), end(%d)\n", + *start, *working, *end); #endif /* DEBUG */ } } else if (wstate == INKEY_ASSEMBLING) { @@ -175,8 +179,8 @@ inkey(wchar_t *wc, int to, int delay) k = (wchar_t) c; #ifdef DEBUG - __CTRACE("inkey (wstate assembling) got '%s'\n", - unctrl(k)); + __CTRACE(__CTRACE_INPUT, + "inkey (wstate assembling) got '%s'\n", unctrl(k)); #endif /* DEBUG */ if (feof(infd)) { /* inter-char T/O, start backout */ clearerr(infd); @@ -187,16 +191,20 @@ inkey(wchar_t *wc, int to, int delay) k = inbuf[*start]; wstate = INKEY_TIMEOUT; #ifdef DEBUG - __CTRACE("[inkey]ASSEMBLING=>TIMEOUT,start(%d),current(%d),end(%d)\n", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: ASSEMBLING=>TIMEOUT, start(%d), " + "current(%d), end(%d)\n", + *start, *working, *end); #endif /* DEBUG */ } else { inbuf[ *end ] = k; *working = *end; *end = ( *end + 1 ) % MAX_CBUF_SIZE; #ifdef DEBUG - __CTRACE("[inkey]ASSEMBLING:start(%d),current(%d),end(%d)", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: ASSEMBLING: start(%d), " + "current(%d), end(%d)", + *start, *working, *end); #endif /* DEBUG */ } } else if (wstate == INKEY_WCASSEMBLING) { @@ -229,7 +237,8 @@ inkey(wchar_t *wc, int to, int delay) k = (wchar_t) c; #ifdef DEBUG - __CTRACE("inkey (wstate wcassembling) got '%s'\n", + __CTRACE(__CTRACE_INPUT, + "inkey (wstate wcassembling) got '%s'\n", unctrl(k)); #endif if (feof(infd)) { /* inter-char T/O, start backout */ @@ -244,14 +253,18 @@ inkey(wchar_t *wc, int to, int delay) if (*start == *end) { state = wstate = INKEY_NORM; #ifdef DEBUG - __CTRACE("[inkey]WCASSEMBLING=>NORM,start(%d),current(%d),end(%d)", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: WCASSEMBLING=>NORM, " + "start(%d), current(%d), end(%d)", + *start, *working, *end); #endif /* DEBUG */ } else { state = wstate = INKEY_BACKOUT; #ifdef DEBUG - __CTRACE("[inkey]WCASSEMBLING=>BACKOUT,start(%d),current(%d),end(%d)", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: WCASSEMBLING=>BACKOUT, " + "start(%d), current(%d), end(%d)", + *start, *working, *end); #endif /* DEBUG */ } return OK; @@ -261,14 +274,17 @@ inkey(wchar_t *wc, int to, int delay) *working = *end; *end = ( *end + 1 ) % MAX_CBUF_SIZE; #ifdef DEBUG - __CTRACE("[inkey]WCASSEMBLING[head(%d),current(%d),tail(%d)]\n", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: WCASSEMBLING[head(%d), " + "urrent(%d), tail(%d)]\n", + *start, *working, *end); #endif /* DEBUG */ ret = mbrtowc( wc, inbuf + (*working), 1, &_cursesi_screen->sp ); #ifdef DEBUG - __CTRACE("[inkey]mbrtowc returns %d,wc(%x)\n", - ret, *wc ); + __CTRACE(__CTRACE_INPUT, + "inkey: mbrtowc returns %d, wc(%x)\n", + ret, *wc ); #endif /* DEBUG */ if ( ret == -2 ) { *working = (*working + 1) @@ -282,32 +298,41 @@ inkey(wchar_t *wc, int to, int delay) *wc = inbuf[ *start ]; *working = *start = ( *start + 1 ) % MAX_CBUF_SIZE; #ifdef DEBUG - __CTRACE("[inkey]Invalid wide char(%x)[head(%d),current(%d),tail(%d)]\n", - *wc, *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: Invalid wide char(%x) " + "[head(%d), current(%d), " + "tail(%d)]\n", + *wc, *start, *working, *end); #endif /* DEBUG */ } else { /* > 0 */ /* return the wide character */ *start = *working = (*working + ret)%MAX_CBUF_SIZE; #ifdef DEBUG - __CTRACE("[inkey]Wide char found(%x)[head(%d),current(%d),tail(%d)]\n", - *wc, *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: Wide char found(%x) " + "[head(%d), current(%d), " + "tail(%d)]\n", + *wc, *start, *working, *end); #endif /* DEBUG */ } if (*start == *end) { /* only one char processed */ state = wstate = INKEY_NORM; #ifdef DEBUG - __CTRACE("[inkey]WCASSEMBLING=>NORM,start(%d),current(%d),end(%d)", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: WCASSEMBLING=>NORM, " + "start(%d), current(%d), end(%d)", + *start, *working, *end); #endif /* DEBUG */ } else { /* otherwise we must have more than one char to backout */ state = wstate = INKEY_BACKOUT; #ifdef DEBUG - __CTRACE( - "[inkey]WCASSEMBLING=>BACKOUT,start(%d),current(%d),end(%d)", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: WCASSEMBLING=>BACKOUT, " + "start(%d), current(%d), end(%d)", + *start, *working, *end); #endif /* DEBUG */ } return OK; @@ -328,7 +353,8 @@ inkey(wchar_t *wc, int to, int delay) && (current->key[mapping]->enable == FALSE))) { /* wide character specific code */ #ifdef DEBUG - __CTRACE("[inkey]Checking for wide char\n" ); + __CTRACE(__CTRACE_INPUT, + "inkey: Checking for wide char\n"); #endif /* DEBUG */ mbrtowc( NULL, NULL, 1, &_cursesi_screen->sp ); *working = *start; @@ -337,14 +363,16 @@ inkey(wchar_t *wc, int to, int delay) if ( !mlen ) return ERR; #ifdef DEBUG - __CTRACE("[inkey]Check wide char[head(%d),current(%d),tail(%d),mlen(%d)]\n", - *start, *working, *end, mlen ); + __CTRACE(__CTRACE_INPUT, + "inkey: Check wide char[head(%d), " + "current(%d), tail(%d), mlen(%ld)]\n", + *start, *working, *end, (long) mlen); #endif /* DEBUG */ ret = mbrtowc( wc, inbuf + (*working), mlen, &_cursesi_screen->sp ); #ifdef DEBUG - __CTRACE("[inkey]mbrtowc returns %d, wc(%x)\n", - ret, *wc ); + __CTRACE(__CTRACE_INPUT, + "inkey: mbrtowc returns %d, wc(%x)\n", ret, *wc); #endif /* DEBUG */ if ( ret == -2 && *end < *working ) { /* second half of a wide character */ @@ -367,31 +395,39 @@ inkey(wchar_t *wc, int to, int delay) *working = *start = ( *start + 1 ) % MAX_CBUF_SIZE; #ifdef DEBUG - __CTRACE("[inkey]Invalid wide char(%x)[head(%d),current(%d),tail(%d)]\n", - *wc, *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: Invalid wide char(%x)[head(%d), " + "current(%d), tail(%d)]\n", + *wc, *start, *working, *end); #endif /* DEBUG */ } else { /* > 0 */ /* return the wide character */ *start = *working = ( *working + ret ) % MAX_CBUF_SIZE; #ifdef DEBUG - __CTRACE("[inkey]Wide char found(%x)[head(%d),current(%d),tail(%d)]\n", - *wc, *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: Wide char found(%x)[head(%d), " + "current(%d), tail(%d)]\n", + *wc, *start, *working, *end); #endif /* DEBUG */ } if (*start == *end) { /* only one char processed */ state = wstate = INKEY_NORM; #ifdef DEBUG - __CTRACE("[inkey]Empty cbuf=>NORM,start(%d),current(%d),end(%d)\n", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: Empty cbuf=>NORM, " + "start(%d), current(%d), end(%d)\n", + *start, *working, *end); #endif /* DEBUG */ } else { /* otherwise we must have more than one char to backout */ state = wstate = INKEY_BACKOUT; #ifdef DEBUG - __CTRACE("[inkey]Non-empty cbuf=>BACKOUT,start(%d),current(%d),end(%d)\n", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "inkey: Non-empty cbuf=>BACKOUT, " + "start(%d), current(%d), end(%d)\n", + *start, *working, *end); #endif /* DEBUG */ } return OK; @@ -404,22 +440,27 @@ inkey(wchar_t *wc, int to, int delay) /* check if inbuf empty now */ #ifdef DEBUG - __CTRACE("[inkey]Key found(%s)\n", - key_name( current->key[mapping]->value.symbol )); + __CTRACE(__CTRACE_INPUT, + "inkey: Key found(%s)\n", + key_name(current->key[mapping]->value.symbol)); #endif /* DEBUG */ if (*start == *end) { /* if it is go back to normal */ state = wstate = INKEY_NORM; #ifdef DEBUG - __CTRACE("[inkey]=>NORM,start(%d),current(%d),end(%d)", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "[inkey]=>NORM, start(%d), " + "current(%d), end(%d)", + *start, *working, *end); #endif /* DEBUG */ } else { /* otherwise go to backout state */ state = wstate = INKEY_BACKOUT; #ifdef DEBUG - __CTRACE("[inkey]=>BACKOUT,start(%d),current(%d),end(%d)", - *start, *working, *end ); + __CTRACE(__CTRACE_INPUT, + "[inkey]=>BACKOUT, start(%d), " + "current(%d), end(%d)", + *start, *working, *end ); #endif /* DEBUG */ } @@ -506,8 +547,9 @@ wget_wch(WINDOW *win, wint_t *ch) if (is_wintouched(win)) wrefresh(win); #ifdef DEBUG - __CTRACE("wget_wch: __echoit = %d, __rawmode = %d, __nl = %d, flags = %#.4x\n", - __echoit, __rawmode, _cursesi_screen->nl, win->flags); + __CTRACE(__CTRACE_INPUT, "wget_wch: __echoit = %d, " + "__rawmode = %d, __nl = %d, flags = %#.4x\n", + __echoit, __rawmode, _cursesi_screen->nl, win->flags); #endif if (__echoit && !__rawmode) { cbreak(); @@ -586,9 +628,10 @@ wget_wch(WINDOW *win, wint_t *ch) /* XXXX perhaps __unctrl should be expanded to include * XXXX the keysyms in the table.... */ - __CTRACE("wget_wch assembled keysym 0x%x\n", inp); + __CTRACE(__CTRACE_INPUT, "wget_wch assembled keysym 0x%x\n", + inp); else - __CTRACE("wget_wch got '%s'\n", unctrl(inp)); + __CTRACE(__CTRACE_INPUT, "wget_wch got '%s'\n", unctrl(inp)); #endif if (win->delay > -1) { if (__delay() == ERR) { diff --git a/lib/libcurses/get_wstr.c b/lib/libcurses/get_wstr.c index 2d32b1f5685..54b83aeff3a 100644 --- a/lib/libcurses/get_wstr.c +++ b/lib/libcurses/get_wstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: get_wstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: get_wstr.c,v 1.2 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: get_wstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: get_wstr.c,v 1.2 2007/05/28 15:01:55 blymn Exp $"); #endif /* not lint */ #include "curses.h" @@ -190,7 +190,7 @@ __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) return ERR; #else wchar_t *ostr, ec, kc, sc[ 2 ]; - int oldx, remain, ret; + int oldx, remain; wint_t wc; cchar_t cc; @@ -205,11 +205,12 @@ __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) oldx = win->curx; remain = n - 1; - while ((ret = wget_wch(win, &wc)) != ERR - && wc != L'\n' && wc != L'\r') { + while (wget_wch(win, &wc) != ERR + && wc != L'\n' && wc != L'\r') { #ifdef DEBUG - __CTRACE("__wgetn_wstr: win %p, char 0x%x, remain %d\n", - win, wc, remain); + __CTRACE(__CTRACE_INPUT, + "__wgetn_wstr: win %p, char 0x%x, remain %d\n", + win, wc, remain); #endif *wstr = wc; touchline(win, win->cury, 1); @@ -217,15 +218,15 @@ __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) *wstr = L'\0'; if (wstr != ostr) { if ((wchar_t)wc == ec) { - mvwadd_wch(win, win->cury, + mvwadd_wch(win, win->cury, win->curx, &cc); wmove(win, win->cury, win->curx - 1); } if (wc == KEY_BACKSPACE || wc == KEY_LEFT) { /* getch() displays the key sequence */ - mvwadd_wch(win, win->cury, + mvwadd_wch(win, win->cury, win->curx - 1, &cc); - mvwadd_wch(win, win->cury, + mvwadd_wch(win, win->cury, win->curx - 2, &cc); wmove(win, win->cury, win->curx - 1); } @@ -237,7 +238,7 @@ __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) } else { /* str == ostr */ if (wc == KEY_BACKSPACE || wc == KEY_LEFT) /* getch() displays the other keys */ - mvwadd_wch(win, win->cury, + mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, oldx); } @@ -248,7 +249,7 @@ __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) mvwadd_wch(win, win->cury, win->curx - 1, &cc); /* Clear the characters from screen and str */ while (wstr != ostr) { - mvwadd_wch(win, win->cury, + mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); wstr--; diff --git a/lib/libcurses/getch.c b/lib/libcurses/getch.c index 94f4a389621..d03b28f6361 100644 --- a/lib/libcurses/getch.c +++ b/lib/libcurses/getch.c @@ -1,4 +1,4 @@ -/* $NetBSD: getch.c,v 1.47 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: getch.c,v 1.48 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)getch.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: getch.c,v 1.47 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: getch.c,v 1.48 2007/05/28 15:01:55 blymn Exp $"); #endif #endif /* not lint */ @@ -44,81 +44,9 @@ __RCSID("$NetBSD: getch.c,v 1.47 2007/01/21 13:25:36 jdc Exp $"); #include <stdio.h> #include "curses.h" #include "curses_private.h" +#include "keymap.h" -int ESCDELAY = 300; /* Delay in ms between keys for esc seq's */ - -/* - * Keyboard input handler. Do this by snarfing - * all the info we can out of the termcap entry for TERM and putting it - * into a set of keymaps. A keymap is an array the size of all the possible - * single characters we can get, the contents of the array is a structure - * that contains the type of entry this character is (i.e. part/end of a - * multi-char sequence or a plain char) and either a pointer which will point - * to another keymap (in the case of a multi-char sequence) OR the data value - * that this key should return. - * - */ - -/* private data structures for holding the key definitions */ -typedef struct key_entry key_entry_t; - -struct key_entry { - short type; /* type of key this is */ - bool enable; /* true if the key is active */ - union { - keymap_t *next; /* next keymap is key is multi-key sequence */ - wchar_t symbol; /* key symbol if key is a leaf entry */ - } value; -}; -/* Types of key structures we can have */ -#define KEYMAP_MULTI 1 /* part of a multi char sequence */ -#define KEYMAP_LEAF 2 /* key has a symbol associated with it, either - * it is the end of a multi-char sequence or a - * single char key that generates a symbol */ - -/* allocate this many key_entry structs at once to speed start up must - * be a power of 2. - */ -#define KEYMAP_ALLOC_CHUNK 4 - -/* The max number of different chars we can receive */ -#define MAX_CHAR 256 - -/* - * Unused mapping flag. - */ -#define MAPPING_UNUSED (0 - MAX_CHAR) /* never been used */ - -struct keymap { - int count; /* count of number of key structs allocated */ - short mapping[MAX_CHAR]; /* mapping of key to allocated structs */ - key_entry_t **key; /* dynamic array of keys */ -}; - - -/* Key buffer */ -#define INBUF_SZ 16 /* size of key buffer - must be larger than - * longest multi-key sequence */ -static wchar_t inbuf[INBUF_SZ]; -static int start, end, working; /* pointers for manipulating inbuf data */ - -#define INC_POINTER(ptr) do { \ - (ptr)++; \ - ptr %= INBUF_SZ; \ -} while(/*CONSTCOND*/0) - -static short state; /* state of the inkey function */ - -#define INKEY_NORM 0 /* no key backlog to process */ -#define INKEY_ASSEMBLING 1 /* assembling a multi-key sequence */ -#define INKEY_BACKOUT 2 /* recovering from an unrecognised key */ -#define INKEY_TIMEOUT 3 /* multi-key sequence timeout */ - -/* The termcap data we are interested in and the symbols they map to */ -struct tcdata { - const char *name; /* name of termcap entry */ - wchar_t symbol; /* the symbol associated with it */ -}; +short state; /* state of the inkey function */ static const struct tcdata tc[] = { {"!1", KEY_SSAVE}, @@ -275,14 +203,22 @@ static const struct tcdata tc[] = { /* Number of TC entries .... */ static const int num_tcs = (sizeof(tc) / sizeof(struct tcdata)); +int ESCDELAY = 300; /* Delay in ms between keys for esc seq's */ + +/* Key buffer */ +#define INBUF_SZ 16 /* size of key buffer - must be larger than + * longest multi-key sequence */ +static wchar_t inbuf[INBUF_SZ]; +static int start, end, working; /* pointers for manipulating inbuf data */ + /* prototypes for private functions */ static void add_key_sequence(SCREEN *screen, char *sequence, int key_type); -static key_entry_t *add_new_key(keymap_t *current, char chr, int key_type, - int symbol); +static key_entry_t *add_new_key(keymap_t *current, char ch, int key_type, + int symbol); static void delete_key_sequence(keymap_t *current, int key_type); static void do_keyok(keymap_t *current, int key_type, bool flag, int *retval); -static keymap_t *new_keymap(void); /* create a new keymap */ -static key_entry_t *new_key(void); /* create a new key entry */ +static keymap_t *new_keymap(void); /* create a new keymap */ +static key_entry_t *new_key(void); /* create a new key entry */ static wchar_t inkey(int to, int delay); /* @@ -311,7 +247,7 @@ _cursesi_free_keymap(keymap_t *map) free(map); } - + /* * Add a new key entry to the keymap pointed to by current. Entry * contains the character to add to the keymap, type is the type of @@ -336,7 +272,7 @@ add_new_key(keymap_t *current, char chr, int key_type, int symbol) current->mapping[(unsigned char) chr] = current->count; /* map new entry */ ki = current->count; - + /* make sure we have room in the key array first */ if ((current->count & (KEYMAP_ALLOC_CHUNK - 1)) == 0) { @@ -348,7 +284,7 @@ add_new_key(keymap_t *current, char chr, int key_type, int symbol) "Could not malloc for key entry\n"); exit(1); } - + the_key = new_key(); for (i = 0; i < KEYMAP_ALLOC_CHUNK; i++) { current->key[ki + i] = &the_key[i]; @@ -359,12 +295,12 @@ add_new_key(keymap_t *current, char chr, int key_type, int symbol) ki = - current->mapping[(unsigned char) chr]; current->mapping[(unsigned char) chr] = ki; } - + current->count++; - + /* point at the current key array element to use */ the_key = current->key[ki]; - + the_key->type = key_type; switch (key_type) { @@ -440,7 +376,7 @@ delete_key_sequence(keymap_t *current, int key_type) } } } - + /* * Add the sequence of characters given in sequence as the key mapping * for the given key symbol. @@ -452,6 +388,10 @@ add_key_sequence(SCREEN *screen, char *sequence, int key_type) keymap_t *current; int length, j, key_ent; +#ifdef DEBUG + __CTRACE(__CTRACE_MISC, "add_key_sequence: add key sequence: %s(%s)\n", + sequence, keyname(key_type)); +#endif /* DEBUG */ current = screen->base_keymap; /* always start with * base keymap. */ length = (int) strlen(sequence); @@ -459,13 +399,13 @@ add_key_sequence(SCREEN *screen, char *sequence, int key_type) for (j = 0; j < length - 1; j++) { /* add the entry to the struct */ tmp_key = add_new_key(current, sequence[j], KEYMAP_MULTI, 0); - + /* index into the key array - it's clearer if we stash this */ key_ent = current->mapping[(unsigned char) sequence[j]]; current->key[key_ent] = tmp_key; - + /* next key uses this map... */ current = current->key[key_ent]->value.next; } @@ -510,7 +450,7 @@ __init_getch(SCREEN *screen) p = entry; limit = 1023; if (t_getstr(screen->cursesi_genbuf, tc[i].name, - &p, &limit) != NULL) { + &p, &limit) != (char *) NULL) { #ifdef DEBUG __CTRACE(__CTRACE_INIT, "Processing termcap entry %s, sequence ", @@ -522,7 +462,7 @@ __init_getch(SCREEN *screen) #endif add_key_sequence(screen, entry, tc[i].symbol); } - + } } @@ -616,7 +556,7 @@ reread: clearerr(infd); return ERR; } - + if (delay && (__notimeout() == ERR)) return ERR; @@ -665,7 +605,7 @@ reread: clearerr(infd); return ERR; } - + if ((to || delay) && (__notimeout() == ERR)) return ERR; @@ -790,7 +730,7 @@ int keyok(int key_type, bool flag) { int result = ERR; - + do_keyok(_cursesi_screen->base_keymap, key_type, flag, &result); return result; } @@ -845,7 +785,7 @@ define_key(char *sequence, int symbol) return OK; } - + /* * wgetch -- * Read in a character from the window. @@ -931,7 +871,7 @@ wgetch(WINDOW *win) __restore_termios(); return ERR; /* we have timed out */ } - + if (ferror(infd)) { clearerr(infd); inp = ERR; diff --git a/lib/libcurses/getstr.c b/lib/libcurses/getstr.c index 6817475ddea..291238e20d1 100644 --- a/lib/libcurses/getstr.c +++ b/lib/libcurses/getstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: getstr.c,v 1.19 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: getstr.c,v 1.20 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -35,7 +35,7 @@ #if 0 static char sccsid[] = "@(#)getstr.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: getstr.c,v 1.19 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: getstr.c,v 1.20 2007/05/28 15:01:55 blymn Exp $"); #endif #endif /* not lint */ @@ -188,7 +188,7 @@ __wgetnstr(WINDOW *win, char *str, int n) } 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 - 1, ' '); mvwaddch(win, win->cury, win->curx - 2, ' '); diff --git a/lib/libcurses/in_wch.c b/lib/libcurses/in_wch.c index 87f3e6d6d10..182e91ba145 100644 --- a/lib/libcurses/in_wch.c +++ b/lib/libcurses/in_wch.c @@ -1,4 +1,4 @@ -/* $NetBSD: in_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: in_wch.c,v 1.2 2007/05/28 15:01:55 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: in_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: in_wch.c,v 1.2 2007/05/28 15:01:55 blymn Exp $"); #endif /* not lint */ #include "curses.h" diff --git a/lib/libcurses/in_wchstr.c b/lib/libcurses/in_wchstr.c index 1e397ce93d3..5239172de18 100644 --- a/lib/libcurses/in_wchstr.c +++ b/lib/libcurses/in_wchstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: in_wchstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: in_wchstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: in_wchstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: in_wchstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ #include "curses.h" diff --git a/lib/libcurses/inch.c b/lib/libcurses/inch.c index 68aec5a824f..5effbc8ee8d 100644 --- a/lib/libcurses/inch.c +++ b/lib/libcurses/inch.c @@ -1,4 +1,4 @@ -/* $NetBSD: inch.c,v 1.6 2004/01/20 08:29:09 wiz Exp $ */ +/* $NetBSD: inch.c,v 1.7 2007/05/28 15:01:56 blymn Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: inch.c,v 1.6 2004/01/20 08:29:09 wiz Exp $"); +__RCSID("$NetBSD: inch.c,v 1.7 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ #include "curses.h" @@ -88,9 +88,13 @@ mvwinch(WINDOW *win, int y, int x) chtype winch(WINDOW *win) { +#ifndef HAVE_WCHAR chtype ch; ch = (chtype) (((win)->lines[(win)->cury]->line[(win)->curx].ch & __CHARTEXT) | (chtype) ((win)->lines[(win)->cury]->line[(win)->curx].attr & __ATTRIBUTES)); return (ch); +#else + return ( chtype )win->lines[ win->cury ]->line[ win->curx ].ch; +#endif /* HAVE_WCHAR */ } diff --git a/lib/libcurses/ins_wch.c b/lib/libcurses/ins_wch.c index 4b4910fb70a..276209189c7 100644 --- a/lib/libcurses/ins_wch.c +++ b/lib/libcurses/ins_wch.c @@ -1,4 +1,4 @@ -/* $NetBSD: ins_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: ins_wch.c,v 1.2 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ins_wch.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: ins_wch.c,v 1.2 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -114,17 +114,17 @@ wins_wch(WINDOW *win, const cchar_t *wch) return wadd_wch( win, wch ); #ifdef DEBUG - __CTRACE("--before--\n" ); + __CTRACE(__CTRACE_INPUT, "--before--\n"); for ( x = 0; x < win->maxx; x++ ) - __CTRACE("[wins_wch](0,%d)=(%x,%x,%p)\n", x, - win->lines[ 0 ]->line[ x ].ch, - win->lines[ 0 ]->line[ x ].attr, - win->lines[ 0 ]->line[ x ].nsp ); + __CTRACE(__CTRACE_INPUT, "wins_wch: (0,%d)=(%x,%x,%p)\n", x, + win->lines[0]->line[x].ch, + win->lines[0]->line[x].attr, + win->lines[0]->line[x].nsp); #endif /* DEBUG */ x = win->curx; y = win->cury; #ifdef DEBUG - __CTRACE("[wins_wch](%d,%d)\n", y, x ); + __CTRACE(__CTRACE_INPUT, "wins_wch: (%d,%d)\n", y, x); #endif /* DEBUG */ switch ( wch->vals[ 0 ]) { case L'\b': @@ -170,14 +170,14 @@ wins_wch(WINDOW *win, const cchar_t *wch) /* shift all complete characters */ #ifdef DEBUG - __CTRACE("[wins_wch]shift all characters\n" ); + __CTRACE(__CTRACE_INPUT, "wins_wch: shift all characters\n"); #endif /* DEBUG */ temp1 = &win->lines[ y ]->line[ win->maxx - 1 ]; temp2 = temp1 - cw; pcw = WCOL(*(temp2 + 1)); if (pcw < 0) { #ifdef DEBUG - __CTRACE("[wins_wch]clear EOL\n" ); + __CTRACE(__CTRACE_INPUT, "wins_wch: clear EOL\n"); #endif /* DEBUG */ temp2 += pcw; while ( temp1 > temp2 + cw ) { @@ -219,8 +219,8 @@ wins_wch(WINDOW *win, const cchar_t *wch) } } #ifdef DEBUG - __CTRACE("[wins_wch]insert (%x,%x,%p)\n", - start->ch, start->attr, start->nsp ); + __CTRACE(__CTRACE_INPUT, "wins_wch: insert (%x,%x,%p)\n", + start->ch, start->attr, start->nsp); #endif /* DEBUG */ temp1 = start + 1; ex = x + 1; @@ -233,12 +233,13 @@ wins_wch(WINDOW *win, const cchar_t *wch) #ifdef DEBUG { int x; - __CTRACE("--after---\n"); + __CTRACE(__CTRACE_INPUT, "--after---\n"); for ( x = 0; x < win->maxx; x++ ) - __CTRACE("[wins_wch](0,%d)=(%x,%x,%p)\n", x, - win->lines[ 0 ]->line[ x ].ch, - win->lines[ 0 ]->line[ x ].attr, - win->lines[ 0 ]->line[ x ].nsp ); + __CTRACE(__CTRACE_INPUT, + "wins_wch: (0,%d)=(%x,%x,%p)\n", x, + win->lines[0]->line[x].ch, + win->lines[0]->line[x].attr, + win->lines[0]->line[x].nsp); } #endif /* DEBUG */ newx = win->maxx - 1 + win->ch_off; diff --git a/lib/libcurses/ins_wstr.c b/lib/libcurses/ins_wstr.c index f8a910d9131..8d9e8f50a87 100644 --- a/lib/libcurses/ins_wstr.c +++ b/lib/libcurses/ins_wstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: ins_wstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: ins_wstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ins_wstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: ins_wstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -158,7 +158,7 @@ wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) scp++; } #ifdef DEBUG - __CTRACE("[wins_nwstr]width=%d,len=%d\n", width, len); + __CTRACE(__CTRACE_INPUT, "wins_nwstr: width=%d,len=%d\n", width, len); #endif /* DEBUG */ if (cw > win->maxx - win->curx + 1) @@ -172,7 +172,7 @@ wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) start += pcw; } #ifdef DEBUG - __CTRACE("[wins_nwstr]start@(%d)\n", sx); + __CTRACE(__CTRACE_INPUT, "wins_nwstr: start@(%d)\n", sx); #endif /* DEBUG */ pcw = WCOL(*start); lnp->flags |= __ISDIRTY; @@ -182,28 +182,30 @@ wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) #ifdef DEBUG { int x; - __CTRACE("========before=======\n"); + __CTRACE(__CTRACE_INPUT, "========before=======\n"); for (x = 0; x < win->maxx; x++) - __CTRACE("[wins_nwstr](%d,%d)=(%x,%x,%p)\n", - (int)win->cury, x, - win->lines[win->cury]->line[x].ch, - win->lines[win->cury]->line[x].attr, - win->lines[win->cury]->line[x].nsp); + __CTRACE(__CTRACE_INPUT, + "wins_nwstr: (%d,%d)=(%x,%x,%p)\n", + (int) win->cury, x, + win->lines[win->cury]->line[x].ch, + win->lines[win->cury]->line[x].attr, + win->lines[win->cury]->line[x].nsp); } #endif /* DEBUG */ /* shift all complete characters */ if (sx + width + pcw <= win->maxx) { #ifdef DEBUG - __CTRACE("[wins_nwstr]shift all characters\n"); + __CTRACE(__CTRACE_INPUT, "wins_nwstr: shift all characters\n"); #endif /* DEBUG */ temp1 = &win->lines[win->cury]->line[win->maxx - 1]; temp2 = temp1 - width; pcw = WCOL(*(temp2 + 1)); if (pcw < 0) { #ifdef DEBUG - __CTRACE("[wins_nwstr]clear from %d to EOL(%d)\n", - win->maxx + pcw, win->maxx - 1); + __CTRACE(__CTRACE_INPUT, + "wins_nwstr: clear from %d to EOL(%d)\n", + win->maxx + pcw, win->maxx - 1); #endif /* DEBUG */ temp2 += pcw; while (temp1 > temp2 + width) { @@ -213,8 +215,8 @@ wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) temp1->attr = win->battr; SET_WCOL(*temp1, 1); #ifdef DEBUG - __CTRACE("[wins_nwstr]empty cell(%p)\n", - temp1); + __CTRACE(__CTRACE_INPUT, + "wins_nwstr: empty cell(%p)\n", temp1); #endif /* DEBUG */ temp1--; } @@ -226,13 +228,14 @@ wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) #ifdef DEBUG { int x; - __CTRACE("=====after shift====\n"); + __CTRACE(__CTRACE_INPUT, "=====after shift====\n"); for (x = 0; x < win->maxx; x++) - __CTRACE("[wins_nwstr](%d,%d)=(%x,%x,%p)\n", - (int)win->cury, x, - win->lines[win->cury]->line[x].ch, - win->lines[win->cury]->line[x].attr, - win->lines[win->cury]->line[x].nsp); + __CTRACE(__CTRACE_INPUT, + "wins_nwstr: (%d,%d)=(%x,%x,%p)\n", + (int) win->cury, x, + win->lines[win->cury]->line[x].ch, + win->lines[win->cury]->line[x].attr, + win->lines[win->cury]->line[x].nsp); } #endif /* DEBUG */ } @@ -273,8 +276,8 @@ wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) SET_WCOL(*temp1, cw); temp1->nsp = NULL; #ifdef DEBUG - __CTRACE("[wins_nwstr]add spacing char(%x)\n", - temp1->ch); + __CTRACE(__CTRACE_INPUT, + "wins_nwstr: add spacing char(%x)\n", temp1->ch); #endif /* DEBUG */ temp2 = temp1++; if (cw > 1) { @@ -298,21 +301,22 @@ wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) np->next = temp1->nsp; temp1->nsp = np; #ifdef DEBUG - __CTRACE("[wins_nstr]add non-spacing char(%x)\n", - np->ch); + __CTRACE(__CTRACE_INPUT, + "wins_nstr: add non-spacing char(%x)\n", np->ch); #endif /* DEBUG */ } } #ifdef DEBUG { int x; - __CTRACE("========after=======\n"); + __CTRACE(__CTRACE_INPUT, "========after=======\n"); for (x = 0; x < win->maxx; x++) - __CTRACE("[wins_nwstr](%d,%d)=(%x,%x,%p)\n", - (int)win->cury, x, - win->lines[win->cury]->line[x].ch, - win->lines[win->cury]->line[x].attr, - win->lines[win->cury]->line[x].nsp); + __CTRACE(__CTRACE_INPUT, + "wins_nwstr: (%d,%d)=(%x,%x,%p)\n", + (int) win->cury, x, + win->lines[win->cury]->line[x].ch, + win->lines[win->cury]->line[x].attr, + win->lines[win->cury]->line[x].nsp); } #endif /* DEBUG */ newx = win->maxx - 1 + win->ch_off; diff --git a/lib/libcurses/insch.c b/lib/libcurses/insch.c index 2ef926c3f5b..b8d6da0ea2c 100644 --- a/lib/libcurses/insch.c +++ b/lib/libcurses/insch.c @@ -1,4 +1,4 @@ -/* $NetBSD: insch.c,v 1.20 2006/02/05 17:04:46 jdc Exp $ */ +/* $NetBSD: insch.c,v 1.21 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,11 +34,12 @@ #if 0 static char sccsid[] = "@(#)insch.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: insch.c,v 1.20 2006/02/05 17:04:46 jdc Exp $"); +__RCSID("$NetBSD: insch.c,v 1.21 2007/05/28 15:01:56 blymn Exp $"); #endif #endif /* not lint */ #include <string.h> +#include <stdlib.h> #include "curses.h" #include "curses_private.h" @@ -57,7 +58,7 @@ insch(chtype ch) /* * mvinsch -- - * Do an insert-char on the line at (y, x). + * Do an insert-char on the line at (y, x). */ int mvinsch(int y, int x, chtype ch) @@ -67,7 +68,7 @@ mvinsch(int y, int x, chtype ch) /* * mvwinsch -- - * Do an insert-char on the line at (y, x) in the given window. + * Do an insert-char on the line at (y, x) in the given window. */ int mvwinsch(WINDOW *win, int y, int x, chtype ch) @@ -110,6 +111,11 @@ winsch(WINDOW *win, chtype ch) temp1->attr |= (win->battr & ~__COLOR); else temp1->attr |= win->battr; +#ifdef HAVE_WCHAR + if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) + return ERR; + SET_WCOL(*temp1, 1); +#endif /* HAVE_WCHAR */ __touchline(win, (int) win->cury, (int) win->curx, (int) win->maxx - 1); if (win->cury == LINES - 1 && (win->lines[LINES - 1]->line[COLS - 1].ch != ' ' || diff --git a/lib/libcurses/insdelln.c b/lib/libcurses/insdelln.c index fa011717aea..592ce6c2d51 100644 --- a/lib/libcurses/insdelln.c +++ b/lib/libcurses/insdelln.c @@ -1,4 +1,4 @@ -/* $NetBSD: insdelln.c,v 1.13 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: insdelln.c,v 1.14 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -38,16 +38,17 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: insdelln.c,v 1.13 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: insdelln.c,v 1.14 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ -/* +/* * Based on deleteln.c and insertln.c - * Copyright (c) 1981, 1993, 1994 * The Regents of the University of California. All rights reserved. */ #include <string.h> +#include <stdlib.h> #include "curses.h" #include "curses_private.h" @@ -75,6 +76,9 @@ winsdelln(WINDOW *win, int lines) { int y, i, last; __LINE *temp; +#ifdef HAVE_WCHAR + __LDATA *lp; +#endif /* HAVE_WCHAR */ attr_t attr; #ifdef DEBUG @@ -120,6 +124,16 @@ winsdelln(WINDOW *win, int lines) for (i = 0; i < win->maxx; i++) { win->lines[y]->line[i].ch = win->bch; win->lines[y]->line[i].attr = attr; +#ifndef HAVE_WCHAR + win->lines[y]->line[i].ch = win->bch; +#else + win->lines[y]->line[i].ch + = ( wchar_t )btowc(( int ) win->bch ); + lp = &win->lines[y]->line[i]; + if (_cursesi_copy_nsp(win->bnsp, lp) == ERR) + return ERR; + SET_WCOL( *lp, 1 ); +#endif /* HAVE_WCHAR */ } for (y = last; y >= win->cury; --y) __touchline(win, y, 0, (int) win->maxx - 1); @@ -154,6 +168,16 @@ winsdelln(WINDOW *win, int lines) for (i = 0; i < win->maxx; i++) { win->lines[y]->line[i].ch = win->bch; win->lines[y]->line[i].attr = attr; +#ifndef HAVE_WCHAR + win->lines[y]->line[i].ch = win->bch; +#else + win->lines[y]->line[i].ch + = (wchar_t)btowc((int) win->bch); + lp = &win->lines[y]->line[i]; + SET_WCOL( *lp, 1 ); + if (_cursesi_copy_nsp(win->bnsp, lp) == ERR) + return ERR; +#endif /* HAVE_WCHAR */ } for (y = win->cury; y < last; y++) __touchline(win, y, 0, (int) win->maxx - 1); diff --git a/lib/libcurses/insstr.c b/lib/libcurses/insstr.c index da701804b98..a21ee2d2d9c 100644 --- a/lib/libcurses/insstr.c +++ b/lib/libcurses/insstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: insstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: insstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: insstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: insstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -149,14 +149,14 @@ winsnstr(WINDOW *win, const char *str, int n) else for ( scp = str, len = 0; *scp++; ++len ); #ifdef DEBUG - __CTRACE("[winsnstr]len = %d\n", len); + __CTRACE(__CTRACE_INPUT, "winsnstr: len = %d\n", len); #endif /* DEBUG */ /* move string */ end = &win->lines[win->cury]->line[win->curx]; if ( len < win->maxx - win->curx ) { #ifdef DEBUG - __CTRACE("[winsnstr]shift %d cells\n", len); + __CTRACE(__CTRACE_INPUT, "winsnstr: shift %d cells\n", len); #endif /* DEBUG */ temp1 = &win->lines[win->cury]->line[win->maxx - 1]; temp2 = temp1 - len; @@ -191,9 +191,10 @@ winsnstr(WINDOW *win, const char *str, int n) int i; for ( i = win->curx; i < win->curx + len; i++ ) { - __CTRACE("[winsnstr](%d,%d)=('%c',%x)\n", win->cury, i, - win->lines[ win->cury ]->line[ i ].ch, - win->lines[ win->cury ]->line[ i ].attr ); + __CTRACE(__CTRACE_INPUT, + "winsnstr: (%d,%d)=('%c',%x)\n", win->cury, i, + win->lines[win->cury]->line[i].ch, + win->lines[win->cury]->line[i].attr); } } #endif /* DEBUG */ diff --git a/lib/libcurses/inwstr.c b/lib/libcurses/inwstr.c index d8a7ec5291c..307f476a8ec 100644 --- a/lib/libcurses/inwstr.c +++ b/lib/libcurses/inwstr.c @@ -1,4 +1,4 @@ -/* $NetBSD: inwstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: inwstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: inwstr.c,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: inwstr.c,v 1.2 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ #include "curses.h" diff --git a/lib/libcurses/keymap.h b/lib/libcurses/keymap.h index 378eef51a29..23457403384 100644 --- a/lib/libcurses/keymap.h +++ b/lib/libcurses/keymap.h @@ -1,4 +1,4 @@ -/* $NetBSD: keymap.h,v 1.1 2007/01/21 11:38:59 blymn Exp $ */ +/* $NetBSD: keymap.h,v 1.2 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -39,7 +39,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: keymap.h,v 1.1 2007/01/21 11:38:59 blymn Exp $"); +__RCSID("$NetBSD: keymap.h,v 1.2 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ /* keymap related stuff */ @@ -99,8 +99,6 @@ struct keymap { (ptr) %= INBUF_SZ; \ } while(/*CONSTCOND*/0) -static short state; /* state of the inkey function */ - #define INKEY_NORM 0 /* no key backlog to process */ #define INKEY_ASSEMBLING 1 /* assembling a multi-key sequence */ #define INKEY_BACKOUT 2 /* recovering from an unrecognised key */ @@ -115,158 +113,4 @@ struct tcdata { wchar_t symbol; /* the symbol associated with it */ }; -static const struct tcdata tc[] = { - {"!1", KEY_SSAVE}, - {"!2", KEY_SSUSPEND}, - {"!3", KEY_SUNDO}, - {"#1", KEY_SHELP}, - {"#2", KEY_SHOME}, - {"#3", KEY_SIC}, - {"#4", KEY_SLEFT}, - {"%0", KEY_REDO}, - {"%1", KEY_HELP}, - {"%2", KEY_MARK}, - {"%3", KEY_MESSAGE}, - {"%4", KEY_MOVE}, - {"%5", KEY_NEXT}, - {"%6", KEY_OPEN}, - {"%7", KEY_OPTIONS}, - {"%8", KEY_PREVIOUS}, - {"%9", KEY_PRINT}, - {"%a", KEY_SMESSAGE}, - {"%b", KEY_SMOVE}, - {"%c", KEY_SNEXT}, - {"%d", KEY_SOPTIONS}, - {"%e", KEY_SPREVIOUS}, - {"%f", KEY_SPRINT}, - {"%g", KEY_SREDO}, - {"%h", KEY_SREPLACE}, - {"%i", KEY_SRIGHT}, - {"%j", KEY_SRSUME}, - {"&0", KEY_SCANCEL}, - {"&1", KEY_REFERENCE}, - {"&2", KEY_REFRESH}, - {"&3", KEY_REPLACE}, - {"&4", KEY_RESTART}, - {"&5", KEY_RESUME}, - {"&6", KEY_SAVE}, - {"&7", KEY_SUSPEND}, - {"&8", KEY_UNDO}, - {"&9", KEY_SBEG}, - {"*0", KEY_SFIND}, - {"*1", KEY_SCOMMAND}, - {"*2", KEY_SCOPY}, - {"*3", KEY_SCREATE}, - {"*4", KEY_SDC}, - {"*5", KEY_SDL}, - {"*6", KEY_SELECT}, - {"*7", KEY_SEND}, - {"*8", KEY_SEOL}, - {"*9", KEY_SEXIT}, - {"@0", KEY_FIND}, - {"@1", KEY_BEG}, - {"@2", KEY_CANCEL}, - {"@3", KEY_CLOSE}, - {"@4", KEY_COMMAND}, - {"@5", KEY_COPY}, - {"@6", KEY_CREATE}, - {"@7", KEY_END}, - {"@8", KEY_ENTER}, - {"@9", KEY_EXIT}, - {"F1", KEY_F(11)}, - {"F2", KEY_F(12)}, - {"F3", KEY_F(13)}, - {"F4", KEY_F(14)}, - {"F5", KEY_F(15)}, - {"F6", KEY_F(16)}, - {"F7", KEY_F(17)}, - {"F8", KEY_F(18)}, - {"F9", KEY_F(19)}, - {"FA", KEY_F(20)}, - {"FB", KEY_F(21)}, - {"FC", KEY_F(22)}, - {"FD", KEY_F(23)}, - {"FE", KEY_F(24)}, - {"FF", KEY_F(25)}, - {"FG", KEY_F(26)}, - {"FH", KEY_F(27)}, - {"FI", KEY_F(28)}, - {"FJ", KEY_F(29)}, - {"FK", KEY_F(30)}, - {"FL", KEY_F(31)}, - {"FM", KEY_F(32)}, - {"FN", KEY_F(33)}, - {"FO", KEY_F(34)}, - {"FP", KEY_F(35)}, - {"FQ", KEY_F(36)}, - {"FR", KEY_F(37)}, - {"FS", KEY_F(38)}, - {"FT", KEY_F(39)}, - {"FU", KEY_F(40)}, - {"FV", KEY_F(41)}, - {"FW", KEY_F(42)}, - {"FX", KEY_F(43)}, - {"FY", KEY_F(44)}, - {"FZ", KEY_F(45)}, - {"Fa", KEY_F(46)}, - {"Fb", KEY_F(47)}, - {"Fc", KEY_F(48)}, - {"Fd", KEY_F(49)}, - {"Fe", KEY_F(50)}, - {"Ff", KEY_F(51)}, - {"Fg", KEY_F(52)}, - {"Fh", KEY_F(53)}, - {"Fi", KEY_F(54)}, - {"Fj", KEY_F(55)}, - {"Fk", KEY_F(56)}, - {"Fl", KEY_F(57)}, - {"Fm", KEY_F(58)}, - {"Fn", KEY_F(59)}, - {"Fo", KEY_F(60)}, - {"Fp", KEY_F(61)}, - {"Fq", KEY_F(62)}, - {"Fr", KEY_F(63)}, - {"K1", KEY_A1}, - {"K2", KEY_B2}, - {"K3", KEY_A3}, - {"K4", KEY_C1}, - {"K5", KEY_C3}, - {"Km", KEY_MOUSE}, - {"k0", KEY_F0}, - {"k1", KEY_F(1)}, - {"k2", KEY_F(2)}, - {"k3", KEY_F(3)}, - {"k4", KEY_F(4)}, - {"k5", KEY_F(5)}, - {"k6", KEY_F(6)}, - {"k7", KEY_F(7)}, - {"k8", KEY_F(8)}, - {"k9", KEY_F(9)}, - {"k;", KEY_F(10)}, - {"kA", KEY_IL}, - {"ka", KEY_CATAB}, - {"kB", KEY_BTAB}, - {"kb", KEY_BACKSPACE}, - {"kC", KEY_CLEAR}, - {"kD", KEY_DC}, - {"kd", KEY_DOWN}, - {"kE", KEY_EOL}, - {"kF", KEY_SF}, - {"kH", KEY_LL}, - {"kh", KEY_HOME}, - {"kI", KEY_IC}, - {"kL", KEY_DL}, - {"kl", KEY_LEFT}, - {"kM", KEY_EIC}, - {"kN", KEY_NPAGE}, - {"kP", KEY_PPAGE}, - {"kR", KEY_SR}, - {"kr", KEY_RIGHT}, - {"kS", KEY_EOS}, - {"kT", KEY_STAB}, - {"kt", KEY_CTAB}, - {"ku", KEY_UP} -}; -/* Number of TC entries .... */ -static const int num_tcs = (sizeof(tc) / sizeof(struct tcdata)); #endif /* _KEYMAP_H_ */ diff --git a/lib/libcurses/keyname.c b/lib/libcurses/keyname.c index b612e89786b..41701f18f63 100644 --- a/lib/libcurses/keyname.c +++ b/lib/libcurses/keyname.c @@ -1,4 +1,4 @@ -/* $NetBSD: keyname.c,v 1.2 2006/03/19 01:53:11 christos Exp $ */ +/* $NetBSD: keyname.c,v 1.3 2007/05/28 15:01:56 blymn Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: keyname.c,v 1.2 2006/03/19 01:53:11 christos Exp $"); +__RCSID("$NetBSD: keyname.c,v 1.3 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ #include <stdlib.h> @@ -483,6 +483,34 @@ keyname(int key) } free(name); /* No more names. */ + strncpy(name, "UNKOWN KEY\0", KEYNAMEMAX); + return name; +#endif +} +/* + * key_name -- + * Return name of key or NULL; + */ +char * +key_name(wchar_t key) +{ +#ifndef HAVE_WCHAR + return NULL; +#else +/* We don't bother with the large keyname table if SMALL is defined. */ +#ifdef SMALL return NULL; +#else + char *name = keyname(( int )key ); + + if ( !name ) + return NULL; + if (!strncmp( name, "M-", 2 )) { + free( name ); + name = NULL; + } + return name; #endif +#endif /* HAVE_WCHAR */ } + diff --git a/lib/libcurses/line.c b/lib/libcurses/line.c index b7a5dc0772c..b2ff3d42c4b 100644 --- a/lib/libcurses/line.c +++ b/lib/libcurses/line.c @@ -1,8 +1,8 @@ -/* $NetBSD: line.c,v 1.4 2002/01/02 10:38:28 blymn Exp $ */ +/* $NetBSD: line.c,v 1.5 2007/05/28 15:01:56 blymn Exp $ */ /*- * Copyright (c) 1998-1999 Brett Lymn - * (blymn@baea.com.au, brett_lymn@yahoo.com.au) + * (blymn@baea.com.au, brett_lymn@yahoo.com.au) * All rights reserved. * * This code has been donated to The NetBSD Foundation by the Author. @@ -31,15 +31,17 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: line.c,v 1.4 2002/01/02 10:38:28 blymn Exp $"); +__RCSID("$NetBSD: line.c,v 1.5 2007/05/28 15:01:56 blymn Exp $"); #endif /* not lint */ +#include <string.h> + #include "curses.h" #include "curses_private.h" /* * hline -- - * Draw a horizontal line of character c on stdscr. + * Draw a horizontal line of character c on stdscr. */ int hline(chtype ch, int count) @@ -49,8 +51,8 @@ hline(chtype ch, int count) /* * mvhline -- - * Move to location (y, x) and draw a horizontal line of character c - * on stdscr. + * Move to location (y, x) and draw a horizontal line of character c + * on stdscr. */ int mvhline(int y, int x, chtype ch, int count) @@ -60,8 +62,8 @@ mvhline(int y, int x, chtype ch, int count) /* * mvwhline -- - * Move to location (y, x) and draw a horizontal line of character c - * in the given window. + * Move to location (y, x) and draw a horizontal line of character c + * in the given window. */ int mvwhline(WINDOW *win, int y, int x, chtype ch, int count) @@ -74,9 +76,9 @@ mvwhline(WINDOW *win, int y, int x, chtype ch, int count) /* * whline -- - * Draw a horizontal line of character c in the given window moving - * towards the rightmost column. At most count characters are drawn - * or until the edge of the screen, whichever comes first. + * Draw a horizontal line of character c in the given window moving + * towards the rightmost column. At most count characters are drawn + * or until the edge of the screen, whichever comes first. */ int whline(WINDOW *win, chtype ch, int count) @@ -97,7 +99,7 @@ whline(WINDOW *win, chtype ch, int count) /* * vline -- - * Draw a vertical line of character ch on stdscr. + * Draw a vertical line of character ch on stdscr. */ int vline(chtype ch, int count) @@ -107,7 +109,7 @@ vline(chtype ch, int count) /* * mvvline -- - * Move to the given location an draw a vertical line of character ch. + * Move to the given location an draw a vertical line of character ch. */ int mvvline(int y, int x, chtype ch, int count) @@ -117,8 +119,8 @@ mvvline(int y, int x, chtype ch, int count) /* * mvwvline -- - * Move to the given location and draw a vertical line of character ch - * on the given window. + * Move to the given location and draw a vertical line of character ch + * on the given window. */ int mvwvline(WINDOW *win, int y, int x, chtype ch, int count) @@ -131,9 +133,9 @@ mvwvline(WINDOW *win, int y, int x, chtype ch, int count) /* * wvline -- - * Draw a vertical line of character ch in the given window moving - * towards the bottom of the screen. At most count characters are drawn - * or until the edge of the screen, whichever comes first. + * Draw a vertical line of character ch in the given window moving + * towards the bottom of the screen. At most count characters are drawn + * or until the edge of the screen, whichever comes first. */ int wvline(WINDOW *win, chtype ch, int count) @@ -152,3 +154,126 @@ wvline(WINDOW *win, chtype ch, int count) wmove(win, ocury, ocurx); return OK; } + +int hline_set(const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return whline_set( stdscr, wch, n ); +#endif /* HAVE_WCHAR */ +} + +int mvhline_set(int y, int x, const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return mvwhline_set( stdscr, y, x, wch, n ); +#endif /* HAVE_WCHAR */ +} + +int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + if ( wmove( win, y , x ) == ERR ) + return ERR; + + return whline_set( win, wch, n ); +#endif /* HAVE_WCHAR */ +} + +int whline_set(WINDOW *win, const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + int ocurx, wcn, i, cw; + cchar_t cc; + + cw = wcwidth( wch->vals[ 0 ]); + if ( ( win->maxx - win->curx ) < cw ) + return ERR; + wcn = min( n, ( win->maxx - win->curx ) / cw ); +#ifdef DEBUG + __CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn); +#endif /* DEBUG */ + ocurx = win->curx; + + memcpy( &cc, wch, sizeof( cchar_t )); + if (!(wch->vals[ 0 ])) + cc.vals[ 0 ] |= WACS_HLINE; + for (i = 0; i < wcn; i++ ) { +#ifdef DEBUG + __CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n", + win->cury, ocurx + i * cw); +#endif /* DEBUG */ + mvwadd_wch(win, win->cury, ocurx + i * cw, &cc); + } + + wmove(win, win->cury, ocurx); + return OK; +#endif /* HAVE_WCHAR */ +} + +int vline_set(const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return wvline_set( stdscr, wch, n ); +#endif /* HAVE_WCHAR */ +} + +int mvvline_set(int y, int x, const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + return mvwvline_set( stdscr, y, x, wch, n ); +#endif /* HAVE_WCHAR */ +} + +int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + if ( wmove( win, y, x ) == ERR ) + return ERR; + + return wvline_set( win, wch, n ); +#endif /* HAVE_WCHAR */ +} + +int wvline_set(WINDOW *win, const cchar_t *wch, int n) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + int ocury, ocurx, wcn, i; + cchar_t cc; + + wcn = min( n, win->maxy - win->cury); +#ifdef DEBUG + __CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn); +#endif /* DEBUG */ + ocury = win->cury; + ocurx = win->curx; + + memcpy( &cc, wch, sizeof( cchar_t )); + if (!(wch->vals[ 0 ])) + cc.vals[ 0 ] |= WACS_VLINE; + for (i = 0; i < wcn; i++) { + mvwadd_wch(win, ocury + i, ocurx, &cc); +#ifdef DEBUG + __CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n", + ocury + i, ocurx); +#endif /* DEBUG */ + } + wmove(win, ocury, ocurx); + return OK; +#endif /* HAVE_WCHAR */ +} diff --git a/lib/libcurses/newwin.c b/lib/libcurses/newwin.c index 62074f6ecef..42915af99b7 100644 --- a/lib/libcurses/newwin.c +++ b/lib/libcurses/newwin.c @@ -1,4 +1,4 @@ -/* $NetBSD: newwin.c,v 1.44 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: newwin.c,v 1.45 2007/05/28 15:01:56 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)newwin.c 8.3 (Berkeley) 7/27/94"; #else -__RCSID("$NetBSD: newwin.c,v 1.44 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: newwin.c,v 1.45 2007/05/28 15:01:56 blymn Exp $"); #endif #endif /* not lint */ @@ -154,8 +154,14 @@ __newwin(SCREEN *screen, int nlines, int ncols, int by, int bx, int ispad) else lp->flags = 0; for (sp = lp->line, j = 0; j < maxx; j++, sp++) { - sp->ch = ' '; sp->attr = 0; +#ifndef HAVE_WCHAR + sp->ch = win->bch; +#else + sp->ch = ( wchar_t )btowc(( int ) win->bch ); + sp->nsp = NULL; + SET_WCOL( *sp, 1 ); +#endif /* HAVE_WCHAR */ } lp->hash = __hash((char *)(void *)lp->line, (size_t) (ncols * __LDATASIZE)); @@ -217,6 +223,11 @@ __set_subwin(WINDOW *orig, WINDOW *win) { int i; __LINE *lp, *olp; +#ifdef HAVE_WCHAR + __LDATA *cp; + int j; + nschar_t *np; +#endif /* HAVE_WCHAR */ win->ch_off = win->begx - orig->begx; /* Point line pointers to line space. */ @@ -229,8 +240,25 @@ __set_subwin(WINDOW *orig, WINDOW *win) lp->line = &olp->line[win->ch_off]; lp->firstchp = &olp->firstch; lp->lastchp = &olp->lastch; +#ifndef HAVE_WCHAR lp->hash = __hash((char *)(void *)lp->line, (size_t) (win->maxx * __LDATASIZE)); +#else + for ( cp = lp->line, j = 0; j < win->maxx; j++, cp++ ) { + lp->hash = __hash_more( &cp->ch, + sizeof( wchar_t ), lp->hash ); + lp->hash = __hash_more( &cp->attr, + sizeof( wchar_t ), lp->hash ); + if ( cp->nsp ) { + np = cp->nsp; + while ( np ) { + lp->hash = __hash_more( &np->ch, + sizeof( wchar_t ), lp->hash ); + np = np->next; + } + } + } +#endif /* HAVE_WCHAR */ } #ifdef DEBUG @@ -345,6 +373,10 @@ __makenew(SCREEN *screen, int nlines, int ncols, int by, int bx, int sub, win->flags = (__IDLINE | __IDCHAR); win->delay = -1; win->wattr = 0; +#ifdef HAVE_WCHAR + win->bnsp = NULL; + SET_BGWCOL( *win, 1 ); +#endif /* HAVE_WCHAR */ win->scr_t = 0; win->scr_b = win->maxy - 1; if (ispad) { diff --git a/lib/libcurses/putchar.c b/lib/libcurses/putchar.c index 2d87cf5b24c..8f77d5e87c3 100644 --- a/lib/libcurses/putchar.c +++ b/lib/libcurses/putchar.c @@ -1,4 +1,4 @@ -/* $NetBSD: putchar.c,v 1.18 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: putchar.c,v 1.19 2007/05/28 15:01:57 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)putchar.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: putchar.c,v 1.18 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: putchar.c,v 1.19 2007/05/28 15:01:57 blymn Exp $"); #endif #endif /* not lint */ @@ -67,3 +67,24 @@ __cputchar_args(char ch, void *args) #endif putc(ch, outfd); } + +#ifdef HAVE_WCHAR +int +__cputwchar(wchar_t wch) +{ + return (putwc(wch, _cursesi_screen->outfd)); +} + +/* + * This is the same as __cputchar but the extra argument holds the file + * descriptor to write the output to. This function can only be used with + * the "new" libterm interface. + */ +void +__cputwchar_args(wchar_t wch, void *args) +{ + FILE *outfd = (FILE *) args; + + putwc(wch, outfd); +} +#endif /* HAVE_WCHAR */ diff --git a/lib/libcurses/refresh.c b/lib/libcurses/refresh.c index 1ea27d011ce..714e16b13b0 100644 --- a/lib/libcurses/refresh.c +++ b/lib/libcurses/refresh.c @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.64 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: refresh.c,v 1.65 2007/05/28 15:01:57 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)refresh.c 8.7 (Berkeley) 8/13/94"; #else -__RCSID("$NetBSD: refresh.c,v 1.64 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: refresh.c,v 1.65 2007/05/28 15:01:57 blymn Exp $"); #endif #endif /* not lint */ @@ -44,12 +44,18 @@ __RCSID("$NetBSD: refresh.c,v 1.64 2007/01/21 13:25:36 jdc Exp $"); #include "curses.h" #include "curses_private.h" -static void domvcur __P((int, int, int, int)); -static int makech __P((int)); -static void quickch __P((void)); -static void scrolln __P((int, int, int, int, int)); +static void domvcur(int, int, int, int); +static int makech(int); +static void quickch(void); +static void scrolln(int, int, int, int, int); -static int _cursesi_wnoutrefresh(SCREEN *, WINDOW *, int, int, int, int, int, int); +static int _cursesi_wnoutrefresh(SCREEN *, WINDOW *, + int, int, int, int, int, int); + +#ifdef HAVE_WCHAR +int cellcmp( __LDATA *, __LDATA * ); +int linecmp( __LDATA *, __LDATA *, size_t ); +#endif /* HAVE_WCHAR */ #ifndef _CURSES_USE_MACROS @@ -87,7 +93,7 @@ wnoutrefresh(WINDOW *win) */ int pnoutrefresh(WINDOW *pad, int pbegy, int pbegx, int sbegy, int sbegx, - int smaxy, int smaxx) + int smaxy, int smaxx) { int pmaxy, pmaxx; @@ -118,7 +124,7 @@ pnoutrefresh(WINDOW *pad, int pbegy, int pbegx, int sbegy, int sbegx, pmaxy = pad->maxy - pad->begy; if (pmaxx > pad->maxx - pad->begx) pmaxx = pad->maxx - pad->begx; - + if (smaxy - sbegy < 0 || smaxx - sbegx < 0 ) return ERR; @@ -129,13 +135,13 @@ pnoutrefresh(WINDOW *pad, int pbegy, int pbegx, int sbegy, int sbegx, /* * _cursesi_wnoutrefresh -- - * Does the grunt work for wnoutrefresh to the given screen. + * Does the grunt work for wnoutrefresh to the given screen. * Copies the part of the window given by the rectangle * (begy, begx) to (maxy, maxx) at screen position (wbegy, wbegx). */ int _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx, - int wbegy, int wbegx, int maxy, int maxx) + int wbegy, int wbegx, int maxy, int maxx) { short sy, wy, wx, y_off, x_off, mx; @@ -169,8 +175,10 @@ _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx, #endif for (sy = 0; sy < sub_win->maxy; sy++) { if (sub_win->lines[sy]->flags == __ISDIRTY) { - orig->lines[sy + sub_win->begy - orig->begy]->flags |= __ISDIRTY; - sub_win->lines[sy]->flags &= ~__ISDIRTY; + orig->lines[sy + sub_win->begy - orig->begy]->flags + |= __ISDIRTY; + sub_win->lines[sy]->flags + &= ~__ISDIRTY; } } } @@ -195,7 +203,7 @@ _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx, for (wy = begy, y_off = wbegy; wy < maxy && y_off < screen->__virtscr->maxy; wy++, y_off++) { - wlp = win->lines[wy]; + wlp = win->lines[wy]; #ifdef DEBUG __CTRACE(__CTRACE_REFRESH, "_wnoutrefresh: wy %d\tf %d\tl %d\tflags %x\n", @@ -237,6 +245,17 @@ _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx, (vlp->line[x_off].attr & _cursesi_screen->nca)) vlp->line[x_off].attr &= ~__COLOR; +#ifdef HAVE_WCHAR + if (wlp->line[wx].ch + == (wchar_t)btowc((int) win->bch)) { + vlp->line[x_off].ch = win->bch; + SET_WCOL( vlp->line[x_off], 1 ); + if (_cursesi_copy_nsp(win->bnsp, + &vlp->line[x_off]) + == ERR) + return ERR; + } +#endif /* HAVE_WCHAR */ wx++; x_off++; } @@ -333,7 +352,7 @@ wrefresh(WINDOW *win) */ int prefresh(WINDOW *pad, int pbegy, int pbegx, int sbegy, int sbegx, - int smaxy, int smaxx) + int smaxy, int smaxx) { int retval; @@ -372,6 +391,11 @@ doupdate(void) __LINE *wlp; short wy; int dnum; +#ifdef HAVE_WCHAR + __LDATA *lp; + nschar_t *np; + int x; +#endif /* HAVE_WCHAR */ /* Check if we need to restart ... */ if (_cursesi_screen->endwin) @@ -387,13 +411,37 @@ doupdate(void) _cursesi_screen->lx = curscr->curx; wy = 0; - if (!_cursesi_screen->curwin) + if (!_cursesi_screen->curwin) { for (wy = 0; wy < win->maxy; wy++) { wlp = win->lines[wy]; - if (wlp->flags & __ISDIRTY) + if (wlp->flags & __ISDIRTY) { +#ifndef HAVE_WCHAR wlp->hash = __hash(wlp->line, (size_t)(win->maxx * __LDATASIZE)); +#else + wlp->hash = 0; + for ( x = 0; x < win->maxx; x++ ) { + lp = &wlp->line[ x ]; + wlp->hash = __hash_more( &lp->ch, + sizeof( wchar_t ), wlp->hash ); + wlp->hash = __hash_more( &lp->attr, + sizeof( attr_t ), wlp->hash ); + np = lp->nsp; + if (np) { + while ( np ) { + wlp->hash + = __hash_more( + &np->ch, + sizeof(wchar_t), + wlp->hash ); + np = np->next; + } + } + } +#endif /* HAVE_WCHAR */ + } } + } if ((win->flags & __CLEAROK) || (curscr->flags & __CLEAROK) || _cursesi_screen->curwin) { @@ -419,7 +467,7 @@ doupdate(void) } #ifdef DEBUG __CTRACE(__CTRACE_REFRESH, "doupdate: (%p): curwin = %d\n", win, - _cursesi_screen->curwin); + _cursesi_screen->curwin); __CTRACE(__CTRACE_REFRESH, "doupdate: \tfirstch\tlastch\n"); #endif @@ -441,6 +489,9 @@ doupdate(void) __CTRACE(__CTRACE_REFRESH, "#####################################\n"); + __CTRACE(__CTRACE_REFRESH, + "stdscr(%p)-curscr(%p)-__virtscr(%p)\n", + stdscr, curscr, _cursesi_screen->__virtscr); for (i = 0; i < curscr->maxy; i++) { __CTRACE(__CTRACE_REFRESH, "C: %d:", i); __CTRACE(__CTRACE_REFRESH, " 0x%x \n", @@ -452,7 +503,7 @@ doupdate(void) __CTRACE(__CTRACE_REFRESH, " attr:"); for (j = 0; j < curscr->maxx; j++) __CTRACE(__CTRACE_REFRESH, " %x", - curscr->lines[i]->line[j].attr); + curscr->lines[i]->line[j].attr); __CTRACE(__CTRACE_REFRESH, "\n"); __CTRACE(__CTRACE_REFRESH, "W: %d:", i); __CTRACE(__CTRACE_REFRESH, " 0x%x \n", @@ -468,9 +519,21 @@ doupdate(void) __CTRACE(__CTRACE_REFRESH, " %x", win->lines[i]->line[j].attr); __CTRACE(__CTRACE_REFRESH, "\n"); +#ifdef HAVE_WCHAR + __CTRACE(__CTRACE_REFRESH, " nsp:"); + for (j = 0; j < curscr->maxx; j++) + __CTRACE(__CTRACE_REFRESH, " %p", + win->lines[i]->line[j].nsp); + __CTRACE(__CTRACE_REFRESH, "\n"); + __CTRACE(__CTRACE_REFRESH, " bnsp:"); + for (j = 0; j < curscr->maxx; j++) + __CTRACE(__CTRACE_REFRESH, " %p", + win->bnsp); + __CTRACE(__CTRACE_REFRESH, "\n"); +#endif /* HAVE_WCHAR */ } } -#endif /* DEBUG */ +#endif /* DEBUG */ for (wy = 0; wy < win->maxy; wy++) { wlp = win->lines[wy]; @@ -479,10 +542,15 @@ doupdate(void) __CTRACE(__CTRACE_REFRESH, "doupdate: wy %d\tf: %d\tl:%d\tflags %x\n", wy, *wlp->firstchp, *wlp->lastchp, wlp->flags); -#endif +#endif /* DEBUG */ if (!_cursesi_screen->curwin) curscr->lines[wy]->hash = wlp->hash; if (wlp->flags & __ISDIRTY) { +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, + "doupdate: [ISDIRTY]wy:%d\tf:%d\tl:%d\n", wy, + *wlp->firstchp, *wlp->lastchp); +#endif /* DEBUG */ if (makech(wy) == ERR) return (ERR); else { @@ -494,22 +562,22 @@ doupdate(void) #ifdef DEBUG __CTRACE(__CTRACE_REFRESH, "doupdate: line %d notdirty\n", wy); -#endif +#endif /* DEBUG */ wlp->flags &= ~__ISDIRTY; } } } #ifdef DEBUG - __CTRACE(__CTRACE_REFRESH, "t%d\t%d\n", + __CTRACE(__CTRACE_REFRESH, "\t%d\t%d\n", *wlp->firstchp, *wlp->lastchp); -#endif +#endif /* DEBUG */ } #ifdef DEBUG __CTRACE(__CTRACE_REFRESH, "doupdate: ly=%d, lx=%d\n", _cursesi_screen->ly, _cursesi_screen->lx); -#endif +#endif /* DEBUG */ if (_cursesi_screen->curwin) domvcur(_cursesi_screen->ly, _cursesi_screen->lx, @@ -528,6 +596,31 @@ doupdate(void) /* Don't leave the screen with attributes set. */ __unsetattr(0); +#ifdef DEBUG +#ifdef HAVE_WCHAR + { + int i, j; + + __CTRACE(__CTRACE_REFRESH, + "***********after*****************\n"); + __CTRACE(__CTRACE_REFRESH, + "stdscr(%p)-curscr(%p)-__virtscr(%p)\n", + stdscr, curscr, _cursesi_screen->__virtscr); + for (i = 0; i < curscr->maxy; i++) { + for (j = 0; j < curscr->maxx; j++) + __CTRACE(__CTRACE_REFRESH, + "[%d,%d](%x,%x,%p)-(%x,%x,%p)\n", + i, j, + curscr->lines[i]->line[j].ch, + curscr->lines[i]->line[j].attr, + curscr->lines[i]->line[j].nsp, + _cursesi_screen->__virtscr->lines[i]->line[j].ch, + _cursesi_screen->__virtscr->lines[i]->line[j].attr, + _cursesi_screen->__virtscr->lines[i]->line[j].nsp); + } + } +#endif /* HAVE_WCHAR */ +#endif /* DEBUG */ return fflush(_cursesi_screen->outfd) == EOF ? ERR : OK; } @@ -536,11 +629,10 @@ doupdate(void) * Make a change on the screen. */ static int -makech(wy) - int wy; +makech(int wy) { WINDOW *win; - static __LDATA blank = {' ', 0}; + static __LDATA blank; __LDATA *nsp, *csp, *cp, *cep; int clsp, nlsp; /* Last space in lines. */ int lch, wx; @@ -555,6 +647,36 @@ makech(wy) win = curscr; else win = __virtscr; +#ifdef HAVE_WCHAR + blank.ch = ( wchar_t )btowc(( int ) win->bch ); + blank.attr = 0; + if (_cursesi_copy_nsp(win->bnsp, &blank) == ERR) + return ERR; + SET_WCOL( blank, 1 ); +#endif /* HAVE_WCHAR */ +#ifdef DEBUG +#if HAVE_WCHAR + { + int x; + __LDATA *lp, *vlp; + + __CTRACE(__CTRACE_REFRESH, + "[makech-before]wy=%d,curscr(%p)-__virtscr(%p)\n", + wy, curscr, __virtscr); + for (x = 0; x < curscr->maxx; x++) { + lp = &curscr->lines[wy]->line[x]; + vlp = &__virtscr->lines[wy]->line[x]; + __CTRACE(__CTRACE_REFRESH, + "[%d,%d](%x,%x,%x,%x,%p)-" + "(%x,%x,%x,%x,%p)\n", + wy, x, lp->ch, lp->attr, + win->bch, win->battr, lp->nsp, + vlp->ch, vlp->attr, + win->bch, win->battr, vlp->nsp); + } + } +#endif /* HAVE_WCHAR */ +#endif /* DEBUG */ /* Is the cursor still on the end of the last line? */ if (wy > 0 && curscr->lines[wy - 1]->flags & __ISPASTEOL) { domvcur(_cursesi_screen->ly, _cursesi_screen->lx, @@ -575,18 +697,41 @@ makech(wy) if (lch >= (int) win->maxx) lch = win->maxx - 1; - if (_cursesi_screen->curwin) + if (_cursesi_screen->curwin) { csp = ␣ - else +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, "makech: csp is blank\n"); +#endif /* DEBUG */ + } else { csp = &curscr->lines[wy]->line[wx]; +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, + "makech: csp is on curscr:(%d,%d)\n", wy, wx); +#endif /* DEBUG */ + } nsp = &win->lines[wy]->line[wx]; +#ifdef DEBUG + if ( _cursesi_screen->curwin ) + __CTRACE(__CTRACE_REFRESH, + "makech: nsp is at curscr:(%d,%d)\n", wy, wx); + else + __CTRACE(__CTRACE_REFRESH, + "makech: nsp is at __virtscr:(%d,%d)\n", wy, wx); +#endif /* DEBUG */ if (__tc_ce && !_cursesi_screen->curwin) { cp = &win->lines[wy]->line[win->maxx - 1]; lspc = cp->attr & __COLOR; - while (cp->ch == ' ' && cp->attr == lspc) +#ifndef HAVE_WCHAR + while (cp->ch == ' ' && cp->attr == lspc) /* XXX */ + if (cp-- <= win->lines[wy]->line) + break; +#else + while (cp->ch == ( wchar_t )btowc(( int )' ' ) + && ( cp->attr & WA_ATTRIBUTES ) == lspc) if (cp-- <= win->lines[wy]->line) break; +#endif /* HAVE_WCHAR */ nlsp = cp - win->lines[wy]->line; if (nlsp < 0) nlsp = 0; @@ -597,6 +742,10 @@ makech(wy) ce = NULL; while (wx <= lch) { +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, "makech: wx=%d,lch=%d\n", wx, lch); +#endif /* DEBUG */ +#ifndef HAVE_WCHAR if (memcmp(nsp, csp, sizeof(__LDATA)) == 0) { if (wx <= lch) { while (wx <= lch && @@ -610,6 +759,27 @@ makech(wy) } break; } +#else +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, "makech: nsp=(%x,%x,%x,%x,%p)\n", + nsp->ch, nsp->attr, win->bch, win->battr, nsp->nsp); + __CTRACE(__CTRACE_REFRESH, "makech: csp=(%x,%x,%x,%x,%p)\n", + csp->ch, csp->attr, win->bch, win->battr, csp->nsp); +#endif /* DEBUG */ + if (((nsp->attr & __WCWIDTH) != __WCWIDTH) && + cellcmp(nsp, csp)) { + if (wx <= lch) { + while (wx <= lch && cellcmp( csp, nsp )) { + nsp++; + if (!_cursesi_screen->curwin) + ++csp; + ++wx; + } + continue; + } + break; + } +#endif /* HAVE_WCHAR */ domvcur(_cursesi_screen->ly, _cursesi_screen->lx, wy, wx); #ifdef DEBUG @@ -619,12 +789,38 @@ makech(wy) #endif _cursesi_screen->ly = wy; _cursesi_screen->lx = wx; +#ifndef HAVE_WCHAR while (wx <= lch && memcmp(nsp, csp, sizeof(__LDATA)) != 0) { if (ce != NULL && wx >= nlsp && nsp->ch == ' ' && nsp->attr == lspc) { + /* Are we continuing a multircell character? */ + if ((nsp->attr & __WCWIDTH) == __WCWIDTH) { +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, + "Skipping continuation cell\n"); + wx++; + csp->ch = nsp->ch; + csp->attr = nsp->attr; + nsp++; + csp++; + continue; + } +#endif +#else + while (!cellcmp(nsp, csp) && wx <= lch) { + if (ce != NULL && wx >= nlsp + && nsp->ch == (wchar_t)btowc((int)' ') /* XXX */ + && (nsp->attr & WA_ATTRIBUTES) == lspc) { + +#endif /* Check for clear to end-of-line. */ cep = &curscr->lines[wy]->line[win->maxx - 1]; - while (cep->ch == ' ' && cep->attr == lspc) +#ifndef HAVE_WCHAR + while (cep->ch == ' ' && cep->attr == lspc) /* XXX */ +#else + while (cep->ch == (wchar_t)btowc((int)' ') + && (cep->attr & WA_ATTRIBUTES) == lspc) +#endif /* HAVE_WCHAR */ if (cep-- <= csp) break; clsp = cep - curscr->lines[wy]->line - @@ -648,8 +844,13 @@ makech(wy) tputs(__tc_ce, 0, __cputchar); _cursesi_screen->lx = wx + win->begx; while (wx++ <= clsp) { - csp->ch = ' '; csp->attr = lspc; +#ifndef HAVE_WCHAR + csp->ch = ' '; /* XXX */ +#else + csp->ch = (wchar_t)btowc((int)' '); + SET_WCOL( *csp, 1 ); +#endif /* HAVE_WCHAR */ csp++; } return (OK); @@ -660,10 +861,11 @@ makech(wy) #ifdef DEBUG __CTRACE(__CTRACE_REFRESH, "makech: have attr %08x, need attr %08x\n", - curscr->wattr, nsp->attr); + curscr->wattr & WA_ATTRIBUTES, + nsp->attr & WA_ATTRIBUTES); #endif - off = ~nsp->attr & curscr->wattr; + off = (~nsp->attr & curscr->wattr) & WA_ATTRIBUTES; /* * Unset attributes as appropriate. Unset first @@ -702,16 +904,23 @@ makech(wy) off &= __mask_se; } +#ifndef HAVE_WCHAR if (off & __ALTCHARSET && __tc_ae != NULL) { tputs(__tc_ae, 0, __cputchar); curscr->wattr &= ~__ALTCHARSET; } +#else + if (off & WA_ALTCHARSET && __tc_ae != NULL) { + tputs(__tc_ae, 0, __cputchar); + curscr->wattr &= ~WA_ALTCHARSET; + } +#endif /* HAVE_WCHAR */ /* Set/change colour as appropriate. */ if (__using_color) __set_color(curscr, nsp->attr & __COLOR); - on = nsp->attr & ~curscr->wattr; + on = (nsp->attr & ~curscr->wattr) & WA_ATTRIBUTES; /* * Enter standout mode if appropriate. @@ -761,29 +970,85 @@ makech(wy) tputs(__tc_mr, 0, __cputchar); curscr->wattr |= __REVERSE; } +#ifdef HAVE_WCHAR + if (on & WA_TOP && __tc_Xt != NULL) { + tputs(__tc_Xt, 0, __cputchar); + curscr->wattr |= WA_TOP; + } + if (on & WA_LOW && __tc_Xo != NULL) { + tputs(__tc_Xo, 0, __cputchar); + curscr->wattr |= WA_LOW; + } + if (on & WA_LEFT && __tc_Xl != NULL) { + tputs(__tc_Xl, 0, __cputchar); + curscr->wattr |= WA_LEFT; + } + if (on & WA_RIGHT && __tc_Xl != NULL) { + tputs(__tc_Xl, 0, __cputchar); + curscr->wattr |= WA_RIGHT; + } + if (on & WA_HORIZONTAL && __tc_Xh != NULL) { + tputs(__tc_Xh, 0, __cputchar); + curscr->wattr |= WA_HORIZONTAL; + } + if (on & WA_VERTICAL && __tc_Xv != NULL) { + tputs(__tc_Xv, 0, __cputchar); + curscr->wattr |= WA_VERTICAL; + } +#endif /* HAVE_WCHAR */ } /* Enter/exit altcharset mode as appropriate. */ +#ifndef HAVE_WCHAR if (on & __ALTCHARSET && __tc_as != NULL && __tc_ae != NULL) { tputs(__tc_as, 0, __cputchar); curscr->wattr |= __ALTCHARSET; } +#else + if (on & WA_ALTCHARSET && __tc_as != NULL && + __tc_ae != NULL) { + tputs(__tc_as, 0, __cputchar); + curscr->wattr |= WA_ALTCHARSET; + } +#endif /* HAVE_WCHAR */ wx++; if (wx >= win->maxx && - wy == win->maxy - 1 && !_cursesi_screen->curwin) + wy == win->maxy - 1 && !_cursesi_screen->curwin) { if (win->flags & __SCROLLOK) { if (win->flags & __ENDLINE) __unsetattr(1); if (!(win->flags & __SCROLLWIN)) { if (!_cursesi_screen->curwin) { csp->attr = nsp->attr; - __cputchar((int) - (csp->ch = - nsp->ch)); - } else - __cputchar((int) nsp->ch); + csp->ch = nsp->ch; +#ifdef HAVE_WCHAR + if (_cursesi_copy_nsp(nsp->nsp, csp) == ERR) + return ERR; +#endif /* HAVE_WCHAR */ + } +#ifndef HAVE_WCHAR + __cputchar((int) nsp->ch); +#else + if ( WCOL( *nsp ) > 0 ) { + __cputwchar((int)nsp->ch); +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, + "makech: (%d,%d)putwchar(0x%x)\n", + wy, wx - 1, + nsp->ch ); +#endif /* DEBUG */ + /* + * Output non-spacing + * characters for the + * cell. + */ + __cursesi_putnsp(nsp->nsp, + wy, wx); + + } +#endif /* HAVE_WCHAR */ } if (wx < curscr->maxx) { domvcur(_cursesi_screen->ly, wx, @@ -794,19 +1059,37 @@ makech(wy) _cursesi_screen->lx = win->maxx - 1; return (OK); } + } if (wx < win->maxx || wy < win->maxy - 1 || !(win->flags & __SCROLLWIN)) { if (!_cursesi_screen->curwin) { csp->attr = nsp->attr; - __cputchar((int) (csp->ch = nsp->ch)); + csp->ch = nsp->ch; +#ifdef HAVE_WCHAR + if (_cursesi_copy_nsp(nsp->nsp, + csp) == ERR) + return ERR; +#endif /* HAVE_WCHAR */ csp++; - } else - __cputchar((int) nsp->ch); - } + } +#ifndef HAVE_WCHAR + __cputchar((int) nsp->ch); #ifdef DEBUG - __CTRACE(__CTRACE_REFRESH, "makech: putchar(%c)\n", - nsp->ch & 0177); + __CTRACE(__CTRACE_REFRESH, + "makech: putchar(%c)\n", nsp->ch & 0177); #endif +#else + if (WCOL(*nsp) > 0) { + __cputwchar((int) nsp->ch); +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, + "makech:(%d,%d) putwchar(%x)\n", + wy, wx - 1, nsp->ch); + __cursesi_putnsp(nsp->nsp, wy, wx); +#endif /* DEBUG */ + } +#endif /* HAVE_WCHAR */ + } if (__tc_uc && ((nsp->attr & __STANDOUT) || (nsp->attr & __UNDERSCORE))) { __cputchar('\b'); @@ -837,6 +1120,29 @@ makech(wy) wx, _cursesi_screen->lx); #endif } +#ifdef DEBUG +#if HAVE_WCHAR + { + int x; + __LDATA *lp, *vlp; + + __CTRACE(__CTRACE_REFRESH, + "makech-after: curscr(%p)-__virtscr(%p)\n", + curscr, __virtscr ); + for (x = 0; x < curscr->maxx; x++) { + lp = &curscr->lines[wy]->line[x]; + vlp = &__virtscr->lines[wy]->line[x]; + __CTRACE(__CTRACE_REFRESH, + "[%d,%d](%x,%x,%x,%x,%p)-" + "(%x,%x,%x,%x,%p)\n", + wy, x, lp->ch, lp->attr, + win->bch, win->battr, lp->nsp, + vlp->ch, vlp->attr, + win->bch, win->battr, vlp->nsp); + } + } +#endif /* HAVE_WCHAR */ +#endif /* DEBUG */ return (OK); } @@ -849,7 +1155,13 @@ static void domvcur(oy, ox, ny, nx) int oy, ox, ny, nx; { +#ifdef DEBUG + __CTRACE(__CTRACE_REFRESH, "domvcur: (%x,%d)=>(%d,%d)\n", + oy, ox, ny, nx ); +#endif /* DEBUG */ __unsetattr(1); + if ( oy == ny && ox == nx ) + return; __mvcur(oy, ox, ny, nx, 1); } @@ -882,24 +1194,44 @@ quickch(void) * Find how many lines from the top of the screen are unchanged. */ for (top = 0; top < __virtscr->maxy; top++) +#ifndef HAVE_WCHAR + if (__virtscr->lines[top]->flags & __ISDIRTY && + (__virtscr->lines[top]->hash != curscr->lines[top]->hash || + memcmp(__virtscr->lines[top]->line, + curscr->lines[top]->line, + (size_t) __virtscr->maxx * __LDATASIZE) + != 0)) + break; +#else if (__virtscr->lines[top]->flags & __ISDIRTY && (__virtscr->lines[top]->hash != curscr->lines[top]->hash || - memcmp(__virtscr->lines[top]->line, - curscr->lines[top]->line, - (size_t) __virtscr->maxx * __LDATASIZE) != 0)) + !linecmp(__virtscr->lines[top]->line, + curscr->lines[top]->line, + (size_t) __virtscr->maxx ))) break; +#endif /* HAVE_WCHAR */ else __virtscr->lines[top]->flags &= ~__ISDIRTY; /* * Find how many lines from bottom of screen are unchanged. */ for (bot = __virtscr->maxy - 1; bot >= 0; bot--) +#ifndef HAVE_WCHAR if (__virtscr->lines[bot]->flags & __ISDIRTY && (__virtscr->lines[bot]->hash != curscr->lines[bot]->hash || - memcmp(__virtscr->lines[bot]->line, - curscr->lines[bot]->line, - (size_t) __virtscr->maxx * __LDATASIZE) != 0)) + memcmp(__virtscr->lines[bot]->line, + curscr->lines[bot]->line, + (size_t) __virtscr->maxx * __LDATASIZE) + != 0)) break; +#else + if (__virtscr->lines[bot]->flags & __ISDIRTY && + (__virtscr->lines[bot]->hash != curscr->lines[bot]->hash || + !linecmp(__virtscr->lines[bot]->line, + curscr->lines[bot]->line, + (size_t) __virtscr->maxx ))) + break; +#endif /* HAVE_WCHAR */ else __virtscr->lines[bot]->flags &= ~__ISDIRTY; @@ -949,7 +1281,7 @@ quickch(void) for (bsize = bot - top; bsize >= THRESH; bsize--) { for (startw = top; startw <= bot - bsize; startw++) for (starts = top; starts <= bot - bsize; - starts++) { + starts++) { for (curw = startw, curs = starts; curs < starts + bsize; curw++, curs++) if (__virtscr->lines[curw]->hash != @@ -958,12 +1290,19 @@ quickch(void) if (curs != starts + bsize) continue; for (curw = startw, curs = starts; - curs < starts + bsize; curw++, curs++) + curs < starts + bsize; curw++, curs++) +#ifndef HAVE_WCHAR if (memcmp(__virtscr->lines[curw]->line, curscr->lines[curs]->line, (size_t) __virtscr->maxx * __LDATASIZE) != 0) break; +#else + if (!linecmp(__virtscr->lines[curw]->line, + curscr->lines[curs]->line, + (size_t) __virtscr->maxx)) + break; +#endif /* HAVE_WCHAR */ if (curs == starts + bsize) goto done; } @@ -1022,12 +1361,24 @@ done: } #endif +#ifndef HAVE_WCHAR if (buf[0].ch != ' ') { for (i = 0; i < BLANKSIZE; i++) { buf[i].ch = ' '; buf[i].attr = 0; } } +#else + if (buf[0].ch != ( wchar_t )btowc(( int ) curscr->bch )) { + for (i = 0; i < BLANKSIZE; i++) { + buf[i].ch = ( wchar_t )btowc(( int ) curscr->bch ); + if (_cursesi_copy_nsp(curscr->bnsp, &buf[i]) == ERR) + return; + buf[i].attr = 0; + SET_WCOL( buf[ i ], 1 ); + } + } +#endif /* HAVE_WCHAR */ if (__virtscr->maxx != last_hash_len) { blank_hash = 0; @@ -1098,16 +1449,25 @@ done: } else if ((n > 0 && target >= top && target < top + n) || (n < 0 && target <= bot && target > bot + n)) { - if (clp->hash != blank_hash || memcmp(clp->line, - clp->line + 1, (__virtscr->maxx - 1) * - __LDATASIZE) || memcmp(clp->line, buf, - __LDATASIZE)) { - for (i = __virtscr->maxx; i > BLANKSIZE; +#ifndef HAVE_WCHAR + if (clp->hash != blank_hash || + memcmp(clp->line, clp->line + 1, + (__virtscr->maxx - 1) + * __LDATASIZE) || + memcmp(clp->line, buf, __LDATASIZE)) { +#else + if (clp->hash != blank_hash + || linecmp(clp->line, clp->line + 1, + (unsigned int) (__virtscr->maxx - 1)) + || cellcmp(clp->line, buf)) { +#endif /* HAVE_WCHAR */ + for (i = __virtscr->maxx; + i > BLANKSIZE; i -= BLANKSIZE) { - (void)memcpy(clp->line + i - + (void) memcpy(clp->line + i - BLANKSIZE, buf, sizeof(buf)); } - (void)memcpy(clp->line , buf, i * + (void) memcpy(clp->line , buf, i * sizeof(buf[0])); #ifdef DEBUG __CTRACE(__CTRACE_REFRESH, @@ -1335,9 +1695,9 @@ __unsetattr(int checkms) "__unsetattr: checkms = %d, ms = %s, wattr = %08x\n", checkms, __tc_ms ? "TRUE" : "FALSE", curscr->wattr); #endif - + /* - * Don't leave the screen in standout mode (check against ms). Check + * Don't leave the screen in standout mode (check against ms). Check * to see if we also turn off underscore, attributes and colour. */ if (curscr->wattr & __STANDOUT && isms) { @@ -1362,11 +1722,81 @@ __unsetattr(int checkms) curscr->wattr &= __mask_me; } /* Don't leave the screen with altcharset set (don't check ms). */ +#ifndef HAVE_WCHAR if (curscr->wattr & __ALTCHARSET) { tputs(__tc_ae, 0, __cputchar); curscr->wattr &= ~__ALTCHARSET; } +#else + if (curscr->wattr & WA_ALTCHARSET) { + tputs(__tc_ae, 0, __cputchar); + curscr->wattr &= ~WA_ALTCHARSET; + } +#endif /* HAVE_WCHAR */ /* Don't leave the screen with colour set (check against ms). */ if (__using_color && isms) __unset_color(curscr); } + +#ifdef HAVE_WCHAR +/* compare two cells on screen, must have the same forground/background, + * and the same sequence of non-spacing characters */ +int +cellcmp( __LDATA *x, __LDATA *y ) +{ + nschar_t *xnp = x->nsp, *ynp = y->nsp; + int ret = ( x->ch == y->ch ) & ( x->attr == y->attr ); + + if ( !ret ) + return 0; + if ( !xnp && !ynp ) + return 1; + if (( xnp && !ynp ) || ( !xnp && ynp )) + return 0; + + while ( xnp && ynp ) { + if ( xnp->ch != ynp->ch ) + return 0; + xnp = xnp->next; + ynp = ynp->next; + } + return ( !xnp && !ynp ); +} + +/* compare two line segments */ +int +linecmp( __LDATA *xl, __LDATA *yl, size_t len ) +{ + int i = 0; + __LDATA *xp = xl, *yp = yl; + + for ( i = 0; i < len; i++, xp++, yp++ ) { + if ( !cellcmp( xp, yp )) + return 0; + } + return 1; +} + +/* + * Output the non-spacing characters associated with the given character + * cell to the screen. + */ + +void +__cursesi_putnsp(nschar_t *nsp, const int wy, const int wx) +{ + nschar_t *p; + + p = nsp; + while (p != NULL) { + __cputwchar((int) p->ch); +#ifdef BEBUG + __CTRACE(__CTRACE_REFRESH, + "_cursesi_putnsp: (%d,%d) non-spacing putwchar(0x%x)\n", + wy, wx - 1, p->ch); +#endif + p = p->next; + } +} + +#endif /* HAVE_WCHAR */ diff --git a/lib/libcurses/resize.c b/lib/libcurses/resize.c index bfaa5858bce..f8864c89dcc 100644 --- a/lib/libcurses/resize.c +++ b/lib/libcurses/resize.c @@ -1,4 +1,4 @@ -/* $NetBSD: resize.c,v 1.13 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: resize.c,v 1.14 2007/05/28 15:01:57 blymn Exp $ */ /* * Copyright (c) 2001 @@ -40,7 +40,7 @@ #if 0 static char sccsid[] = "@(#)resize.c blymn 2001/08/26"; #else -__RCSID("$NetBSD: resize.c,v 1.13 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: resize.c,v 1.14 2007/05/28 15:01:57 blymn Exp $"); #endif #endif /* not lint */ @@ -179,6 +179,14 @@ __resizewin(WINDOW *win, int nlines, int ncols) __CTRACE(__CTRACE_WINDOW, "resize: win->scr_b = %d\n", win->scr_b); #endif + /* + * free up any non-spacing storage before we lose the + * pointers... + */ +#ifdef HAVE_WCHAR + __cursesi_win_free_nsp(win); +#endif + if (nlines <= 0 || ncols <= 0) nlines = ncols = 0; else { @@ -229,8 +237,7 @@ __resizewin(WINDOW *win, int nlines, int ncols) /* Point line pointers to line space. */ for (lp = win->lspace, i = 0; i < nlines; i++, lp++) { win->lines[i] = lp; - olp = win->orig->lines[i + win->begy - - win->orig->begy]; + olp = win->orig->lines[i + win->begy - win->orig->begy]; lp->line = &olp->line[win->ch_off]; #ifdef DEBUG lp->sentinel = SENTINEL_VALUE; @@ -257,8 +264,16 @@ __resizewin(WINDOW *win, int nlines, int ncols) for (i = 0; i < win->maxy; i++) { lp = win->lines[i]; for (sp = lp->line, j = 0; j < win->maxx; j++, sp++) { - sp->ch = ' '; sp->attr = 0; +#ifndef HAVE_WCHAR + sp->ch = win->bch; +#else + sp->ch = ( wchar_t )btowc(( int ) win->bch ); + sp->nsp = NULL; + if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) + return ERR; + SET_WCOL( *sp, 1 ); +#endif /* HAVE_WCHAR */ } lp->hash = __hash((char *)(void *)lp->line, (size_t) (ncols * __LDATASIZE)); @@ -294,4 +309,3 @@ __resizewin(WINDOW *win, int nlines, int ncols) return OK; } - diff --git a/lib/libcurses/screen.c b/lib/libcurses/screen.c index 96880cafbd4..fd00e51705f 100644 --- a/lib/libcurses/screen.c +++ b/lib/libcurses/screen.c @@ -1,4 +1,4 @@ -/* $NetBSD: screen.c,v 1.19 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: screen.c,v 1.20 2007/05/28 15:01:57 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)screen.c 8.2 (blymn) 11/27/2001"; #else -__RCSID("$NetBSD: screen.c,v 1.19 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: screen.c,v 1.20 2007/05/28 15:01:57 blymn Exp $"); #endif #endif /* not lint */ @@ -90,6 +90,9 @@ set_term(SCREEN *new) __virtscr = new->__virtscr; _cursesi_reset_acs(new); +#ifdef HAVE_WCHAR + _cursesi_reset_wacs(new); +#endif /* HAVE_WCHAR */ #ifdef DEBUG __CTRACE(__CTRACE_SCREEN, "set_term: LINES = %d, COLS = %d\n", @@ -117,10 +120,14 @@ newterm(char *type, FILE *outfd, FILE *infd) if ((new_screen = (SCREEN *) malloc(sizeof(SCREEN))) == NULL) return NULL; +#ifdef DEBUG + __CTRACE(__CTRACE_INIT, "newterm\n"); +#endif + new_screen->infd = infd; new_screen->outfd = outfd; new_screen->echoit = new_screen->nl = 1; - new_screen->pfast = new_screen->rawmode = new_screen->noqch = 0; + new_screen->pfast = new_screen->rawmode = new_screen->noqch = 0; new_screen->nca = A_NORMAL; new_screen->color_type = COLOR_NONE; new_screen->COLOR_PAIRS = 0; @@ -166,8 +173,11 @@ newterm(char *type, FILE *outfd, FILE *infd) } __init_getch(new_screen); - __init_acs(new_screen); +#ifdef HAVE_WCHAR + __init_get_wch( new_screen ); + __init_wacs(new_screen); +#endif /* HAVE_WCHAR */ __set_stophandler(); __set_winchhandler(); diff --git a/lib/libcurses/setterm.c b/lib/libcurses/setterm.c index 5aa67663b86..5733962914d 100644 --- a/lib/libcurses/setterm.c +++ b/lib/libcurses/setterm.c @@ -1,4 +1,4 @@ -/* $NetBSD: setterm.c,v 1.40 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: setterm.c,v 1.41 2007/05/28 15:01:57 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)setterm.c 8.8 (Berkeley) 10/25/94"; #else -__RCSID("$NetBSD: setterm.c,v 1.40 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: setterm.c,v 1.41 2007/05/28 15:01:57 blymn Exp $"); #endif #endif /* not lint */ @@ -105,8 +105,15 @@ static char *_PC, &__tc_SR, &__tc_sr, &__tc_ta, &__tc_te, &__tc_ti, /* uc ue UP up us */ &__tc_uc, &__tc_ue, &__tc_UP, &__tc_up, &__tc_us, +#ifndef HAVE_WCHAR /* vb ve vi vs */ &__tc_vb, &__tc_ve, &__tc_vi, &__tc_vs +#else + /* vb ve vi vs Xh */ + &__tc_vb, &__tc_ve, &__tc_vi, &__tc_vs, &__tc_Xh, + /* Xl Xo Xr Xt Xv */ + &__tc_Xl, &__tc_Xo, &__tc_Xr, &__tc_Xt, &__tc_Xv +#endif /* HAVE_WCHAR */ }; attr_t __mask_op, __mask_me, __mask_ue, __mask_se; @@ -167,7 +174,8 @@ _cursesi_setterm(char *type, SCREEN *screen) COLS = screen->COLS; #ifdef DEBUG - __CTRACE(__CTRACE_INIT, "setterm: LINES = %d, COLS = %d\n", LINES, COLS); + __CTRACE(__CTRACE_INIT, "setterm: LINES = %d, COLS = %d\n", + LINES, COLS); #endif if (!unknown) { if (zap(screen) == ERR) /* Get terminal description.*/ @@ -188,7 +196,7 @@ _cursesi_setterm(char *type, SCREEN *screen) } else screen->CA = 1; - /* + /* * set the pad char, only take the first char of the pc capability * as this is all we can use. */ @@ -221,7 +229,11 @@ _cursesi_setterm(char *type, SCREEN *screen) /* * Precalculate conflict info for color/attribute end commands. */ +#ifndef HAVE_WCHAR screen->mask_op = __ATTRIBUTES & ~__COLOR; +#else + screen->mask_op = WA_ATTRIBUTES & ~__COLOR; +#endif /* HAVE_WCHAR */ if (screen->tc_op != NULL) { if (does_esc_m(screen->tc_op)) screen->mask_op &= @@ -245,10 +257,18 @@ _cursesi_setterm(char *type, SCREEN *screen) if (screen->tc_me != NULL && does_ctrl_o(screen->tc_me)) screen->mask_me = 0; else +#ifndef HAVE_WCHAR screen->mask_me = __ALTCHARSET; +#else + screen->mask_me = WA_ALTCHARSET; +#endif /* HAVE_WCHAR */ /* Check what turning off the attributes also turns off */ +#ifndef HAVE_WCHAR screen->mask_ue = __ATTRIBUTES & ~__UNDERSCORE; +#else + screen->mask_ue = WA_ATTRIBUTES & ~__UNDERSCORE; +#endif /* HAVE_WCHAR */ if (screen->tc_ue != NULL) { if (does_esc_m(screen->tc_ue)) screen->mask_ue &= @@ -265,7 +285,11 @@ _cursesi_setterm(char *type, SCREEN *screen) screen->mask_ue &= ~__COLOR; } } +#ifndef HAVE_WCHAR screen->mask_se = __ATTRIBUTES & ~__STANDOUT; +#else + screen->mask_se = WA_ATTRIBUTES & ~__STANDOUT; +#endif /* HAVE_WCHAR */ if (screen->tc_se != NULL) { if (does_esc_m(screen->tc_se)) screen->mask_se &= @@ -354,7 +378,8 @@ zap(SCREEN *screen) *(tmp + 1) = *(namp + 1); *fp++ = t_getflag(screen->cursesi_genbuf, tmp); #ifdef DEBUG - __CTRACE(__CTRACE_INIT, "%2.2s = %s\n", namp, fp[-1] ? "TRUE" : "FALSE"); + __CTRACE(__CTRACE_INIT, "%2.2s = %s\n", namp, + fp[-1] ? "TRUE" : "FALSE"); #endif namp += 2; screen->flag_count++; @@ -373,7 +398,11 @@ zap(SCREEN *screen) screen->int_count++; } while (*namp); - nampstr = "ABacaeAFALalasbcblbtcdceclcmcrcsdcDLdldmDOdoeAedeihoIcicimIpipk0k1k2k3k4k5k6k7k8k9kdkekhklkrkskuLEllmambmdmemhmkmmmompmrndnlocoppcrcRISbscseSFSfsfsospSRsrtatetiucueUPupusvbvevivs"; +#ifndef HAVE_WCHAR + nampstr = "ABacaeAFALalasbcblbtcdceclcmcrcsdcDLdldmDOdoeAedeihoIcicimIpipk0k1k2k3k4k5k6k7k8k9kdkekhklkrkskuLEllmambmdmemhmkmmmompmrndnlocoppcrcRISbscseSFSfsfsospSRsrtatetiucueUPupusvbvevivs"; +#else + nampstr = "ABacaeAFALalasbcblbtcdceclcmcrcsdcDLdldmDOdoeAedeihoIcicimIpipk0k1k2k3k4k5k6k7k8k9kdkekhklkrkskuLEllmambmdmemhmkmmmompmrndnlocoppcrcRISbscseSFSfsfsospSRsrtatetiucueUPupusvbvevivsXhXlXoXrXtXv"; +#endif /* HAVE_WCHAR */ namp = nampstr; sp = &screen->tc_AB; @@ -383,11 +412,13 @@ zap(SCREEN *screen) *(tmp + 1) = *(namp + 1); *sp++ = t_agetstr(screen->cursesi_genbuf, tmp); #ifdef DEBUG - __CTRACE(__CTRACE_INIT, "%2.2s = %s", namp, sp[-1] == NULL ? "NULL\n" : "\""); - if (sp[-1] != NULL) { + if (sp[-1] == NULL) + __CTRACE(__CTRACE_INIT, "%2.2s = NULL\n", namp); + else { + __CTRACE(__CTRACE_INIT, "%2.2s = \"", namp); for (cp = sp[-1]; *cp; cp++) __CTRACE(__CTRACE_INIT, "%s", unctrl(*cp)); - __CTRACE(__CTRACE_INIT, "\n"); + __CTRACE(__CTRACE_INIT, "\"\n"); } #endif namp += 2; diff --git a/lib/libcurses/shlib_version b/lib/libcurses/shlib_version index 47120ec1ab5..90d669d675c 100644 --- a/lib/libcurses/shlib_version +++ b/lib/libcurses/shlib_version @@ -1,7 +1,7 @@ -# $NetBSD: shlib_version,v 1.36 2004/03/28 08:59:15 jdc Exp $ +# $NetBSD: shlib_version,v 1.37 2007/05/28 15:01:57 blymn Exp $ # Remember to update distrib/sets/lists/base/shl.* when changing # Remember to increment the major numbers of both libform and libmenu # when the libcurses major number increments. # major=6 -minor=1 +minor=2 diff --git a/lib/libcurses/touchwin.c b/lib/libcurses/touchwin.c index 980e3aecad2..d26ddd67c89 100644 --- a/lib/libcurses/touchwin.c +++ b/lib/libcurses/touchwin.c @@ -1,4 +1,4 @@ -/* $NetBSD: touchwin.c,v 1.23 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: touchwin.c,v 1.24 2007/05/28 15:01:58 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)touchwin.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: touchwin.c,v 1.23 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: touchwin.c,v 1.24 2007/05/28 15:01:58 blymn Exp $"); #endif #endif /* not lint */ @@ -43,7 +43,7 @@ __RCSID("$NetBSD: touchwin.c,v 1.23 2007/01/21 13:25:36 jdc Exp $"); /* * is_linetouched -- - * Indicate if line has been touched or not. + * Indicate if line has been touched or not. */ bool is_linetouched(WINDOW *win, int line) @@ -83,7 +83,7 @@ int wredrawln(WINDOW *win, int start, int count) /* * is_wintouched -- - * Check if the window has been touched. + * Check if the window has been touched. */ bool is_wintouched(WINDOW *win) @@ -127,7 +127,7 @@ redrawwin(WINDOW *win) /* * untouchwin -- - * Make it look like the window has not been changed. + * Make it look like the window has not been changed. */ int untouchwin(WINDOW *win) @@ -140,8 +140,8 @@ untouchwin(WINDOW *win) /* * wtouchln -- - * If changed is 1 then touch n lines starting at line. If changed - * is 0 then mark the lines as unchanged. + * If changed is 1 then touch n lines starting at line. If changed + * is 0 then mark the lines as unchanged. */ int wtouchln(WINDOW *win, int line, int n, int changed) @@ -176,7 +176,7 @@ wtouchln(WINDOW *win, int line, int n, int changed) int __touchwin(WINDOW *win) { - int y, maxy; + int y, maxy; #ifdef DEBUG __CTRACE(__CTRACE_LINE, "__touchwin: (%p)\n", win); diff --git a/lib/libcurses/tty.c b/lib/libcurses/tty.c index dbdbef089fc..7127d2ef3da 100644 --- a/lib/libcurses/tty.c +++ b/lib/libcurses/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.39 2007/01/21 13:25:36 jdc Exp $ */ +/* $NetBSD: tty.c,v 1.40 2007/05/28 15:01:58 blymn Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)tty.c 8.6 (Berkeley) 1/10/95"; #else -__RCSID("$NetBSD: tty.c,v 1.39 2007/01/21 13:25:36 jdc Exp $"); +__RCSID("$NetBSD: tty.c,v 1.40 2007/05/28 15:01:58 blymn Exp $"); #endif #endif /* not lint */ @@ -630,3 +630,37 @@ killchar(void) return 0; return _cursesi_screen->baset.c_cc[VKILL]; } + +/* + * erasewchar -- + * Return the wide character of the erase key. + */ +int +erasewchar( wchar_t *ch ) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + if (_cursesi_screen->notty == TRUE) + return ERR; + *ch = _cursesi_screen->baset.c_cc[VERASE]; + return OK; +#endif /* HAVE_WCHAR */ +} + +/* + * killwchar -- + * Return the wide character of the kill key. + */ +int +killwchar( wchar_t *ch ) +{ +#ifndef HAVE_WCHAR + return ERR; +#else + if (_cursesi_screen->notty == TRUE) + return 0; + *ch = _cursesi_screen->baset.c_cc[VKILL]; + return OK; +#endif /* HAVE_WCHAR */ +} diff --git a/lib/libcurses/unctrl.c b/lib/libcurses/unctrl.c index d1506540983..ffb6aeb4d3a 100644 --- a/lib/libcurses/unctrl.c +++ b/lib/libcurses/unctrl.c @@ -1,4 +1,4 @@ -/* $NetBSD: unctrl.c,v 1.10 2004/02/14 18:23:45 christos Exp $ */ +/* $NetBSD: unctrl.c,v 1.11 2007/05/28 15:01:58 blymn Exp $ */ /* * Copyright (c) 1981, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)unctrl.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: unctrl.c,v 1.10 2004/02/14 18:23:45 christos Exp $"); +__RCSID("$NetBSD: unctrl.c,v 1.11 2007/05/28 15:01:58 blymn Exp $"); #endif #endif /* not lint */ @@ -110,3 +110,41 @@ const unsigned char __unctrllen[256] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, }; + +#ifdef HAVE_WCHAR +const wchar_t * const __wunctrl[256] = { + L"^@", L"^A", L"^B", L"^C", L"^D", L"^E", L"^F", L"^G", + L"^H", L"^I", L"^J", L"^K", L"^L", L"^M", L"^N", L"^O", + L"^P", L"^Q", L"^R", L"^S", L"^T", L"^U", L"^V", L"^W", + L"^X", L"^Y", L"^Z", L"^[", L"^\\", L"^]", L"^~", L"^_", + L" ", L"!", L"\"", L"#", L"$", L"%", L"&", L"'", + L"(", L")", L"*", L"+", L",", L"-", L".", L"/", + L"0", L"1", L"2", L"3", L"4", L"5", L"6", L"7", + L"8", L"9", L":", L";", L"<", L"=", L">", L"?", + L"@", L"A", L"B", L"C", L"D", L"E", L"F", L"G", + L"H", L"I", L"J", L"K", L"L", L"M", L"N", L"O", + L"P", L"Q", L"R", L"S", L"T", L"U", L"V", L"W", + L"X", L"Y", L"Z", L"[", L"\\", L"]", L"^", L"_", + L"`", L"a", L"b", L"c", L"d", L"e", L"f", L"g", + L"h", L"i", L"j", L"k", L"l", L"m", L"n", L"o", + L"p", L"q", L"r", L"s", L"t", L"u", L"v", L"w", + L"x", L"y", L"z", L"{", L"|", L"}", L"~", L"^?", + + L"0x80", L"0x81", L"0x82", L"0x83", L"0x84", L"0x85", L"0x86", L"0x87", + L"0x88", L"0x89", L"0x8a", L"0x8b", L"0x8c", L"0x8d", L"0x8e", L"0x8f", + L"0x90", L"0x91", L"0x92", L"0x93", L"0x94", L"0x95", L"0x96", L"0x97", + L"0x98", L"0x99", L"0x9a", L"0x9b", L"0x9c", L"0x9d", L"0x9e", L"0x9f", + L"0xa0", L"0xa1", L"0xa2", L"0xa3", L"0xa4", L"0xa5", L"0xa6", L"0xa7", + L"0xa8", L"0xa9", L"0xaa", L"0xab", L"0xac", L"0xad", L"0xae", L"0xaf", + L"0xb0", L"0xb1", L"0xb2", L"0xb3", L"0xb4", L"0xb5", L"0xb6", L"0xb7", + L"0xb8", L"0xb9", L"0xba", L"0xbb", L"0xbc", L"0xbd", L"0xbe", L"0xbf", + L"0xc0", L"0xc1", L"0xc2", L"0xc3", L"0xc4", L"0xc5", L"0xc6", L"0xc7", + L"0xc8", L"0xc9", L"0xca", L"0xcb", L"0xcc", L"0xcd", L"0xce", L"0xcf", + L"0xd0", L"0xd1", L"0xd2", L"0xd3", L"0xd4", L"0xd5", L"0xd6", L"0xd7", + L"0xd8", L"0xd9", L"0xda", L"0xdb", L"0xdc", L"0xdd", L"0xde", L"0xdf", + L"0xe0", L"0xe1", L"0xe2", L"0xe3", L"0xe4", L"0xe5", L"0xe6", L"0xe7", + L"0xe8", L"0xe9", L"0xea", L"0xeb", L"0xec", L"0xed", L"0xee", L"0xef", + L"0xf0", L"0xf1", L"0xf2", L"0xf3", L"0xf4", L"0xf5", L"0xf6", L"0xf7", + L"0xf8", L"0xf9", L"0xfa", L"0xfb", L"0xfc", L"0xfd", L"0xfe", L"0xff", +}; +#endif /* HAVE_WCHAR */ diff --git a/lib/libcurses/unctrl.h b/lib/libcurses/unctrl.h index 3e38c4dd9c4..f8a04cf8093 100644 --- a/lib/libcurses/unctrl.h +++ b/lib/libcurses/unctrl.h @@ -1,4 +1,4 @@ -/* $NetBSD: unctrl.h,v 1.3 2004/02/14 18:23:45 christos Exp $ */ +/* $NetBSD: unctrl.h,v 1.4 2007/05/28 15:01:58 blymn Exp $ */ /* * Copyright (c) 1982, 1993 @@ -35,14 +35,24 @@ #define _UNCTRL_H_ #include <sys/cdefs.h> +#ifdef HAVE_WCHAR +#include <wchar.h> +#include <curses.h> +#endif /* HAVE_WCHAR */ __BEGIN_DECLS extern const char * const __unctrl[]; /* Control strings. */ extern const unsigned char __unctrllen[]; /* Control strings length. */ +#ifdef HAVE_WCHAR +extern const wchar_t * const __wunctrl[]; /* Wide char control strings. */ +#endif /* HAVE_WCHAR */ __END_DECLS /* 8-bit ASCII characters. */ #define unctrl(c) __unctrl[((unsigned char)c) & 0xff] -#define unctrllen(c) __unctrllen[((unsigned char)c) & 0xff] +#define unctrllen(c) __unctrllen[((unsigned char)c) & 0xff] +#ifdef HAVE_WCHAR +#define wunctrl(wc) __wunctrl[( int )(wc->vals[ 0 ]) & 0xff] +#endif /* HAVE_WCHAR */ #endif /* _UNCTRL_H_ */ |
