From 5b7f4de105080e2a715b0564ede4bb7eb6767659 Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sat, 4 Jul 2009 23:55:21 +0000 Subject: [PATCH] ncurses 5.7 - patch 20090704 + remove wide-character checks from unctrl() (patch by Clemens Ladisch). + revise wadd_wch() and wecho_wchar() to eliminate dependency on unctrl(). + continue integrating "sp-funcs" by Juergen Pfeifer (incomplete). --- NEWS | 8 +- dist.mk | 4 +- include/curses.h.in | 3 +- include/nc_panel.h | 33 +-- ncurses/Makefile.in | 13 +- ncurses/base/MKunctrl.awk | 19 +- ncurses/base/lib_endwin.c | 21 +- ncurses/base/lib_getch.c | 58 ++++- ncurses/base/lib_mouse.c | 24 +- ncurses/base/lib_nl.c | 6 +- ncurses/base/lib_pad.c | 38 +-- ncurses/base/lib_slk.c | 210 +++++++++------- ncurses/base/resizeterm.c | 33 ++- ncurses/curses.priv.h | 11 +- ncurses/tinfo/lib_options.c | 5 +- ncurses/tty/MKexpanded.sh | 7 +- ncurses/widechar/lib_add_wch.c | 439 +++++++++++++++++++++++++++++---- 17 files changed, 690 insertions(+), 242 deletions(-) diff --git a/NEWS b/NEWS index 848a07d7..8de73713 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.1398 2009/06/27 20:59:09 tom Exp $ +-- $Id: NEWS,v 1.1400 2009/07/04 22:12:46 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,12 @@ See the AUTHORS file for the corresponding full names. Changes through 1.9.9e did not credit all contributions; it is not possible to add this information. +20090704 + + remove wide-character checks from unctrl() (patch by Clemens Ladisch). + + revise wadd_wch() and wecho_wchar() to eliminate dependency on + unctrl(). + + continue integrating "sp-funcs" by Juergen Pfeifer (incomplete). + 20090627 + update llib-lncurses[wt] to use sp-funcs. + various code-fixes to build/work with --disable-macros configure diff --git a/dist.mk b/dist.mk index 4f3110dd..79f76e23 100644 --- a/dist.mk +++ b/dist.mk @@ -25,7 +25,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.706 2009/06/27 22:21:38 tom Exp $ +# $Id: dist.mk,v 1.707 2009/07/04 17:04:26 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -37,7 +37,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 5 NCURSES_MINOR = 7 -NCURSES_PATCH = 20090627 +NCURSES_PATCH = 20090704 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/include/curses.h.in b/include/curses.h.in index 0220752b..43424675 100644 --- a/include/curses.h.in +++ b/include/curses.h.in @@ -32,7 +32,7 @@ * and: Thomas E. Dickey 1996-on * ****************************************************************************/ -/* $Id: curses.h.in,v 1.202 2009/06/13 21:44:51 tom Exp $ */ +/* $Id: curses.h.in,v 1.203 2009/07/04 20:19:26 tom Exp $ */ #ifndef __NCURSES_H #define __NCURSES_H @@ -844,6 +844,7 @@ extern NCURSES_EXPORT(char *) keybound (int, int); extern NCURSES_EXPORT(const char *) curses_version (void); extern NCURSES_EXPORT(int) assume_default_colors (int, int); extern NCURSES_EXPORT(int) define_key (const char *, int); +extern NCURSES_EXPORT(int) get_escdelay (void); extern NCURSES_EXPORT(int) key_defined (const char *); extern NCURSES_EXPORT(int) keyok (int, bool); extern NCURSES_EXPORT(int) resize_term (int, int); diff --git a/include/nc_panel.h b/include/nc_panel.h index ece95947..6a9ffea3 100644 --- a/include/nc_panel.h +++ b/include/nc_panel.h @@ -31,9 +31,8 @@ * and: Thomas E. Dickey * ****************************************************************************/ - /* - * $Id: nc_panel.h,v 1.6 2009/04/11 21:17:57 tom Exp $ + * $Id: nc_panel.h,v 1.7 2009/07/04 18:20:02 tom Exp $ * * nc_panel.h * @@ -45,29 +44,33 @@ #define NC_PANEL_H 1 #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -struct panel; /* Forward Declaration */ + struct panel; /* Forward Declaration */ -struct panelhook { - struct panel* top_panel; - struct panel* bottom_panel; - struct panel* stdscr_pseudo_panel; + struct panelhook + { + struct panel *top_panel; + struct panel *bottom_panel; + struct panel *stdscr_pseudo_panel; #if NO_LEAKS - int (*destroy)(struct panel *); + int (*destroy) (struct panel *); #endif -}; - -/* Retrieve the panelhook of the current screen */ -extern NCURSES_EXPORT(struct panelhook*) _nc_panelhook (void); + }; + struct screen; /* Forward declaration */ +/* Retrieve the panelhook of the specified screen */ + extern NCURSES_EXPORT(struct panelhook *) + _nc_panelhook (void); #if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(struct panelhook*) NCURSES_SP_NAME(_nc_panelhook) (SCREEN *); + extern NCURSES_EXPORT(struct panelhook *) + NCURSES_SP_NAME(_nc_panelhook) (SCREEN *); #endif #ifdef __cplusplus } #endif -#endif /* NC_PANEL_H */ +#endif /* NC_PANEL_H */ diff --git a/ncurses/Makefile.in b/ncurses/Makefile.in index 043c8029..0f94e433 100644 --- a/ncurses/Makefile.in +++ b/ncurses/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.116 2009/06/27 14:31:36 tom Exp $ +# $Id: Makefile.in,v 1.117 2009/07/04 16:36:11 tom Exp $ ############################################################################## # Copyright (c) 1998-2007,2009 Free Software Foundation, Inc. # # # @@ -165,11 +165,12 @@ TEST_PROGS = \ hashmap$x \ lib_mvcur$x -base = $(srcdir)/base -serial = $(srcdir)/tty -tinfo = $(srcdir)/tinfo -trace = $(srcdir)/trace -wide = $(srcdir)/widechar +base = $(srcdir)/base +serial = $(srcdir)/tty +tinfo = $(srcdir)/tinfo +trace = $(srcdir)/trace +wide = $(srcdir)/widechar +win32con = $(srcdir)/win32con ################################################################################ all \ diff --git a/ncurses/base/MKunctrl.awk b/ncurses/base/MKunctrl.awk index 2c37d442..2140900e 100644 --- a/ncurses/base/MKunctrl.awk +++ b/ncurses/base/MKunctrl.awk @@ -1,4 +1,4 @@ -# $Id: MKunctrl.awk,v 1.25 2009/04/18 23:43:49 tom Exp $ +# $Id: MKunctrl.awk,v 1.26 2009/07/04 22:05:15 Clemens.Ladisch Exp $ ############################################################################## # Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. # # # @@ -36,12 +36,6 @@ BEGIN { print "#include " print "#include " print "" - print "#if USE_WIDEC_SUPPORT" - print "#if HAVE_WCTYPE_H" - print "#include " - print "#endif" - print "#endif" - print "" print "#undef unctrl" print "" } @@ -157,16 +151,6 @@ END { print "\t\t && (check < 160))" printf "\t\t\tresult = %s_c1[check - 128];\n", stringname; print "\t\telse" - print "#if USE_WIDEC_SUPPORT" - print "\t\tif ((check >= 160)" - print "\t\t && (check < 256)" - print "\t\t && ((sp != 0)" - print "\t\t && ((sp->_legacy_coding > 0)" - print "\t\t || (sp->_legacy_coding == 0" - print "\t\t && (isprint(check) || iswprint(check))))))" - printf "\t\t\tresult = %s_c1[check - 128];\n", stringname; - print "\t\telse" - print "#else" print "\t\tif ((check >= 160)" print "\t\t && (check < 256)" print "\t\t && ((sp != 0)" @@ -175,7 +159,6 @@ END { print "\t\t && isprint(check)))))" printf "\t\t\tresult = %s_c1[check - 128];\n", stringname; print "\t\telse" - print "#endif /* USE_WIDEC_SUPPORT */" print "#endif /* NCURSES_EXT_FUNCS */" printf "\t\t\tresult = %s_table[check];\n", stringname; print "\t} else {" diff --git a/ncurses/base/lib_endwin.c b/ncurses/base/lib_endwin.c index 386db405..3b552dae 100644 --- a/ncurses/base/lib_endwin.c +++ b/ncurses/base/lib_endwin.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2000,2009 Free Software Foundation, Inc. * + * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -41,24 +41,33 @@ */ #include -#include -MODULE_ID("$Id: lib_endwin.c,v 1.20 2009/02/15 00:35:00 tom Exp $") +MODULE_ID("$Id: lib_endwin.c,v 1.21 2009/07/04 18:35:43 tom Exp $") NCURSES_EXPORT(int) NCURSES_SP_NAME(endwin) (NCURSES_SP_DCL0) { - T((T_CALLED("endwin()"))); + int code = ERR; + + T((T_CALLED("endwin(%p)"), SP_PARM)); if (SP_PARM) { +#ifdef USE_TERM_DRIVER + TERMINAL_CONTROL_BLOCK *TCB = TCBOf(SP_PARM); + + SP_PARM->_endwin = TRUE; + if (TCB && TCB->drv && TCB->drv->scexit) + TCB->drv->scexit(SP_PARM); +#else SP_PARM->_endwin = TRUE; SP_PARM->_mouse_wrap(SP_PARM); _nc_screen_wrap(); _nc_mvcur_wrap(); /* wrap up cursor addressing */ - returnCode(reset_shell_mode()); +#endif + code = NCURSES_SP_NAME(reset_shell_mode) (NCURSES_SP_ARG); } - returnCode(ERR); + returnCode(code); } #if NCURSES_SP_FUNCS diff --git a/ncurses/base/lib_getch.c b/ncurses/base/lib_getch.c index e228355a..ccfcc336 100644 --- a/ncurses/base/lib_getch.c +++ b/ncurses/base/lib_getch.c @@ -42,12 +42,12 @@ #include -MODULE_ID("$Id: lib_getch.c,v 1.103 2009/05/30 15:50:47 tom Exp $") +MODULE_ID("$Id: lib_getch.c,v 1.104 2009/07/04 20:41:13 tom Exp $") #include #if USE_REENTRANT -#define GetEscdelay(sp) (sp)->_ESCDELAY +#define GetEscdelay(sp) *_nc_ptr_Escdelay(sp) NCURSES_EXPORT(int *) _nc_ptr_Escdelay(SCREEN *sp) { @@ -56,7 +56,7 @@ _nc_ptr_Escdelay(SCREEN *sp) NCURSES_EXPORT(int) NCURSES_PUBLIC_VAR(ESCDELAY) (void) { - return *_nc_ptr_Escdelay(CURRENT_SCREEN); + return *(_nc_ptr_Escdelay(CURRENT_SCREEN)); } #else #define GetEscdelay(sp) ESCDELAY @@ -71,7 +71,7 @@ NCURSES_SP_NAME(set_escdelay) (NCURSES_SP_DCLx int value) int code = OK; #if USE_REENTRANT if (SP_PARM) { - SP_PARM->_ESCDELAY = value; + SET_ESCDELAY(value); } else { code = ERR; } @@ -86,7 +86,33 @@ NCURSES_SP_NAME(set_escdelay) (NCURSES_SP_DCLx int value) NCURSES_EXPORT(int) set_escdelay(int value) { - return NCURSES_SP_NAME(set_escdelay) (CURRENT_SCREEN, value); + int code; +#if USE_REENTRANT + code = NCURSES_SP_NAME(set_escdelay) (CURRENT_SCREEN, value); +#else + ESCDELAY = value; + code = OK; +#endif + return code; +} +#endif +#endif /* NCURSES_EXT_FUNCS */ + +#if NCURSES_EXT_FUNCS +NCURSES_EXPORT(int) +NCURSES_SP_NAME(get_escdelay) (NCURSES_SP_DCL0) +{ +#if !USE_REENTRANT + (void) SP_PARM; +#endif + return GetEscdelay(SP_PARM); +} + +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(int) +get_escdelay (void) +{ + return NCURSES_SP_NAME(get_escdelay)(CURRENT_SCREEN); } #endif #endif /* NCURSES_EXT_FUNCS */ @@ -115,10 +141,22 @@ check_mouse_activity(SCREEN *sp, int delay EVENTLIST_2nd(_nc_eventlist * evl)) #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail)) { - return 2; + return TW_MOUSE; } #endif - rc = _nc_timed_wait(sp, TWAIT_MASK, delay, (int *) 0 EVENTLIST_2nd(evl)); +#ifdef USE_TERM_DRIVER + rc = TCBOf(sp)->drv->twait(TCBOf(sp), + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); +#else + rc = _nc_timed_wait(sp, + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); +#endif #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail) @@ -220,9 +258,15 @@ fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) } else #endif { /* Can block... */ +#ifdef USE_TERM_DRIVER + int buf; + n = CallDriver_1(sp, read, &buf); + ch = buf; +#else unsigned char c2 = 0; n = read(sp->_ifd, &c2, 1); ch = c2; +#endif } #ifdef HIDE_EINTR diff --git a/ncurses/base/lib_mouse.c b/ncurses/base/lib_mouse.c index f0ad82fc..cd760dc0 100644 --- a/ncurses/base/lib_mouse.c +++ b/ncurses/base/lib_mouse.c @@ -30,6 +30,7 @@ * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * * and: Thomas E. Dickey 1996-on * + * and: Juergen Pfeifer 2008 * ****************************************************************************/ /* @@ -80,10 +81,10 @@ #include #ifndef CUR -#define CUR SP_TERMTYPE +#define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_mouse.c,v 1.107 2009/05/10 00:48:29 tom Exp $") +MODULE_ID("$Id: lib_mouse.c,v 1.108 2009/07/04 19:51:08 tom Exp $") #include @@ -153,7 +154,7 @@ make an error #define LIBGPM_SONAME "libgpm.so" #endif -#define GET_DLSYM(name) (my_##name = (TYPE_##name) dlsym(SP_PARM->_dlopen_gpm, #name)) +#define GET_DLSYM(name) (my_##name = (TYPE_##name) dlsym(sp->_dlopen_gpm, #name)) #endif /* USE_GPM_SUPPORT */ @@ -347,6 +348,9 @@ handle_sysmouse(int sig GCC_UNUSED) } #endif /* USE_SYSMOUSE */ +#ifndef USE_TERM_DRIVER +#define xterm_kmous "\033[M" + static void init_xterm_mouse(SCREEN *sp) { @@ -355,6 +359,7 @@ init_xterm_mouse(SCREEN *sp) if (!VALID_STRING(sp->_mouse_xtermcap)) sp->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;"; } +#endif static void enable_xterm_mouse(SCREEN *sp, int enable) @@ -483,8 +488,6 @@ enable_gpm_mouse(SCREEN *sp, bool enable) } #endif /* USE_GPM_SUPPORT */ -#define xterm_kmous "\033[M" - static void initialize_mousetype(SCREEN *sp) { @@ -519,7 +522,7 @@ initialize_mousetype(SCREEN *sp) /* OS/2 VIO */ #if USE_EMX_MOUSE if (!sp->_emxmouse_thread - && strstr(cur_term->type.term_names, "xterm") == 0 + && strstr(TerminalOf(sp)->type.term_names, "xterm") == 0 && key_mouse) { int handles[2]; @@ -626,16 +629,21 @@ initialize_mousetype(SCREEN *sp) } #endif /* USE_SYSMOUSE */ +#ifdef USE_TERM_DRIVER + CallDriver(sp, initmouse); +#else /* we know how to recognize mouse events under "xterm" */ if (key_mouse != 0) { if (!strcmp(key_mouse, xterm_kmous) - || strstr(cur_term->type.term_names, "xterm") != 0) { + || strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { init_xterm_mouse(sp); } - } else if (strstr(cur_term->type.term_names, "xterm") != 0) { + } else if (strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK) init_xterm_mouse(sp); } +#endif + returnVoid; } diff --git a/ncurses/base/lib_nl.c b/ncurses/base/lib_nl.c index 9a05ab8b..28c1848c 100644 --- a/ncurses/base/lib_nl.c +++ b/ncurses/base/lib_nl.c @@ -44,7 +44,7 @@ #include -MODULE_ID("$Id: lib_nl.c,v 1.10 2009/02/21 20:58:21 tom Exp $") +MODULE_ID("$Id: lib_nl.c,v 1.11 2009/07/04 00:25:53 tom Exp $") #ifdef __EMX__ #include @@ -59,7 +59,7 @@ NCURSES_SP_NAME(nl) (NCURSES_SP_DCL0) SP_PARM->_nl = TRUE; #ifdef __EMX__ _nc_flush(); - _fsetmode(NC_OUTPUT, "t"); + _fsetmode(NC_OUTPUT(SP_PARM), "t"); #endif returnCode(OK); } @@ -81,7 +81,7 @@ NCURSES_SP_NAME(nonl) (NCURSES_SP_DCL0) SP_PARM->_nl = FALSE; #ifdef __EMX__ _nc_flush(); - _fsetmode(NC_OUTPUT, "b"); + _fsetmode(NC_OUTPUT(SP_PARM), "b"); #endif returnCode(OK); } diff --git a/ncurses/base/lib_pad.c b/ncurses/base/lib_pad.c index 43d9ed7e..ccd3ad7e 100644 --- a/ncurses/base/lib_pad.c +++ b/ncurses/base/lib_pad.c @@ -42,7 +42,7 @@ #include -MODULE_ID("$Id: lib_pad.c,v 1.43 2009/04/18 18:25:37 tom Exp $") +MODULE_ID("$Id: lib_pad.c,v 1.44 2009/07/04 19:45:20 tom Exp $") NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(newpad) (NCURSES_SP_DCLx int l, int c) @@ -51,12 +51,13 @@ NCURSES_SP_NAME(newpad) (NCURSES_SP_DCLx int l, int c) NCURSES_CH_T *ptr; int i; - T((T_CALLED("newpad(%d, %d)"), l, c)); + T((T_CALLED("newpad(%p,%d, %d)"), SP_PARM, l, c)); if (l <= 0 || c <= 0) returnWin(0); - if ((win = _nc_makenew(l, c, 0, 0, _ISPAD)) == NULL) + win = NCURSES_SP_NAME(_nc_makenew) (NCURSES_SP_ARGx l, c, 0, 0, _ISPAD); + if (win == NULL) returnWin(0); for (i = 0; i < l; i++) { @@ -104,10 +105,14 @@ prefresh(WINDOW *win, int smaxrow, int smaxcol) { +#if NCURSES_SP_FUNCS + SCREEN *sp = _nc_screen_of(win); +#endif + T((T_CALLED("prefresh()"))); if (pnoutrefresh(win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol) != ERR - && doupdate() != ERR) { + && NCURSES_SP_NAME(doupdate) (NCURSES_SP_ARG) != ERR) { returnCode(OK); } returnCode(ERR); @@ -126,6 +131,7 @@ pnoutrefresh(WINDOW *win, NCURSES_SIZE_T m, n; NCURSES_SIZE_T pmaxrow; NCURSES_SIZE_T pmaxcol; + SCREEN *sp; #if USE_SCROLL_HINTS const int my_len = 2; /* parameterize the threshold for hardscroll */ @@ -142,6 +148,8 @@ pnoutrefresh(WINDOW *win, if (!(win->_flags & _ISPAD)) returnCode(ERR); + sp = _nc_screen_of(win); + /* negative values are interpreted as zero */ if (pminrow < 0) pminrow = 0; @@ -172,8 +180,8 @@ pnoutrefresh(WINDOW *win, pmaxcol = pmincol + smaxcol - smincol; } - if (smaxrow >= screen_lines(CURRENT_SCREEN) - || smaxcol >= screen_columns(CURRENT_SCREEN) + if (smaxrow >= screen_lines(sp) + || smaxcol >= screen_columns(sp) || sminrow > smaxrow || smincol > smaxcol) returnCode(ERR); @@ -204,13 +212,13 @@ pnoutrefresh(WINDOW *win, * merely change the costs of various update cases. */ #if USE_SCROLL_HINTS - wide = (smincol < my_len && smaxcol > (newscr->_maxx - my_len)); + wide = (smincol < my_len && smaxcol > (NewScreen(sp)->_maxx - my_len)); #endif for (i = pminrow, m = sminrow + win->_yoffset; - i <= pmaxrow && m <= newscr->_maxy; + i <= pmaxrow && m <= NewScreen(sp)->_maxy; i++, m++) { - register struct ldat *nline = &newscr->_line[m]; + register struct ldat *nline = &NewScreen(sp)->_line[m]; register struct ldat *oline = &win->_line[i]; for (j = pmincol, n = smincol; j <= pmaxcol; j++, n++) { NCURSES_CH_T ch = oline->text[j]; @@ -239,9 +247,9 @@ pnoutrefresh(WINDOW *win, || nind > smaxrow) { nind = _NEWINDEX; } else if (displaced) { - register struct ldat *pline = &curscr->_line[nind]; + register struct ldat *pline = &CurScreen(sp)->_line[nind]; for (j = 0; j <= my_len; j++) { - int k = newscr->_maxx - j; + int k = NewScreen(sp)->_maxx - j; if (pline->text[j] != nline->text[j] || pline->text[k] != nline->text[k]) { nind = _NEWINDEX; @@ -276,7 +284,7 @@ pnoutrefresh(WINDOW *win, if (win->_clear) { win->_clear = FALSE; - newscr->_clear = TRUE; + NewScreen(sp)->_clear = TRUE; } /* @@ -288,10 +296,10 @@ pnoutrefresh(WINDOW *win, && win->_curx >= pmincol && win->_cury <= pmaxrow && win->_curx <= pmaxcol) { - newscr->_cury = win->_cury - pminrow + win->_begy + win->_yoffset; - newscr->_curx = win->_curx - pmincol + win->_begx; + NewScreen(sp)->_cury = win->_cury - pminrow + win->_begy + win->_yoffset; + NewScreen(sp)->_curx = win->_curx - pmincol + win->_begx; } - newscr->_leaveok = win->_leaveok; + NewScreen(sp)->_leaveok = win->_leaveok; win->_flags &= ~_HASMOVED; /* diff --git a/ncurses/base/lib_slk.c b/ncurses/base/lib_slk.c index 2f1a9211..127c2990 100644 --- a/ncurses/base/lib_slk.c +++ b/ncurses/base/lib_slk.c @@ -41,30 +41,80 @@ */ #include - #include -#include /* num_labels, label_*, plab_norm */ #ifndef CUR -#define CUR SP_TERMTYPE +#define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_slk.c,v 1.38 2009/05/10 00:48:29 tom Exp $") +MODULE_ID("$Id: lib_slk.c,v 1.39 2009/07/04 18:37:57 tom Exp $") /* * Free any memory related to soft labels, return an error. */ static int -slk_failed(void) +slk_failed(NCURSES_SP_DCL0) { - if (SP->_slk) { - FreeIfNeeded(SP->_slk->ent); - free(SP->_slk); - SP->_slk = (SLK *) 0; + if ((0 != SP_PARM) && SP_PARM->_slk) { + FreeIfNeeded(SP_PARM->_slk->ent); + free(SP_PARM->_slk); + SP_PARM->_slk = (SLK *) 0; } return ERR; } +NCURSES_EXPORT(int) +_nc_format_slks(NCURSES_SP_DCLx int cols) +{ + int gap, i, x; + unsigned max_length = SP_PARM->_slk->maxlen; + + if (!SP_PARM) + return ERR; + + if (SP_PARM->slk_format >= 3) { /* PC style */ + gap = (cols - 3 * (3 + 4 * max_length)) / 2; + + if (gap < 1) + gap = 1; + + for (i = x = 0; i < SP_PARM->_slk->maxlab; i++) { + SP_PARM->_slk->ent[i].ent_x = x; + x += max_length; + x += (i == 3 || i == 7) ? gap : 1; + } + } else { + if (SP_PARM->slk_format == 2) { /* 4-4 */ + gap = cols - (SP_PARM->_slk->maxlab * max_length) - 6; + + if (gap < 1) + gap = 1; + for (i = x = 0; i < SP_PARM->_slk->maxlab; i++) { + SP_PARM->_slk->ent[i].ent_x = x; + x += max_length; + x += (i == 3) ? gap : 1; + } + } else { + if (SP_PARM->slk_format == 1) { /* 1 -> 3-2-3 */ + gap = (cols - (SP_PARM->_slk->maxlab * max_length) - 5) + / 2; + + if (gap < 1) + gap = 1; + for (i = x = 0; i < SP_PARM->_slk->maxlab; i++) { + SP_PARM->_slk->ent[i].ent_x = x; + x += max_length; + x += (i == 2 || i == 4) ? gap : 1; + } + } else + returnCode(slk_failed(NCURSES_SP_ARG)); + } + } + SP_PARM->_slk->dirty = TRUE; + + return OK; +} + /* * Initialize soft labels. * Called from newterm() @@ -72,111 +122,91 @@ slk_failed(void) NCURSES_EXPORT(int) _nc_slk_initialize(WINDOW *stwin, int cols) { -#if NCURSES_SP_FUNCS - SCREEN *sp = CURRENT_SCREEN; -#endif - int i, x; + int i; int res = OK; unsigned max_length; + SCREEN *sp; + TERMINAL *term; + int numlab; T((T_CALLED("_nc_slk_initialize()"))); - if (SP->_slk) { /* we did this already, so simply return */ + assert(stwin); + + sp = _nc_screen_of(stwin); + if (0 == sp) + returnCode(ERR); + + term = TerminalOf(SP_PARM); + assert(term); + + numlab = InfoOf(SP_PARM).numlabels; + + if (SP_PARM->_slk) { /* we did this already, so simply return */ returnCode(OK); - } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0) + } else if ((SP_PARM->_slk = typeCalloc(SLK, 1)) == 0) returnCode(ERR); - SP->_slk->ent = NULL; + SP_PARM->_slk->hidden = TRUE; + SP_PARM->_slk->ent = NULL; + if (!SP_PARM->slk_format) + SP_PARM->slk_format = _nc_globals.slk_format; /* * If we use colors, vidputs() will suppress video attributes that conflict * with colors. In that case, we're still guaranteed that "reverse" would * work. */ - if ((no_color_video & 1) == 0) - SetAttr(SP->_slk->attr, A_STANDOUT); + if ((InfoOf(SP_PARM).nocolorvideo & 1) == 0) + SetAttr(SP_PARM->_slk->attr, A_STANDOUT); else - SetAttr(SP->_slk->attr, A_REVERSE); - - SP->_slk->maxlab = ((num_labels > 0) - ? num_labels - : MAX_SKEY(_nc_globals.slk_format)); - SP->_slk->maxlen = ((num_labels > 0) - ? label_width * label_height - : MAX_SKEY_LEN(_nc_globals.slk_format)); - SP->_slk->labcnt = ((SP->_slk->maxlab < MAX_SKEY(_nc_globals.slk_format)) - ? MAX_SKEY(_nc_globals.slk_format) - : SP->_slk->maxlab); - - if (SP->_slk->maxlen <= 0 - || SP->_slk->labcnt <= 0 - || (SP->_slk->ent = typeCalloc(slk_ent, - (unsigned) SP->_slk->labcnt)) == NULL) - returnCode(slk_failed()); - - max_length = SP->_slk->maxlen; - for (i = 0; i < SP->_slk->labcnt; i++) { + SetAttr(SP_PARM->_slk->attr, A_REVERSE); + + SP_PARM->_slk->maxlab = ((numlab > 0) + ? numlab + : MAX_SKEY(SP_PARM->slk_format)); + SP_PARM->_slk->maxlen = ((numlab > 0) + ? InfoOf(SP_PARM).labelwidth * InfoOf(SP_PARM).labelheight + : MAX_SKEY_LEN(SP_PARM->slk_format)); + SP_PARM->_slk->labcnt = ((SP_PARM->_slk->maxlab < MAX_SKEY(SP_PARM->slk_format)) + ? MAX_SKEY(SP_PARM->slk_format) + : SP_PARM->_slk->maxlab); + + if (SP_PARM->_slk->maxlen <= 0 + || SP_PARM->_slk->labcnt <= 0 + || (SP_PARM->_slk->ent = typeCalloc(slk_ent, + (unsigned) SP_PARM->_slk->labcnt)) + == NULL) + returnCode(slk_failed(NCURSES_SP_ARG)); + + max_length = SP_PARM->_slk->maxlen; + for (i = 0; i < SP_PARM->_slk->labcnt; i++) { size_t used = max_length + 1; - if ((SP->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used)) == 0) - returnCode(slk_failed()); - memset(SP->_slk->ent[i].ent_text, 0, used); + SP_PARM->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used); + if (SP_PARM->_slk->ent[i].ent_text == 0) + returnCode(slk_failed(NCURSES_SP_ARG)); + memset(SP_PARM->_slk->ent[i].ent_text, 0, used); - if ((SP->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used)) == 0) - returnCode(slk_failed()); - memset(SP->_slk->ent[i].form_text, 0, used); + SP_PARM->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used); + if (SP_PARM->_slk->ent[i].form_text == 0) + returnCode(slk_failed(NCURSES_SP_ARG)); + memset(SP_PARM->_slk->ent[i].form_text, 0, used); - memset(SP->_slk->ent[i].form_text, ' ', max_length); - SP->_slk->ent[i].visible = (char) (i < SP->_slk->maxlab); + memset(SP_PARM->_slk->ent[i].form_text, ' ', max_length); + SP_PARM->_slk->ent[i].visible = (char) (i < SP_PARM->_slk->maxlab); } - if (_nc_globals.slk_format >= 3) { /* PC style */ - int gap = (cols - 3 * (3 + 4 * max_length)) / 2; - - if (gap < 1) - gap = 1; - - for (i = x = 0; i < SP->_slk->maxlab; i++) { - SP->_slk->ent[i].ent_x = x; - x += max_length; - x += (i == 3 || i == 7) ? gap : 1; - } - } else { - if (_nc_globals.slk_format == 2) { /* 4-4 */ - int gap = cols - (SP->_slk->maxlab * max_length) - 6; - if (gap < 1) - gap = 1; - for (i = x = 0; i < SP->_slk->maxlab; i++) { - SP->_slk->ent[i].ent_x = x; - x += max_length; - x += (i == 3) ? gap : 1; - } - } else { - if (_nc_globals.slk_format == 1) { /* 1 -> 3-2-3 */ - int gap = (cols - (SP->_slk->maxlab * max_length) - 5) - / 2; + res = _nc_format_slks(NCURSES_SP_ARGx cols); - if (gap < 1) - gap = 1; - for (i = x = 0; i < SP->_slk->maxlab; i++) { - SP->_slk->ent[i].ent_x = x; - x += max_length; - x += (i == 2 || i == 4) ? gap : 1; - } - } else - returnCode(slk_failed()); - } - } - SP->_slk->dirty = TRUE; - if ((SP->_slk->win = stwin) == NULL) { - returnCode(slk_failed()); + if ((SP_PARM->_slk->win = stwin) == NULL) { + returnCode(slk_failed(NCURSES_SP_ARG)); } /* We now reset the format so that the next newterm has again * per default no SLK keys and may call slk_init again to * define a new layout. (juergen 03-Mar-1999) */ - SP->slk_format = _nc_globals.slk_format; _nc_globals.slk_format = 0; returnCode(res); } @@ -187,14 +217,16 @@ _nc_slk_initialize(WINDOW *stwin, int cols) NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_restore) (NCURSES_SP_DCL0) { - T((T_CALLED("slk_restore()"))); + T((T_CALLED("slk_restore(%p)"), SP_PARM)); + if (0 == SP_PARM) + returnCode(ERR); if (SP_PARM->_slk == NULL) - return (ERR); + returnCode(ERR); SP_PARM->_slk->hidden = FALSE; SP_PARM->_slk->dirty = TRUE; - returnCode(slk_refresh()); + returnCode(NCURSES_SP_NAME(slk_refresh) (NCURSES_SP_ARG)); } #if NCURSES_SP_FUNCS diff --git a/ncurses/base/resizeterm.c b/ncurses/base/resizeterm.c index cf99ad0d..494f429d 100644 --- a/ncurses/base/resizeterm.c +++ b/ncurses/base/resizeterm.c @@ -28,6 +28,7 @@ /**************************************************************************** * Author: Thomas E. Dickey * + * and: Juergen Pfeifer * ****************************************************************************/ /* @@ -39,15 +40,12 @@ */ #include -#include #ifndef CUR -#define CUR SP_TERMTYPE +#define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: resizeterm.c,v 1.39 2009/05/10 00:48:29 tom Exp $") - -#define stolen_lines (screen_lines - SP->_lines_avail) +MODULE_ID("$Id: resizeterm.c,v 1.40 2009/07/04 18:38:49 tom Exp $") /* * If we're trying to be reentrant, do not want any local statics. @@ -121,7 +119,7 @@ ripped_window(WINDOW *win) ripoff_t *rop; if (win != 0) { -#if NCURSES_SP_FUNCS +#ifdef USE_SP_RIPOFF SCREEN *sp = _nc_screen_of(win); #endif for (each_ripoff(rop)) { @@ -145,7 +143,7 @@ ripped_bottom(WINDOW *win) ripoff_t *rop; if (win != 0) { -#if NCURSES_SP_FUNCS +#ifdef USE_SP_RIPOFF SCREEN *sp = _nc_screen_of(win); #endif for (each_ripoff(rop)) { @@ -169,7 +167,7 @@ child_depth(WINDOW *cmp) int depth = 0; if (cmp != 0) { -#if NCURSES_SP_FUNCS +#ifdef USE_SP_WINDOWLIST SCREEN *sp = _nc_screen_of(cmp); #endif WINDOWLIST *wp; @@ -229,6 +227,12 @@ adjust_window(WINDOW *win, int ToLines, int ToCols, int stolen EXTRA_DCLS) * move it to the same relative position. */ win->_begy = ToLines - ripped_bottom(win) - 0 - win->_yoffset; + if (rop->hook == _nc_slk_initialize) + _nc_format_slks( +#if NCURSES_SP_FUNCS + _nc_screen_of(win), +#endif + ToCols); } else if (win->_begy >= bottom) { /* * If it is below the bottom of the new screen, move up by the same @@ -379,10 +383,17 @@ NCURSES_SP_NAME(resize_term) (NCURSES_SP_DCLx int ToLines, int ToCols) decrease_size(NCURSES_SP_ARGx ToLines, ToCols, was_stolen EXTRA_ARGS); } - screen_lines(SP_PARM) = lines = ToLines; - screen_columns(SP_PARM) = columns = ToCols; + screen_lines(SP_PARM) = ToLines; + screen_columns(SP_PARM) = ToCols; + +#ifdef USE_TERM_DRIVER + CallDriver_2(SP_PARM, setsize, ToLines, ToCols); +#else + lines = ToLines; + columns = ToCols; +#endif - SP_PARM->_lines_avail = lines - was_stolen; + SP_PARM->_lines_avail = ToLines - was_stolen; if (SP_PARM->oldhash) { FreeAndNull(SP_PARM->oldhash); diff --git a/ncurses/curses.priv.h b/ncurses/curses.priv.h index 5f6b6b74..caf71161 100644 --- a/ncurses/curses.priv.h +++ b/ncurses/curses.priv.h @@ -35,7 +35,7 @@ /* - * $Id: curses.priv.h,v 1.427 2009/06/27 20:31:54 tom Exp $ + * $Id: curses.priv.h,v 1.430 2009/07/04 20:40:42 tom Exp $ * * curses.priv.h * @@ -395,6 +395,9 @@ NCURSES_EXPORT(int *) _nc_ptr_Escdelay (SCREEN *); #define ptrLines(sp) &LINES #define ptrCols(sp) &COLS +#define ptrTabsize(sp) &TABSIZE +#define ptrEscdelay(sp) &ESCDELAY + #define SET_LINES(value) LINES = value #define SET_COLS(value) COLS = value #define SET_TABSIZE(value) TABSIZE = value @@ -934,8 +937,8 @@ struct screen { bool _nc_sp_idlok; bool _nc_sp_idcok; -#define _nc_idlok SP->_nc_sp_idlok -#define _nc_idcok SP->_nc_sp_idcok +#define _nc_idlok SP_PARM->_nc_sp_idlok +#define _nc_idcok SP_PARM->_nc_sp_idcok /* * These are the data that support the mouse interface. @@ -1848,7 +1851,7 @@ extern NCURSES_EXPORT_VAR(SCREEN *) SP; #define screen_columns(sp) (sp)->_columns extern NCURSES_EXPORT(int) _nc_slk_initialize (WINDOW *, int); -extern NCURSES_EXPORT(int) _nc_format_slks (SCREEN *, int); +extern NCURSES_EXPORT(int) _nc_format_slks (NCURSES_SP_DCLx int _c); /* * Some constants related to SLK's diff --git a/ncurses/tinfo/lib_options.c b/ncurses/tinfo/lib_options.c index f22d6c5c..908ee1b0 100644 --- a/ncurses/tinfo/lib_options.c +++ b/ncurses/tinfo/lib_options.c @@ -48,7 +48,7 @@ #define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_options.c,v 1.64 2009/05/23 23:58:07 tom Exp $") +MODULE_ID("$Id: lib_options.c,v 1.65 2009/07/04 18:14:31 tom Exp $") static int _nc_meta(SCREEN *, bool); @@ -70,6 +70,9 @@ idlok(WINDOW *win, bool flag) NCURSES_EXPORT(void) idcok(WINDOW *win, bool flag) { +#if NCURSES_SP_FUNCS + SCREEN *sp = CURRENT_SCREEN; +#endif T((T_CALLED("idcok(%p,%d)"), win, flag)); if (win) diff --git a/ncurses/tty/MKexpanded.sh b/ncurses/tty/MKexpanded.sh index e13996ed..c7741ae7 100755 --- a/ncurses/tty/MKexpanded.sh +++ b/ncurses/tty/MKexpanded.sh @@ -29,7 +29,7 @@ # # Author: Thomas E. Dickey, 1997-on # -# $Id: MKexpanded.sh,v 1.15 2009/06/27 20:37:50 tom Exp $ +# $Id: MKexpanded.sh,v 1.16 2009/07/04 16:45:03 tom Exp $ # # Script to generate 'expanded.c', a dummy source that contains functions # corresponding to complex macros used in this library. By making functions, @@ -55,6 +55,11 @@ cat < #include + +#ifndef CUR +#define CUR SP_TERMTYPE +#endif + #if NCURSES_EXPANDED EOF diff --git a/ncurses/widechar/lib_add_wch.c b/ncurses/widechar/lib_add_wch.c index 93b41bb4..c1c565c1 100644 --- a/ncurses/widechar/lib_add_wch.c +++ b/ncurses/widechar/lib_add_wch.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2004,2006 Free Software Foundation, Inc. * + * Copyright (c) 2004-2006,2009 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -35,79 +35,410 @@ #include -MODULE_ID("$Id: lib_add_wch.c,v 1.6 2006/12/02 21:19:17 tom Exp $") +#if HAVE_WCTYPE_H +#include +#endif -NCURSES_EXPORT(int) -wadd_wch(WINDOW *win, const cchar_t *wch) +MODULE_ID("$Id: lib_add_wch.c,v 1.7 2009/07/04 21:59:25 tom Exp $") + +/* clone/adapt lib_addch.c */ +static const cchar_t blankchar = NewChar(BLANK_TEXT); + +/* + * Ugly microtweaking alert. Everything from here to end of module is + * likely to be speed-critical -- profiling data sure says it is! + * Most of the important screen-painting functions are shells around + * wadd_wch(). So we make every effort to reduce function-call overhead + * by inlining stuff, even at the cost of making wrapped copies for + * export. Also we supply some internal versions that don't call the + * window sync hook, for use by string-put functions. + */ + +/* Return bit mask for clearing color pair number if given ch has color */ +#define COLOR_MASK(ch) (~(attr_t)((ch) & A_COLOR ? A_COLOR : 0)) + +static NCURSES_INLINE cchar_t +render_char(WINDOW *win, cchar_t ch) +/* compute a rendition of the given char correct for the current context */ { - PUTC_DATA; - int n; - int code = ERR; + attr_t a = WINDOW_ATTRS(win); + int pair = GetPair(ch); - TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wadd_wch(%p, %s)"), win, - _tracech_t(wch))); - - if (win != 0) { - PUTC_INIT; - for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) { - attr_t attrs = (wch->attr & A_ATTRIBUTES); - - if ((PUTC_ch = wch->chars[PUTC_i]) == L'\0') - break; - if ((PUTC_n = wcrtomb(PUTC_buf, PUTC_ch, &PUT_st)) <= 0) { - code = ERR; - if (is8bits(PUTC_ch)) - code = waddch(win, UChar(PUTC_ch) | attrs); - break; + if (ISBLANK(ch) + && AttrOf(ch) == A_NORMAL + && pair == 0) { + /* color/pair in attrs has precedence over bkgrnd */ + ch = win->_nc_bkgd; + SetAttr(ch, a | AttrOf(win->_nc_bkgd)); + if ((pair = GET_WINDOW_PAIR(win)) == 0) + pair = GetPair(win->_nc_bkgd); + SetPair(ch, pair); + } else { + /* color in attrs has precedence over bkgrnd */ + a |= AttrOf(win->_nc_bkgd) & COLOR_MASK(a); + /* color in ch has precedence */ + if (pair == 0) { + if ((pair = GET_WINDOW_PAIR(win)) == 0) + pair = GetPair(win->_nc_bkgd); + } +#if 0 + if (pair > 255) { + cchar_t fixme = ch; + SetPair(fixme, pair); + } +#endif + AddAttr(ch, (a & COLOR_MASK(AttrOf(ch)))); + SetPair(ch, pair); + } + + TR(TRACE_VIRTPUT, + ("render_char bkg %s (%d), attrs %s (%d) -> ch %s (%d)", + _tracech_t2(1, CHREF(win->_nc_bkgd)), + GetPair(win->_nc_bkgd), + _traceattr(WINDOW_ATTRS(win)), + GET_WINDOW_PAIR(win), + _tracech_t2(3, CHREF(ch)), + GetPair(ch))); + + return (ch); +} + +/* check if position is legal; if not, return error */ +#ifndef NDEBUG /* treat this like an assertion */ +#define CHECK_POSITION(win, x, y) \ + if (y > win->_maxy \ + || x > win->_maxx \ + || y < 0 \ + || x < 0) { \ + TR(TRACE_VIRTPUT, ("Alert! Win=%p _curx = %d, _cury = %d " \ + "(_maxx = %d, _maxy = %d)", win, x, y, \ + win->_maxx, win->_maxy)); \ + return(ERR); \ + } +#else +#define CHECK_POSITION(win, x, y) /* nothing */ +#endif + +static bool +newline_forces_scroll(WINDOW *win, NCURSES_SIZE_T * ypos) +{ + bool result = FALSE; + + if (*ypos >= win->_regtop && *ypos == win->_regbottom) { + *ypos = win->_regbottom; + result = TRUE; + } else { + *ypos += 1; + } + return result; +} + +/* + * The _WRAPPED flag is useful only for telling an application that we've just + * wrapped the cursor. We don't do anything with this flag except set it when + * wrapping, and clear it whenever we move the cursor. If we try to wrap at + * the lower-right corner of a window, we cannot move the cursor (since that + * wouldn't be legal). So we return an error (which is what SVr4 does). + * Unlike SVr4, we can successfully add a character to the lower-right corner + * (Solaris 2.6 does this also, however). + */ +static int +wrap_to_next_line(WINDOW *win) +{ + win->_flags |= _WRAPPED; + if (newline_forces_scroll(win, &(win->_cury))) { + win->_curx = win->_maxx; + if (!win->_scroll) + return (ERR); + scroll(win); + } + win->_curx = 0; + return (OK); +} + +static int wadd_wch_literal(WINDOW *, cchar_t); +/* + * Fill the given number of cells with blanks using the current background + * rendition. This saves/restores the current x-position. + */ +static void +fill_cells(WINDOW *win, int count) +{ + cchar_t blank = blankchar; + int save_x = win->_curx; + int save_y = win->_cury; + + while (count-- > 0) { + if (wadd_wch_literal(win, blank) == ERR) + break; + } + win->_curx = save_x; + win->_cury = save_y; +} + +static int +wadd_wch_literal(WINDOW *win, cchar_t ch) +{ + int x; + int y; + struct ldat *line; + + x = win->_curx; + y = win->_cury; + + CHECK_POSITION(win, x, y); + + ch = render_char(win, ch); + + line = win->_line + y; + + CHANGED_CELL(line, x); + + /* + * Non-spacing characters are added to the current cell. + * + * Spacing characters that are wider than one column require some display + * adjustments. + */ + { + int len = wcwidth(CharOf(ch)); + int i; + int j; + wchar_t *chars; + + if (len == 0) { /* non-spacing */ + if ((x > 0 && y >= 0) + || (win->_maxx >= 0 && win->_cury >= 1)) { + if (x > 0 && y >= 0) + chars = (win->_line[y].text[x - 1].chars); + else + chars = (win->_line[y - 1].text[win->_maxx].chars); + for (i = 0; i < CCHARW_MAX; ++i) { + if (chars[i] == 0) { + TR(TRACE_VIRTPUT, + ("added non-spacing %d: %x", + x, (int) CharOf(ch))); + chars[i] = CharOf(ch); + break; + } + } } - for (n = 0; n < PUTC_n; n++) { - if ((code = waddch(win, UChar(PUTC_buf[n]) | attrs)) == ERR) { + goto testwrapping; + } else if (len > 1) { /* multi-column characters */ + /* + * Check if the character will fit on the current line. If it does + * not fit, fill in the remainder of the line with blanks. and + * move to the next line. + */ + if (len > win->_maxx + 1) { + TR(TRACE_VIRTPUT, ("character will not fit")); + return ERR; + } else if (x + len > win->_maxx + 1) { + int count = win->_maxx + 1 - x; + TR(TRACE_VIRTPUT, ("fill %d remaining cells", count)); + fill_cells(win, count); + if (wrap_to_next_line(win) == ERR) + return ERR; + x = win->_curx; + y = win->_cury; + line = win->_line + y; + } + /* + * Check for cells which are orphaned by adding this character, set + * those to blanks. + * + * FIXME: this actually could fill j-i cells, more complicated to + * setup though. + */ + for (i = 0; i < len; ++i) { + if (isWidecBase(win->_line[y].text[x + i])) { + break; + } else if (isWidecExt(win->_line[y].text[x + i])) { + for (j = i; x + j <= win->_maxx; ++j) { + if (!isWidecExt(win->_line[y].text[x + j])) { + TR(TRACE_VIRTPUT, ("fill %d orphan cells", j)); + fill_cells(win, j); + break; + } + } break; } } - if (code == ERR) - break; + /* + * Finally, add the cells for this character. + */ + for (i = 0; i < len; ++i) { + cchar_t value = ch; + SetWidecExt(value, i); + TR(TRACE_VIRTPUT, ("multicolumn %d:%d (%d,%d)", + i + 1, len, + win->_begy + y, win->_begx + x)); + line->text[x] = value; + CHANGED_CELL(line, x); + ++x; + } + goto testwrapping; } } - TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code)); - return (code); + /* + * Single-column characters. + */ + line->text[x++] = ch; + /* + * This label is used only for wide-characters. + */ + testwrapping: + + TR(TRACE_VIRTPUT, ("cell (%ld, %ld..%d) = %s", + (long) win->_cury, (long) win->_curx, x - 1, + _tracech_t(CHREF(ch)))); + + if (x > win->_maxx) { + return wrap_to_next_line(win); + } + win->_curx = x; + return OK; } -NCURSES_EXPORT(int) -wecho_wchar(WINDOW *win, const cchar_t *wch) +static NCURSES_INLINE int +wadd_wch_nosync(WINDOW *win, cchar_t ch) +/* the workhorse function -- add a character to the given window */ { - PUTC_DATA; - int n; - int code = ERR; + NCURSES_SIZE_T x, y; + wchar_t *s; + int tabsize = 8; - TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wecho_wchar(%p, %s)"), win, - _tracech_t(wch))); - - if (win != 0) { - PUTC_INIT; - for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) { - attr_t attrs = (wch->attr & A_ATTRIBUTES); - - if ((PUTC_ch = wch->chars[PUTC_i]) == L'\0') - break; - if ((PUTC_n = wcrtomb(PUTC_buf, PUTC_ch, &PUT_st)) <= 0) { - code = ERR; - if (is8bits(PUTC_ch)) - code = waddch(win, UChar(PUTC_ch) | attrs); - break; + /* + * If we are using the alternate character set, forget about locale. + * Otherwise, if the locale * claims the code is printable, treat it that + * way. + */ + if ((AttrOf(ch) & A_ALTCHARSET) + || iswprint(CharOf(ch))) + return wadd_wch_literal(win, ch); + + /* + * Handle carriage control and other codes that are not printable, or are + * known to expand to more than one character according to unctrl(). + */ + x = win->_curx; + y = win->_cury; + + switch (CharOf(ch)) { + case '\t': +#if USE_REENTRANT + tabsize = sp->_TABSIZE; +#else + tabsize = TABSIZE; +#endif + x += (tabsize - (x % tabsize)); + /* + * Space-fill the tab on the bottom line so that we'll get the + * "correct" cursor position. + */ + if ((!win->_scroll && (y == win->_regbottom)) + || (x <= win->_maxx)) { + cchar_t blank = blankchar; + AddAttr(blank, AttrOf(ch)); + while (win->_curx < x) { + if (wadd_wch_literal(win, blank) == ERR) + return (ERR); } - for (n = 0; n < PUTC_n; n++) { - if ((code = waddch(win, UChar(PUTC_buf[n]) | attrs)) == ERR) { - break; + break; + } else { + wclrtoeol(win); + win->_flags |= _WRAPPED; + if (newline_forces_scroll(win, &y)) { + x = win->_maxx; + if (win->_scroll) { + scroll(win); + x = 0; } + } else { + x = 0; + } + } + break; + case '\n': + wclrtoeol(win); + if (newline_forces_scroll(win, &y)) { + if (win->_scroll) + scroll(win); + else + return (ERR); + } + /* FALLTHRU */ + case '\r': + x = 0; + win->_flags &= ~_WRAPPED; + break; + case '\b': + if (x == 0) + return (OK); + x--; + win->_flags &= ~_WRAPPED; + break; + default: + if ((s = wunctrl(&ch)) != 0) { + while (*s) { + cchar_t sch; + SetChar(sch, *s++, AttrOf(ch)); + if_EXT_COLORS(SetPair(sch, GetPair(ch))); + if (wadd_wch_literal(win, sch) == ERR) + return ERR; } - if (code == ERR) - break; + return OK; } - wrefresh(win); + return ERR; } + win->_curx = x; + win->_cury = y; + + return OK; +} + +/* + * The versions below call _nc_synchook(). We wanted to avoid this in the + * version exported for string puts; they'll call _nc_synchook once at end + * of run. + */ + +/* These are actual entry points */ + +NCURSES_EXPORT(int) +wadd_wch(WINDOW *win, const cchar_t *wch) +{ + int code = ERR; + + TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wadd_wch(%p, %s)"), win, + _tracecchar_t(wch))); + + if (win && (wadd_wch_nosync(win, *wch) != ERR)) { + _nc_synchook(win); + code = OK; + } + + TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code)); + return (code); +} + +NCURSES_EXPORT(int) +wecho_wchar(WINDOW *win, const cchar_t *wch) +{ + int code = ERR; + + TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wechochar(%p, %s)"), win, + _tracecchar_t(wch))); + + if (win && (wadd_wch_nosync(win, *wch) != ERR)) { + bool save_immed = win->_immed; + win->_immed = TRUE; + _nc_synchook(win); + win->_immed = save_immed; + code = OK; + } TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code)); return (code); } -- 2.44.0