ncurses 5.6 - patch 20070526

+ modify keyname() to use "^X" form only if meta() has been called, or
  if keyname() is called without initializing curses, e.g., via
  initscr() or newterm() (prompted by LinuxBase #1604).
+ document some portability issues in man/curs_util.3x
+ add a shadow copy of TTY buffer to _nc_prescreen to fix applications
  broken by moving that data into SCREEN (cf: 20061230).
This commit is contained in:
Thomas E. Dickey 2007-05-26 23:44:27 +00:00
parent 1051e5f924
commit 2c829dd4fa
9 changed files with 480 additions and 45 deletions

10
NEWS
View File

@ -25,7 +25,7 @@
-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
-- $Id: NEWS,v 1.1127 2007/05/12 22:31:49 tom Exp $
-- $Id: NEWS,v 1.1128 2007/05/26 21:46:41 tom Exp $
-------------------------------------------------------------------------------
This is a log of changes that ncurses has gone through since Zeyd started
@ -45,6 +45,14 @@ 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.
20070526
+ modify keyname() to use "^X" form only if meta() has been called, or
if keyname() is called without initializing curses, e.g., via
initscr() or newterm() (prompted by LinuxBase #1604).
+ document some portability issues in man/curs_util.3x
+ add a shadow copy of TTY buffer to _nc_prescreen to fix applications
broken by moving that data into SCREEN (cf: 20061230).
20070512
+ add 'O' (wide-character panel test) in ncurses.c to demonstrate a
problem reported by Sadrul H Chowdhury with repainting parts of

View File

@ -25,7 +25,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
# $Id: dist.mk,v 1.593 2007/05/12 15:09:42 tom Exp $
# $Id: dist.mk,v 1.594 2007/05/26 17:49:30 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 = 6
NCURSES_PATCH = 20070512
NCURSES_PATCH = 20070526
# We don't append the patch to the version, since this only applies to releases
VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)

View File

@ -26,7 +26,7 @@
.\" authorization. *
.\"***************************************************************************
.\"
.\" $Id: curs_terminfo.3x,v 1.27 2007/03/11 00:15:07 tom Exp $
.\" $Id: curs_terminfo.3x,v 1.28 2007/05/26 20:09:06 tom Exp $
.TH curs_terminfo 3X ""
.ds n 5
.na
@ -319,7 +319,7 @@ the SCREEN data allocated in either \fBinitscr\fR or \fBnewterm\fR.
So though it is documented as a terminfo function,
\fBmvcur\fR is really a curses function which is not well specified.
.PP
XSI states that the old location must be given.
XSI states that the old location must be given for \fBmvcur\fP.
This implementation allows the caller to use -1's for the old ordinates.
In that case, the old location is unknown.
.PP

View File

@ -26,7 +26,7 @@
.\" authorization. *
.\"***************************************************************************
.\"
.\" $Id: curs_util.3x,v 1.23 2007/02/24 15:59:07 tom Exp $
.\" $Id: curs_util.3x,v 1.25 2007/05/26 21:44:42 tom Exp $
.TH curs_util 3X ""
.na
.hy 0
@ -146,6 +146,29 @@ returns an error if the associated \fBfwrite\fP calls return an error.
The XSI Curses standard, Issue 4 describes these functions.
It states that \fBunctrl\fR and \fBwunctrl\fR will return a null pointer if
unsuccessful, but does not define any error conditions.
This implementation checks for three cases:
.RS
.TP 5
-
the parameter is a 7-bit US-ASCII code.
This is the case that X/Open Curses documented.
.TP 5
-
the parameter is in the range 128-159, i.e., a C1 control code.
If \fBuse_legacy_coding\fP has been called with a \fB2\fP parameter,
\fBunctrl\fP returns the parameter, i.e., a one-character string with
the parameter as the first character.
Otherwise, it returns ``~@'', ``~A'', etc., analogous to ``^@'', ``^A'', C0 controls.
.IP
X/Open Curses does not document whether \fBunctrl\fP can be called before
initializing curses.
This implementation permits that,
and returns the ``~@'', etc., values in that case.
.TP 5
-
parameter values outside the 0 to 255 range.
\fBunctrl\fP returns a null pointer.
.RE
.PP
The SVr4 documentation describes the action of \fBfilter\fR only in the vaguest
terms. The description here is adapted from the XSI Curses standard (which
@ -157,13 +180,24 @@ showing C1 controls from the upper-128 codes with a `~' prefix rather than `^'.
Other implementations have different conventions.
For example, they may show both sets of control characters with `^',
and strip the parameter to 7 bits.
Or they may ignore C1 controls and treat all of the upper-1280 codes as
Or they may ignore C1 controls and treat all of the upper-128 codes as
printable.
This implementation uses 8 bits but does not modify the string to reflect
locale.
The \fBuse_legacy_coding\fP function allows the caller to
change the output of \fBunctrl\fP.
.PP
Likewise, the \fBmeta\fP function allows the caller to change the
output of \fBkeyname\fP, i.e.,
it determines whether to use the `M-' prefix
for ``meta'' keys (codes in the range 128 to 255).
Both \fBuse_legacy_coding\fP and \fBmeta\fP succeed only after
curses is initialized.
X/Open Curses does not document the treatment of codes 128 to 159.
When treating them as ``meta'' keys
(or if \fBkeyname\fP is called before initializing curses),
this implementation returns strings ``M-^@'', ``M-^A'', etc.
.PP
The \fBkeyname\fP function may return the names of user-defined
string capabilities which are defined in the terminfo entry via the \fB-x\fP
option of \fBtic\fP.
@ -182,7 +216,8 @@ be conditioned using NCURSES_VERSION.
\fBcurses\fR(3X),
\fBcurs_initscr\fR(3X),
\fBcurs_kernel\fR(3X),
\fBcurs_scr_dump\fR(3X).
\fBcurs_scr_dump\fR(3X),
\fBlegacy_coding\fR(3X).
.\"#
.\"# The following sets edit modes for GNU EMACS
.\"# Local Variables:

View File

@ -1,4 +1,4 @@
# $Id: MKkeyname.awk,v 1.32 2007/04/21 23:01:49 tom Exp $
# $Id: MKkeyname.awk,v 1.33 2007/05/26 20:58:24 tom Exp $
##############################################################################
# Copyright (c) 1999-2006,2007 Free Software Foundation, Inc. #
# #
@ -74,7 +74,7 @@ END {
print " if (MyTable[c] == 0) {"
print " int cc = c;"
print " p = name;"
print " if (cc >= 128) {"
print " if (cc >= 128 && (SP == 0 || SP->_use_meta)) {"
print " strcpy(p, \"M-\");"
print " p += 2;"
print " cc -= 128;"

View File

@ -34,7 +34,7 @@
/*
* $Id: curses.priv.h,v 1.331 2007/05/12 18:10:46 tom Exp $
* $Id: curses.priv.h,v 1.332 2007/05/26 18:47:51 tom Exp $
*
* curses.priv.h
*
@ -551,6 +551,7 @@ typedef struct {
ripoff_t rippedoff[N_RIPS];
ripoff_t *rsp;
TPARM_STATE tparm_state;
TTY *saved_tty; /* savetty/resetty information */
#if BROKEN_LINKER || USE_REENTRANT
chtype *real_acs_map;
#endif

View File

@ -41,7 +41,7 @@
#include <curses.priv.h>
MODULE_ID("$Id: lib_data.c,v 1.25 2007/05/12 18:12:12 tom Exp $")
MODULE_ID("$Id: lib_data.c,v 1.26 2007/05/26 18:48:07 tom Exp $")
/*
* OS/2's native linker complains if we don't initialize public data when
@ -210,6 +210,7 @@ NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = {
NUM_VARS_0s, /* dynamic_var */
NUM_VARS_0s, /* static_vars */
},
NULL, /* saved_tty */
#if BROKEN_LINKER || USE_REENTRANT
NULL, /* real_acs_map */
#endif

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
* Copyright (c) 1998-2006,2007 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 *
@ -38,31 +38,35 @@
#include <curses.priv.h>
#include <term.h> /* cur_term */
MODULE_ID("$Id: lib_ttyflags.c,v 1.14 2006/12/30 21:37:20 tom Exp $")
MODULE_ID("$Id: lib_ttyflags.c,v 1.15 2007/05/26 18:54:25 tom Exp $")
NCURSES_EXPORT(int)
_nc_get_tty_mode(TTY * buf)
{
int result = OK;
if (cur_term == 0) {
if (buf == 0) {
result = ERR;
} else {
for (;;) {
if (GET_TTY(cur_term->Filedes, buf) != 0) {
if (errno == EINTR)
continue;
result = ERR;
if (cur_term == 0) {
result = ERR;
} else {
for (;;) {
if (GET_TTY(cur_term->Filedes, buf) != 0) {
if (errno == EINTR)
continue;
result = ERR;
}
break;
}
break;
}
if (result == ERR)
memset(buf, 0, sizeof(*buf));
TR(TRACE_BITS, ("_nc_get_tty_mode(%d): %s",
cur_term->Filedes, _nc_trace_ttymode(buf)));
}
if (result == ERR)
memset(buf, 0, sizeof(*buf));
TR(TRACE_BITS, ("_nc_get_tty_mode(%d): %s",
cur_term->Filedes, _nc_trace_ttymode(buf)));
return (result);
}
@ -71,22 +75,26 @@ _nc_set_tty_mode(TTY * buf)
{
int result = OK;
if (cur_term == 0) {
if (buf == 0) {
result = ERR;
} else {
for (;;) {
if (SET_TTY(cur_term->Filedes, buf) != 0) {
if (errno == EINTR)
continue;
if ((errno == ENOTTY) && (SP != 0))
SP->_notty = TRUE;
result = ERR;
if (cur_term == 0) {
result = ERR;
} else {
for (;;) {
if (SET_TTY(cur_term->Filedes, buf) != 0) {
if (errno == EINTR)
continue;
if ((errno == ENOTTY) && (SP != 0))
SP->_notty = TRUE;
result = ERR;
}
break;
}
break;
}
TR(TRACE_BITS, ("_nc_set_tty_mode(%d): %s",
cur_term->Filedes, _nc_trace_ttymode(buf)));
}
TR(TRACE_BITS, ("_nc_set_tty_mode(%d): %s",
cur_term->Filedes, _nc_trace_ttymode(buf)));
return (result);
}
@ -164,6 +172,22 @@ reset_shell_mode(void)
returnCode(ERR);
}
static TTY *
saved_tty(void)
{
TTY *result = 0;
if (SP != 0) {
result = &(SP->_saved_tty);
} else {
if (_nc_prescreen.saved_tty == 0) {
_nc_prescreen.saved_tty = typeCalloc(TTY, 1);
}
result = _nc_prescreen.saved_tty;
}
return result;
}
/*
** savetty() and resetty()
**
@ -174,7 +198,7 @@ savetty(void)
{
T((T_CALLED("savetty()")));
returnCode(_nc_get_tty_mode(&(SP->_saved_tty)));
returnCode(_nc_get_tty_mode(saved_tty()));
}
NCURSES_EXPORT(int)
@ -182,5 +206,5 @@ resetty(void)
{
T((T_CALLED("resetty()")));
returnCode(_nc_set_tty_mode(&(SP->_saved_tty)));
returnCode(_nc_set_tty_mode(saved_tty()));
}

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 2003,2006 Free Software Foundation, Inc. *
* Copyright (c) 2007 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 *
@ -26,7 +26,7 @@
* authorization. *
****************************************************************************/
/*
* $Id: demo_panels.c,v 1.2 2006/04/01 19:08:03 tom Exp $
* $Id: demo_panels.c,v 1.5 2007/05/26 22:35:46 tom Exp $
*
* Demonstrate a variety of functions from the panel library.
* Thomas Dickey - 2003/4/26
@ -44,10 +44,376 @@ replace_panel -
#include <panel.h>
int
main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
typedef void (*InitPanel) (void);
typedef void (*FillPanel) (PANEL *);
static bool use_colors;
static NCURSES_CONST char *mod[] =
{
printf("Not implemented - demo for panel library\n");
"test ",
"TEST ",
"(**) ",
"*()* ",
"<--> ",
"LAST "
};
/*+-------------------------------------------------------------------------
saywhat(text)
--------------------------------------------------------------------------*/
static void
saywhat(NCURSES_CONST char *text)
{
wmove(stdscr, LINES - 1, 0);
wclrtoeol(stdscr);
if (text != 0 && *text != '\0') {
waddstr(stdscr, text);
waddstr(stdscr, "; ");
}
waddstr(stdscr, "press any key to continue");
} /* end of saywhat */
static PANEL *
mkpanel(short color, int rows, int cols, int tly, int tlx)
{
WINDOW *win;
PANEL *pan = 0;
char *userdata = malloc(3);
if ((win = newwin(rows, cols, tly, tlx)) != 0) {
if ((pan = new_panel(win)) == 0) {
delwin(win);
} else if (use_colors) {
short fg = (color == COLOR_BLUE) ? COLOR_WHITE : COLOR_BLACK;
short bg = color;
init_pair(color, fg, bg);
wbkgdset(win, (chtype) (COLOR_PAIR(color) | ' '));
} else {
wbkgdset(win, A_BOLD | ' ');
}
}
sprintf(userdata, "p%d", color % 8);
set_panel_userptr(pan, (NCURSES_CONST void *) userdata);
return pan;
}
/*+-------------------------------------------------------------------------
rmpanel(pan)
--------------------------------------------------------------------------*/
static void
rmpanel(PANEL * pan)
{
WINDOW *win = panel_window(pan);
del_panel(pan);
delwin(win);
} /* end of rmpanel */
/*+-------------------------------------------------------------------------
pflush()
--------------------------------------------------------------------------*/
static void
pflush(void)
{
update_panels();
doupdate();
} /* end of pflush */
/*+-------------------------------------------------------------------------
fill_panel(win)
--------------------------------------------------------------------------*/
static void
init_panel(void)
{
register int y, x;
for (y = 0; y < LINES - 1; y++) {
for (x = 0; x < COLS; x++)
wprintw(stdscr, "%d", (y + x) % 10);
}
}
static void
fill_panel(PANEL * pan)
{
WINDOW *win = panel_window(pan);
int num = ((const char *) panel_userptr(pan))[1];
int y, x;
wmove(win, 1, 1);
wprintw(win, "-pan%c-", num);
wclrtoeol(win);
box(win, 0, 0);
for (y = 2; y < getmaxy(win) - 1; y++) {
for (x = 1; x < getmaxx(win) - 1; x++) {
wmove(win, y, x);
waddch(win, UChar(num));
}
}
}
#if USE_WIDEC_SUPPORT
static void
make_fullwidth_digit(cchar_t *target, int digit)
{
wchar_t source[2];
source[0] = digit + 0xff10;
source[1] = 0;
setcchar(target, source, A_NORMAL, 0, 0);
}
static void
init_wide_panel(void)
{
int digit;
cchar_t temp[10];
for (digit = 0; digit < 10; ++digit)
make_fullwidth_digit(&temp[digit], digit);
do {
int y, x;
getyx(stdscr, y, x);
digit = (y + x / 2) % 10;
} while (add_wch(&temp[digit]) != ERR);
}
static void
fill_wide_panel(PANEL * pan)
{
WINDOW *win = panel_window(pan);
int num = ((const char *) panel_userptr(pan))[1];
int y, x;
wmove(win, 1, 1);
wprintw(win, "-pan%c-", num);
wclrtoeol(win);
box(win, 0, 0);
for (y = 2; y < getmaxy(win) - 1; y++) {
for (x = 1; x < getmaxx(win) - 1; x++) {
wmove(win, y, x);
waddch(win, UChar(num));
}
}
}
#endif
#define MAX_PANELS 5
static void
canned_panel(PANEL * px[MAX_PANELS + 1], NCURSES_CONST char *cmd)
{
int which = cmd[1] - '0';
saywhat(cmd);
switch (*cmd) {
case 'h':
hide_panel(px[which]);
break;
case 's':
show_panel(px[which]);
break;
case 't':
top_panel(px[which]);
break;
case 'b':
bottom_panel(px[which]);
break;
case 'd':
rmpanel(px[which]);
break;
}
pflush();
wgetch(stdscr);
}
static void
demo_panels(void (*myInit) (void), void (*myFill) (PANEL *))
{
int itmp;
PANEL *px[MAX_PANELS + 1];
scrollok(stdscr, FALSE); /* we don't want stdscr to scroll! */
refresh();
myInit();
for (itmp = 1; itmp <= MAX_PANELS; ++itmp)
px[itmp] = 0;
px[1] = mkpanel(COLOR_RED,
LINES / 2 - 2,
COLS / 8 + 1,
0,
0);
px[2] = mkpanel(COLOR_GREEN,
LINES / 2 + 1,
COLS / 7,
LINES / 4,
COLS / 10);
px[3] = mkpanel(COLOR_YELLOW,
LINES / 4,
COLS / 10,
LINES / 2,
COLS / 9);
px[4] = mkpanel(COLOR_BLUE,
LINES / 2 - 2,
COLS / 8,
LINES / 2 - 2,
COLS / 3);
px[5] = mkpanel(COLOR_MAGENTA,
LINES / 2 - 2,
COLS / 8,
LINES / 2,
COLS / 2 - 2);
myFill(px[1]);
myFill(px[2]);
myFill(px[3]);
myFill(px[4]);
myFill(px[5]);
hide_panel(px[4]);
hide_panel(px[5]);
pflush();
saywhat("");
wgetch(stdscr);
saywhat("h3 s1 s2 s4 s5");
move_panel(px[1], 0, 0);
hide_panel(px[3]);
show_panel(px[1]);
show_panel(px[2]);
show_panel(px[4]);
show_panel(px[5]);
pflush();
wgetch(stdscr);
canned_panel(px, "s1");
canned_panel(px, "s2");
saywhat("m2");
move_panel(px[2], LINES / 3 + 1, COLS / 8);
pflush();
wgetch(stdscr);
canned_panel(px, "s3");
saywhat("m3");
move_panel(px[3], LINES / 4 + 1, COLS / 15);
pflush();
wgetch(stdscr);
canned_panel(px, "b3");
canned_panel(px, "s4");
canned_panel(px, "s5");
canned_panel(px, "t3");
canned_panel(px, "t1");
canned_panel(px, "t2");
canned_panel(px, "t3");
canned_panel(px, "t4");
for (itmp = 0; itmp < 6; itmp++) {
WINDOW *w4 = panel_window(px[4]);
WINDOW *w5 = panel_window(px[5]);
saywhat("m4");
wmove(w4, LINES / 8, 1);
waddstr(w4, mod[itmp]);
move_panel(px[4], LINES / 6, itmp * (COLS / 8));
wmove(w5, LINES / 6, 1);
waddstr(w5, mod[itmp]);
pflush();
wgetch(stdscr);
saywhat("m5");
wmove(w4, LINES / 6, 1);
waddstr(w4, mod[itmp]);
move_panel(px[5], LINES / 3 - 1, (itmp * 10) + 6);
wmove(w5, LINES / 8, 1);
waddstr(w5, mod[itmp]);
pflush();
wgetch(stdscr);
}
saywhat("m4");
move_panel(px[4], LINES / 6, itmp * (COLS / 8));
pflush();
wgetch(stdscr);
canned_panel(px, "t5");
canned_panel(px, "t2");
canned_panel(px, "t1");
canned_panel(px, "d2");
canned_panel(px, "h3");
canned_panel(px, "d1");
canned_panel(px, "d4");
canned_panel(px, "d5");
canned_panel(px, "d3");
wgetch(stdscr);
erase();
endwin();
}
static void
usage(void)
{
static const char *const tbl[] =
{
"Usage: demo_panels [options]"
,""
,"Options:"
," -m do not use colors"
#if USE_WIDEC_SUPPORT
," -w use wide-characters in panels and background"
#endif
};
size_t n;
for (n = 0; n < SIZEOF(tbl); n++)
fprintf(stderr, "%s\n", tbl[n]);
ExitProgram(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
int c;
bool monochrome = FALSE;
InitPanel myInit = init_panel;
FillPanel myFill = fill_panel;
while ((c = getopt(argc, argv, "mw")) != EOF) {
switch (c) {
case 'm':
monochrome = TRUE;
break;
#if USE_WIDEC_SUPPORT
case 'w':
myInit = init_wide_panel;
myFill = fill_wide_panel;
break;
#endif
default:
usage();
}
}
initscr();
use_colors = monochrome ? FALSE : has_colors();
if (use_colors)
start_color();
demo_panels(myInit, myFill);
endwin();
return EXIT_SUCCESS;
}
#else