Tue Jan 24 17:27:30 2017 UTC ()
Implement POSIX Curses Soft Label Key functions.


(roy)
diff -r1.2102 -r1.2103 src/distrib/sets/lists/comp/mi
diff -r1.83 -r1.84 src/lib/libcurses/Makefile
diff -r1.120 -r1.121 src/lib/libcurses/curses.h
diff -r1.59 -r1.60 src/lib/libcurses/curses_private.h
diff -r0 -r1.1 src/lib/libcurses/curses_slk.3
diff -r0 -r1.1 src/lib/libcurses/slk.c
diff -r1.25 -r1.26 src/lib/libcurses/resize.c
diff -r1.2 -r1.3 src/lib/libcurses/ripoffline.c
diff -r1.29 -r1.30 src/lib/libcurses/screen.c

cvs diff -r1.2102 -r1.2103 src/distrib/sets/lists/comp/mi (expand / switch to context diff)
--- src/distrib/sets/lists/comp/mi 2017/01/11 12:02:24 1.2102
+++ src/distrib/sets/lists/comp/mi 2017/01/24 17:27:30 1.2103
@@ -1,4 +1,4 @@
-#	$NetBSD: mi,v 1.2102 2017/01/11 12:02:24 joerg Exp $
+#	$NetBSD: mi,v 1.2103 2017/01/24 17:27:30 roy Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.comp				comp-sys-root
@@ -5739,6 +5739,7 @@
 ./usr/share/man/cat3/curses_scanw.0		comp-c-catman		.cat
 ./usr/share/man/cat3/curses_screen.0		comp-c-catman		.cat
 ./usr/share/man/cat3/curses_scroll.0		comp-c-catman		.cat
+./usr/share/man/cat3/curses_slk.0		comp-c-catman		.cat
 ./usr/share/man/cat3/curses_standout.0		comp-c-catman		.cat
 ./usr/share/man/cat3/curses_termcap.0		comp-c-catman		.cat
 ./usr/share/man/cat3/curses_touch.0		comp-c-catman		.cat
@@ -9008,6 +9009,22 @@
 ./usr/share/man/cat3/sl_find.0			comp-c-catman		.cat
 ./usr/share/man/cat3/sl_free.0			comp-c-catman		.cat
 ./usr/share/man/cat3/sl_init.0			comp-c-catman		.cat
+./usr/share/man/cat3/slk_attroff.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_attr_off.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_attron.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_attr_on.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_attrset.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_attr_set.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_clear.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_color.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_init.0			comp-c-catman		.cat
+./usr/share/man/cat3/slk_label.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_noutrefresh.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_refresh.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_restore.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_set.0			comp-c-catman		.cat
+./usr/share/man/cat3/slk_touch.0		comp-c-catman		.cat
+./usr/share/man/cat3/slk_wset.0			comp-c-catman		.cat
 ./usr/share/man/cat3/sleep.0			comp-c-catman		.cat
 ./usr/share/man/cat3/snprintb.0			comp-c-catman		.cat
 ./usr/share/man/cat3/snprintb_m.0		comp-c-catman		.cat
@@ -13134,6 +13151,7 @@
 ./usr/share/man/html3/curses_scanw.html		comp-c-htmlman		html
 ./usr/share/man/html3/curses_screen.html	comp-c-htmlman		html
 ./usr/share/man/html3/curses_scroll.html	comp-c-htmlman		html
+./usr/share/man/html3/curses_slk.html		comp-c-htmlman		html
 ./usr/share/man/html3/curses_standout.html	comp-c-htmlman		html
 ./usr/share/man/html3/curses_termcap.html	comp-c-htmlman		html
 ./usr/share/man/html3/curses_touch.html		comp-c-htmlman		html
@@ -16339,6 +16357,22 @@
 ./usr/share/man/html3/sl_find.html		comp-c-htmlman		html
 ./usr/share/man/html3/sl_free.html		comp-c-htmlman		html
 ./usr/share/man/html3/sl_init.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_attroff.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_attr_off.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_attron.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_attr_on.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_attrset.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_attr_set.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_clear.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_color.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_init.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_label.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_noutrefresh.html	comp-c-htmlman		html
+./usr/share/man/html3/slk_refresh.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_restore.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_set.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_touch.html		comp-c-htmlman		html
+./usr/share/man/html3/slk_wset.html		comp-c-htmlman		html
 ./usr/share/man/html3/sleep.html		comp-c-htmlman		html
 ./usr/share/man/html3/snprintb.html		comp-c-htmlman		html
 ./usr/share/man/html3/snprintb_m.html		comp-c-htmlman		html
@@ -20436,6 +20470,7 @@
 ./usr/share/man/man3/curses_scanw.3		comp-c-man		.man
 ./usr/share/man/man3/curses_screen.3		comp-c-man		.man
 ./usr/share/man/man3/curses_scroll.3		comp-c-man		.man
+./usr/share/man/man3/curses_slk.3		comp-c-man		.man
 ./usr/share/man/man3/curses_standout.3		comp-c-man		.man
 ./usr/share/man/man3/curses_termcap.3		comp-c-man		.man
 ./usr/share/man/man3/curses_touch.3		comp-c-man		.man
@@ -23701,6 +23736,22 @@
 ./usr/share/man/man3/sl_find.3			comp-c-man		.man
 ./usr/share/man/man3/sl_free.3			comp-c-man		.man
 ./usr/share/man/man3/sl_init.3			comp-c-man		.man
+./usr/share/man/man3/slk_attroff.3		comp-c-man		.man
+./usr/share/man/man3/slk_attr_off.3		comp-c-man		.man
+./usr/share/man/man3/slk_attron.3		comp-c-man		.man
+./usr/share/man/man3/slk_attr_on.3		comp-c-man		.man
+./usr/share/man/man3/slk_attrset.3		comp-c-man		.man
+./usr/share/man/man3/slk_attr_set.3		comp-c-man		.man
+./usr/share/man/man3/slk_clear.3		comp-c-man		.man
+./usr/share/man/man3/slk_color.3		comp-c-man		.man
+./usr/share/man/man3/slk_init.3			comp-c-man		.man
+./usr/share/man/man3/slk_label.3		comp-c-man		.man
+./usr/share/man/man3/slk_noutrefresh.3		comp-c-man		.man
+./usr/share/man/man3/slk_refresh.3		comp-c-man		.man
+./usr/share/man/man3/slk_restore.3		comp-c-man		.man
+./usr/share/man/man3/slk_set.3			comp-c-man		.man
+./usr/share/man/man3/slk_touch.3		comp-c-man		.man
+./usr/share/man/man3/slk_wset.3			comp-c-man		.man
 ./usr/share/man/man3/sleep.3			comp-c-man		.man
 ./usr/share/man/man3/snprintb.3			comp-c-man		.man
 ./usr/share/man/man3/snprintb_m.3		comp-c-man		.man

cvs diff -r1.83 -r1.84 src/lib/libcurses/Makefile (expand / switch to context diff)
--- src/lib/libcurses/Makefile 2017/01/11 20:43:03 1.83
+++ src/lib/libcurses/Makefile 2017/01/24 17:27:30 1.84
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.83 2017/01/11 20:43:03 roy Exp $
+#	$NetBSD: Makefile,v 1.84 2017/01/24 17:27:30 roy Exp $
 #	@(#)Makefile	8.2 (Berkeley) 1/2/94
 
 .include <bsd.own.mk>
@@ -23,7 +23,7 @@
 	insertln.c instr.c keypad.c keyname.c leaveok.c line.c meta.c move.c \
 	mvwin.c newwin.c nodelay.c notimeout.c overlay.c overwrite.c pause.c \
 	printw.c putchar.c refresh.c resize.c ripoffline.c scanw.c screen.c \
-	scroll.c scrollok.c setterm.c standout.c syncok.c timeout.c \
+	scroll.c scrollok.c setterm.c slk.c standout.c syncok.c timeout.c \
 	toucholap.c touchwin.c tstp.c tty.c unctrl.c underscore.c
 
 MAN=	curses.3 curses_addch.3 curses_addchstr.3 curses_addstr.3 \
@@ -34,8 +34,8 @@
 	curses_inch.3 curses_input.3 curses_insertch.3 curses_insertln.3 \
 	curses_insdelln.3 curses_keyname.3 curses_line.3 curses_pad.3 \
 	curses_print.3 curses_refresh.3 curses_scanw.3 curses_screen.3 \
-	curses_scroll.3 curses_standout.3 curses_termcap.3 curses_touch.3 \
-	curses_tty.3 curses_underscore.3 curses_window.3
+	curses_scroll.3 curses_slk.3 curses_standout.3 curses_termcap.3 \
+	curses_touch.3 curses_tty.3 curses_underscore.3 curses_window.3
 INCS=	curses.h unctrl.h
 INCSDIR=/usr/include
 
@@ -150,6 +150,14 @@
 	 curses_cursor.3 setsyx.3 \
 	 curses_input.3 set_escdelay.3 curses_screen.3 set_tabsize.3 \
 	 curses_screen.3 set_term.3 curses_screen.3 setterm.3 \
+	 curses_slk.3 slk_attroff.3 curses_slk.3 slk_attr_off.3 \
+	 curses_slk.3 slk_attron.3 curses_slk.3 slk_attr_on.3 \
+	 curses_slk.3 slk_attrset.3 curses_slk.3 slk_attr_set.3 \
+	 curses_slk.3 slk_clear.3 curses_slk.3 slk_color.3 \
+	 curses_slk.3 slk_init.3 curses_slk.3 slk_label.3 \
+	 curses_slk.3 slk_noutrefresh.3 curses_slk.3 slk_refresh.3 \
+	 curses_slk.3 slk_restore.3 curses_slk.3 slk_set.3 \
+	 curses_slk.3 slk_touch.3 curses_slk.3 slk_wset.3 \
 	 curses_standout.3 standend.3 curses_standout.3 standout.3 \
 	 curses_color.3 start_color.3 curses_pad.3 subpad.3 \
 	 curses_window.3 subwin.3 curses_touch.3 syncok.3 \

cvs diff -r1.120 -r1.121 src/lib/libcurses/curses.h (expand / switch to context diff)
--- src/lib/libcurses/curses.h 2017/01/10 10:13:24 1.120
+++ src/lib/libcurses/curses.h 2017/01/24 17:27:30 1.121
@@ -1,4 +1,4 @@
-/*	$NetBSD: curses.h,v 1.120 2017/01/10 10:13:24 roy Exp $	*/
+/*	$NetBSD: curses.h,v 1.121 2017/01/24 17:27:30 roy Exp $	*/
 
 /*
  * Copyright (c) 1981, 1993, 1994
@@ -842,6 +842,24 @@
 int wchgat(WINDOW *, int, attr_t, short, const void *);
 int mvchgat(int, int, int, attr_t, short, const void *);
 int mvwchgat(WINDOW *, int, int, int, attr_t, short, const void *);
+
+/* Soft Label Keys. */
+int	 slk_attroff(const chtype);
+int	 slk_attr_off(const attr_t, void *);
+int	 slk_attron(const chtype);
+int	 slk_attr_on(const attr_t, void *);
+int	 slk_attrset(const chtype);
+int	 slk_attr_set(const attr_t, short, void *);
+int	 slk_clear(void);
+int	 slk_color(short);
+int	 slk_init(int);
+char	*slk_label(int);
+int	 slk_noutrefresh(void);
+int	 slk_refresh(void);
+int	 slk_restore(void);
+int	 slk_set(int, const char *, int);
+int	 slk_touch(void);
+int	 slk_wset(int, const wchar_t *, int);
 
 /* wide-character support routines */
 /* return ERR when HAVE_WCHAR is not defined */

cvs diff -r1.59 -r1.60 src/lib/libcurses/curses_private.h (expand / switch to context diff)
--- src/lib/libcurses/curses_private.h 2017/01/11 20:43:03 1.59
+++ src/lib/libcurses/curses_private.h 2017/01/24 17:27:30 1.60
@@ -1,4 +1,4 @@
-/*	$NetBSD: curses_private.h,v 1.59 2017/01/11 20:43:03 roy Exp $	*/
+/*	$NetBSD: curses_private.h,v 1.60 2017/01/24 17:27:30 roy Exp $	*/
 
 /*-
  * Copyright (c) 1998-2000 Brett Lymn
@@ -189,6 +189,22 @@
 
 typedef struct keymap keymap_t;
 
+/* POSIX allows up to 8 columns in a label. */
+#define	MAX_SLK_COLS	8
+#ifdef HAVE_WCHAR
+#define	MAX_SLK_LABEL	sizeof(wchar_t) * MAX_SLK_COLS
+#else
+#define	MAX_SLK_LABEL	MAX_SLK_COLS
+#endif
+struct __slk_label {
+	char	*text;
+	int	 justify;
+#define	SLK_JUSTIFY_LEFT	0
+#define	SLK_JUSTIFY_CENTER	1
+#define	SLK_JUSTIFY_RIGHT	2
+	char	 label[MAX_SLK_LABEL + 1];
+	int	 x;
+};
 
 #define	MAX_RIPS	5
 struct __ripoff {
@@ -268,6 +284,18 @@
 	int unget_len, unget_pos;
 	int filtered;
 	int checkfd;
+
+	/* soft label key */
+	bool		 is_term_slk;
+	WINDOW		*slk_window;
+	int		 slk_format;
+#define	SLK_FMT_3_2_3	0
+#define	SLK_FMT_4_4	1
+	int		 slk_nlabels;
+	int		 slk_label_len;
+	bool		 slk_hidden;
+	struct __slk_label *slk_labels;
+
 #ifdef HAVE_WCHAR
 #define MB_LEN_MAX 8
 #define MAX_CBUF_SIZE MB_LEN_MAX
@@ -357,6 +385,10 @@
 void	 __set_stophandler(void);
 void	 __set_winchhandler(void);
 void	 __set_subwin(WINDOW *, WINDOW *);
+int	 __slk_init(SCREEN *);
+void	 __slk_free(SCREEN *);
+int	 __slk_resize(SCREEN *, int cols);
+int	 __slk_noutrefresh(SCREEN *);
 void	 __startwin(SCREEN *);
 void	 __stop_signal_handler(int);
 int	 __stopwin(void);
@@ -365,6 +397,7 @@
 int	 __timeout(int);
 int	 __touchline(WINDOW *, int, int, int);
 int	 __touchwin(WINDOW *);
+int	 __unripoffline(int (*)(WINDOW *, int));
 void	 __unsetattr(int);
 void	 __unset_color(WINDOW *win);
 int	 __waddch(WINDOW *, __LDATA *);

File Added: src/lib/libcurses/curses_slk.3
.\"	$NetBSD: curses_slk.3,v 1.1 2017/01/24 17:27:30 roy Exp $
.\"
.\" Copyright (c) 2017 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Roy Marples.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.\"
.Dd January 12, 2017
.Dt CURSES_SLK 3
.Os
.Sh NAME
.Nm slk_attroff ,
.Nm slk_attr_off ,
.Nm slk_attron ,
.Nm slk_attr_on ,
.Nm slk_attrset ,
.Nm slk_attr_set ,
.Nm slk_clear ,
.Nm slk_color ,
.Nm slk_init ,
.Nm slk_label ,
.Nm slk_noutrefresh ,
.Nm slk_refresh ,
.Nm slk_restore ,
.Nm slk_set ,
.Nm slk_touch ,
.Nm slk_wset
.Nd Curses soft label key routines
.Sh LIBRARY
.Lb libcurses
.Sh SYNOPSIS
.In curses.h
.Ft int
.Fn slk_attroff "const chtype attr"
.Ft int
.Fn slk_attr_off "const attr_t attr" "void *opt"
.Ft int
.Fn slk_attron "const chtype attr"
.Ft int
.Fn slk_attr_on "const attr_t attr" "void *opt"
.Ft int
.Fn slk_attrset "const chtype attr"
.Ft int
.Fn slk_attr_set "const attr_t attr" "void *opt"
.Ft void
.Fn slk_clear "void"
.Ft int
.Fn slk_color "short pair"
.Ft int
.Fn slk_init "int fmt"
.Ft char *
.Fn slk_label "int labnum"
.Ft int
.Fn slk_noutrefresh "void"
.Ft int
.Fn slk_refresh "void"
.Ft int
.Fn slk_restore "void"
.Ft int
.Fn slk_set "int labnum" "const char *label" "int justify"
.Ft int
.Fn slk_touch "void"
.Ft int
.Fn slk_wset "int labnum" "const wchar_t *label" "int justify"
.Sh DESCRIPTION
This Curses interface manipulates the set of soft function-key labels that
exist on some terminals.
For those terminals that do not have soft labels, Curses takes over the bottom
line of
.Dv stdstr ,
reducing the size of
.Dv stdscr
and the value of the
.Dv LINES
external variable.
There can be up to eight labels of up to eight display columns each.
.Pp
To use soft labels,
.Fn slk_init
must be called before
.Xr initscr 3 ,
.Xr newterm 3 ,
or
.Xr ripoffline 3
is called.
If
.Xr newterm 3
eventually uses a line from
.Dv stdscr
to emulate the soft labels, then
.Fa fmt
determines how the labels are arranged on the screen from the following list:
.Bl -tag -width ERR -compact
.It 0
indicates a 3-2-3 arrangement.
.It 1
indicates a 4-4 arrangement.
.El
.Pp
The
.Fn slk_set
and
.Fn slk_wset
functions specify the text of soft label number
.Fa labnum ,
within the range from 1 to 8 inclusive.
The
.Fa label
argument is the string to be put on the label.
The
.Fa justify
argument can have the following values to indicate how to justify
.Fa label
within the space reserved for it:
.Bl -tag -width ERR -compact
.It 0
Left align.
.It 1
Center align.
.It 2
Right align.
.El
.Pp
The
.Fn slk_refresh
and
.Fn slk_noutrefresh
functions correspond to the
.Xr wrefresh 3
and
.Xr wnoutrefresh 3
functions.
.Pp
The
.Fn slk_label
function returns a pointer to the text displayed in the label.
.Pp
The
.Fn slk_clear
function immediately clears the soft labels from the screen.
.Pp
The
.Fn slk_restore
function immediately restores the soft labels to the screen after a call to
.Fn slk_clear .
.Pp
The
.Fn slk_touch
function forces all soft labels to be output the next time
.Fn slk_noutrefresh
or
.Fn slk_refresh
is called.
.Pp
The
.Fn slk_attron ,
.Fn slk_attrset
and
.Fn slk_attroff
functions correspond to
.Xr attron 3 ,
.Xr attrset 3
and
.Xr attroff 3 .
The have an effect only if soft labels are simulated on the bottom line of the
screen.
.Pp
The
.Fn slk_attr_on ,
.Fn slk_attr_set ,
.Fn slk_color
and
.Fn slk_attr_off
functions correspond to
.Xr attr_on 3 ,
.Xr attr_set 3 ,
.Xr color_set 3
and
.Xr attr_off 3
and thus support the attribute constants with the WA_ prefix and color.
The have an effect only if soft labels are simulated on the bottom line of the
screen.
.Pp
The
.Fa opt
argument is reserved for future use.
Currently the application must provide a NULL pointer as
.Fa opt .
.Sh RETURN VALUES
Functions returning pointers will return
.Dv NULL
if an error is detected.
The functions that return an int will return one of the following
values:
.Pp
.Bl -tag -width ERR -compact
.It Er OK
The function completed successfully.
.It Er ERR
An error occurred in the function.
.El
.Sh SEE ALSO
.Xr terminfo 5
.Sh NOTES
This has not been tested on a terminal with real soft label keys.
.Dv label_height ,
.Dv label_width ,
.Dv label_format
and
.Dv lab_f*
are currently not used.
.Sh STANDARDS
The
.Nx
Curses library complies with the X/Open Curses specification, part of the
Single Unix Specification.
.Sh HISTORY
The Curses package appeared in
.Bx 4.0 .
The soft label key functions were added in
.Nx 8.0 .

File Added: src/lib/libcurses/slk.c
/*	$NetBSD: slk.c,v 1.1 2017/01/24 17:27:30 roy Exp $	*/

/*-
 * Copyright (c) 2017 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Roy Marples.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: slk.c,v 1.1 2017/01/24 17:27:30 roy Exp $");
#endif				/* not lint */

#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_WCHAR
#include <wctype.h>
#endif

#include "curses.h"
#include "curses_private.h"

/* Terminals with real soft labels have NOT been tested.
 * If you have such a device, please let us know so this comment
 * can be adjusted. */

/* POSIX says that each label can be up to 8 columns.
 * However, our implementation can allow labels to expand beyond that. */
//#define	SLK_SIZE_DYNAMIC
#ifdef SLK_SIZE_DYNAMIC
#define	SLK_SIZE	MAX_SLK_LABEL
#else
#define	SLK_SIZE	MAX_SLK_COLS
#endif

static int	 slk_fmt;	/* fmt of slk_init */

/* Safe variants of public functions. */
static int	 __slk_attron(SCREEN *, const chtype);
static int	 __slk_attr_on(SCREEN *, const attr_t, void *);
static int	 __slk_attroff(SCREEN *, const chtype);
static int	 __slk_attr_off(SCREEN *, const attr_t, void *);
static int	 __slk_attrset(SCREEN *, const chtype);
static int	 __slk_attr_set(SCREEN *, const attr_t, short, void *opt);
static int	 __slk_color(SCREEN *, short);
static int	 __slk_clear(SCREEN *);
static char	*__slk_label(SCREEN *, int);
static int	 __slk_restore(SCREEN *);
static int	 __slk_set(SCREEN *, int, const char *, int);
static int	 __slk_touch(SCREEN *);
static int	 __slk_wset(SCREEN *, int, const wchar_t *, int);

/* Internal engine parts. */
static int	 __slk_ripoffline(WINDOW *, int);
static int	 __slk_set_finalise(SCREEN *, int);
static int	 __slk_draw(SCREEN *, int);
static int	 __slk_redraw(SCREEN *);

/*
 * slk_init --
 *	Init Soft Label Keys.
 */
int
slk_init(int fmt)
{

	switch(fmt) {
	case SLK_FMT_3_2_3:
	case SLK_FMT_4_4:
		break;
	default:
		return ERR;
	}

	slk_fmt = fmt;
	/* Even if the terminal supports soft label keys directly,
	 * we need to reserve a line. */
	return ripoffline(-1, __slk_ripoffline);
}

/*
 * slk_attron --
 *	Test and set attributes on ripped off slk window.
 */
int
slk_attron(const chtype attr)
{

	return __slk_attron(_cursesi_screen, attr);
}

/*
 * slk_attr_on --
 *	Test and set wide attributes on ripped off slk window.
 */
int
slk_attr_on(const attr_t attr, void *opt)
{

	return __slk_attr_on(_cursesi_screen, attr, opt);
}

/*
 * slk_attroff --
 *	Test and unset attributes on ripped off slk window.
 */
int
slk_attroff(const chtype attr)
{

	return __slk_attroff(_cursesi_screen, attr);
}

/*
 * slk_attr_off --
 *	Test and unset wide attributes on ripped off slk window.
 */
int
slk_attr_off(const attr_t attr, void *opt)
{

	return __slk_attr_off(_cursesi_screen, attr, opt);
}

/*
 * slk_attrset --
 *	Set attributes and color pair on ripped off slk window.
 */
int
slk_attrset(const chtype attr)
{

	return __slk_attrset(_cursesi_screen, attr);
}

/*
 * slk_attr_set --
 *	Set wide attributes and color pair on ripped off slk window.
 */
int
slk_attr_set(const attr_t attr, short pair, void *opt)
{

	return __slk_attr_set(_cursesi_screen, attr, pair, opt);
}

/*
 * slk_clear --
 *	Clear slk from the current screen.
 */
int
slk_clear(void)
{

	return __slk_clear(_cursesi_screen);
}

/*
 * slk_color --
 *	Set color pair on ripped off slk window.
 */
int
slk_color(short pair)
{

	return __slk_color(_cursesi_screen, pair);
}

/*
 * slk_label --
 *	Return a pointer to the saved label for key labnum.
 */
char *
slk_label(int labnum)
{

	return __slk_label(_cursesi_screen, labnum);
}

/*
 * slk_wnoutrefresh --
 *	Add the contents of the ripped off slk window to the virtual window.
 */
int
slk_noutrefresh(void)
{

	return __slk_noutrefresh(_cursesi_screen);
}

/*
 * slk_refresh --
 *	Force a refresh for the ripped off slk window.
 */
int
slk_refresh(void)
{

	if (slk_noutrefresh() == ERR)
		return ERR;
	return doupdate();
}

/*
 * slk_restore --
 *	Retore slk to the screen after a slk_clear.
 */
int
slk_restore(void)
{

	return __slk_restore(_cursesi_screen);
}

/*
 * slk_set --
 *	Sets the text of the label specified by labnum
 *	and how it is displayed.
 */
int
slk_set(int labnum, const char *label, int justify)
{

	return __slk_set(_cursesi_screen, labnum, label, justify);
}

/*
 * slk_touch --
 *	Sets the ripped off slk window as modified.
 */
int
slk_touch(void)
{

	return __slk_touch(_cursesi_screen);
}

/*
 * slk_wset --
 *	Sets the wide text of the label specified by labnum
 *	and how it is displayed.
 */
int
slk_wset(int labnum, const wchar_t *label, int justify)
{

	return __slk_wset(_cursesi_screen, labnum, label, justify);
}

/*
 * __slk_attron --
 *	Test and set attributes on ripped off slk window.
 */
static int
__slk_attron(SCREEN *screen, const chtype attr)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wattron(screen->slk_window, attr);
}

/*
 * __slk_attr_on --
 *	Test and set wide attributes on ripped off slk window.
 */
static int
__slk_attr_on(SCREEN *screen, const attr_t attr, void *opt)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wattr_on(screen->slk_window, attr, opt);
}

/*
 * __slk_attroff --
 *	Test and unset attributes on ripped off slk window.
 */
static int
__slk_attroff(SCREEN *screen, const chtype attr)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wattroff(screen->slk_window, attr);
}

/*
 * __slk_attr_off --
 *	Test and unset wide attributes on ripped off slk window.
 */
static int
__slk_attr_off(SCREEN *screen, const attr_t attr, void *opt)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wattr_off(screen->slk_window, attr, opt);
}

/*
 * __slk_attrset --
 *	Set attributes and color pair on ripped off slk window.
 */
static int
__slk_attrset(SCREEN *screen, const chtype attr)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wattrset(screen->slk_window, attr);
}

/*
 * __slk_attr_set --
 *	Set wide attributes and color pair on ripped off slk window.
 */
static int
__slk_attr_set(SCREEN *screen, const attr_t attr, short pair, void *opt)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wattr_set(screen->slk_window, attr, pair, opt);
}

/*
 * __slk_clear --
 *	Clear slk from the current screen.
 */
static int
__slk_clear(SCREEN *screen)
{

	assert(screen != NULL);
	screen->slk_hidden = true;
	if (screen->is_term_slk) {
		if (t_label_off(screen->term) == NULL)
			return ERR;
		return ti_putp(screen->term,
		    ti_tiparm(screen->term, t_label_off(screen->term)));
	}
	if (screen->slk_window == NULL)
		return ERR;
	werase(screen->slk_window);
	return wrefresh(screen->slk_window);
}

/*
 * __slk_color --
 *	Set color pair on ripped off slk window.
 */
static int
__slk_color(SCREEN *screen, short pair)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wcolor_set(screen->slk_window, pair, NULL);
}


/*
 * __slk_label --
 *	Return a pointer to the saved label for key labnum.
 */
static char *
__slk_label(SCREEN *screen, int labnum)
{

	assert(screen != NULL);
	if (labnum < 1 || labnum > screen->slk_nlabels)
		return NULL;
	return screen->slk_labels[--labnum].text;
}

/*
 * __slk_wnoutrefresh --
 *	Add the contents of the ripped off slk window to the virtual window.
 */
int
__slk_noutrefresh(SCREEN *screen)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return wnoutrefresh(screen->slk_window);
}

/*
 * __slk_restore --
 *	Retore slk to the screen after a slk_clear.
 */
static int
__slk_restore(SCREEN *screen)
{

	assert(screen != NULL);
	screen->slk_hidden = false;
	if (screen->is_term_slk) {
		if (t_label_on(screen->term) == NULL)
			return ERR;
		return ti_putp(screen->term,
		    ti_tiparm(screen->term, t_label_on(screen->term)));
	}
	if (screen->slk_window == NULL)
		return ERR;
	if (__slk_redraw(screen) == ERR)
		return ERR;
	return wrefresh(screen->slk_window);
}

/*
 * __slk_set --
 *	Sets the text of the label specified by labnum
 *	and how it is displayed.
 */
static int
__slk_set(SCREEN *screen, int labnum, const char *label, int justify)
{
	struct __slk_label *l;
	const char *end;
	size_t len;
	char *text;
#ifdef HAVE_WCHAR
	wchar_t wc;
	size_t wc_len;
#endif

	assert(screen != NULL);
	/* Check args. */
	if (labnum < 1 || labnum > screen->slk_nlabels)
		return ERR;
	switch(justify) {
	case SLK_JUSTIFY_LEFT:
	case SLK_JUSTIFY_CENTER:
	case SLK_JUSTIFY_RIGHT:
		break;
	default:
		return ERR;
	}
	if (label == NULL)
		label = "";

	/* Skip leading whitespace. */
	while(isspace((unsigned char)*label))
		label++;
	/* Grab end. */
	end = label;

#ifdef HAVE_WCHAR
	len = 0;
	while (*end != '\0') {
		if ((wc_len = mbrtowc(0, end, strlen(end), &screen->sp)) == -1)
			return ERR;
		mbrtowc(&wc, end, wc_len, &screen->sp);
		if (!iswprint((wint_t)wc))
			break;
		len += wcwidth(wc);
		end += wc_len;
	}
#else
	while(isprint((unsigned char)*end))
		end++;
	len = end - label;
#endif

	/* Take a backup, in-case we can grow the label. */
	if ((text = strndup(label, len)) == NULL)
		return ERR;

	/* All checks out, assign. */
	l = &screen->slk_labels[--labnum]; /* internal zero based index */
	l->text = text;
	l->justify = justify;

	__slk_set_finalise(screen, labnum);
	return OK;
}

/*
 * __slk_touch --
 *	Sets the ripped off slk window as modified.
 */
static int
__slk_touch(SCREEN *screen)
{

	assert(screen != NULL);
	if (screen->slk_window == NULL)
		return ERR;
	return touchwin(screen->slk_window);
}

/*
 * __slk_wset --
 *	Sets the wide text of the label specified by labnum
 *	and how it is displayed.
 */
static int
__slk_wset(SCREEN *screen, int labnum, const wchar_t *label, int justify)
{
#ifdef HAVE_WCHAR
	const wchar_t *olabel;
	size_t len;
	char *str;
	int result = ERR;

	assert(screen != NULL);
	olabel = label;
	if ((len = wcsrtombs(NULL, &olabel, 0, &screen->sp)) == -1)
		return ERR;
	len++; /* We need to store the NULL character. */
	if ((str = malloc(len)) == NULL)
		return ERR;
	olabel = label;
	if (wcsrtombs(str, &olabel, len, &screen->sp) == -1)
		goto out;
	result = __slk_set(screen, labnum, str, justify);
out:
	free(str);
	return result;
#else
	return ERR;
#endif
}


/*
 * __slk_init --
 *	Allocate structures.
 */
int
__slk_init(SCREEN *screen)
{

	__slk_free(screen);	/* safety */

	screen->slk_format = slk_fmt;
	switch(screen->slk_format) {
	case SLK_FMT_3_2_3:
	case SLK_FMT_4_4:
		screen->slk_nlabels = 8;
		break;
	default:	/* impossible */
		return ERR;
	}

	screen->slk_labels = calloc(screen->slk_nlabels,
				    sizeof(*screen->slk_labels));
	if (screen->slk_labels == NULL)
		return ERR;

	screen->is_term_slk =
	    t_plab_norm(screen->term) != NULL &&
	    t_num_labels(screen->term) > 0;
	if (screen->is_term_slk) {
		__unripoffline(__slk_ripoffline);
		screen->slk_nlabels = t_num_labels(screen->term);
		screen->slk_label_len = t_label_width(screen->term);
		/* XXX label_height, label_format? */
	}

	return OK;
}

/*
 * __slk_free --
 *	Free allocates resources.
 */
void
__slk_free(SCREEN *screen)
{
	int i;

	if (screen->slk_window != NULL)
		delwin(screen->slk_window);
	for (i = 0; i < screen->slk_nlabels; i++)
		free(screen->slk_labels[i].text);
	free(screen->slk_labels);
}

/*
 * __slk_ripoffline --
 *	ripoffline callback to accept a WINDOW to create our keys.
 */
static int
__slk_ripoffline(WINDOW *window, int cols)
{

	if (window == NULL)
		return ERR;
	assert(window->screen->slk_window == NULL);
	window->screen->slk_window = window;
	wattron(window,
	    (t_no_color_video(window->screen->term) & 1) == 0
	    ? A_STANDOUT : A_REVERSE);
	__slk_resize(window->screen, cols);
	return OK;
}

/*
 * __slk_resize --
 *	Size and position the labels in the ripped off slk window.
 */
int
__slk_resize(SCREEN *screen, int cols)
{
	int x = 0;
	struct __slk_label *l;

	assert(screen != NULL);
	if (screen->is_term_slk || screen->slk_nlabels == 0)
		return OK;

	screen->slk_label_len = (cols / screen->slk_nlabels) - 1;
	if (screen->slk_label_len > SLK_SIZE)
		screen->slk_label_len = SLK_SIZE;

	l = screen->slk_labels;

	switch(screen->slk_format) {
	case SLK_FMT_3_2_3:
		/* Left 3 */
		(l++)->x = x;
		(l++)->x = (x += screen->slk_label_len + 1);
		(l++)->x = (x += screen->slk_label_len + 1);

		/* Middle 2 */
		x = cols / 2;
		(l++)->x = x -(screen->slk_label_len + 1);
		(l++)->x = x + 1;

		/* Right 3 */
		x = (cols - ((screen->slk_label_len + 1) * 3)) + 1;
		(l++)->x = x;
		(l++)->x = (x += screen->slk_label_len + 1);
		(l++)->x = (x += screen->slk_label_len + 1);
		break;

	case SLK_FMT_4_4:
	{
		int i, half;

		half = screen->slk_nlabels / 2;
		for (i = 0; i < screen->slk_nlabels; i++) {
			(l++)->x = x;
			x += screen->slk_label_len;
			/* Split labels in half */
			if (i == half - 1)
				x = cols - (screen->slk_label_len * half) + 1;
		}
		break;
	}
	}

	/* Write text to the labels. */
	for (x = 0; x < screen->slk_nlabels; x++)
		__slk_set_finalise(screen, x);

	return __slk_redraw(screen);
}

/*
 * __slk_set_finalise --
 *	Does the grunt work of positioning and sizing the text in the label.
 */
static int
__slk_set_finalise(SCREEN *screen, int labnum)
{
	struct __slk_label *l;
	size_t spc, len, x;
	char *p;

	l = &screen->slk_labels[labnum];
	spc = screen->slk_label_len;

#ifdef HAVE_WCHAR
	len = 0;
	if (l->text != NULL) {
		wchar_t wc;

		p = l->text;
		while (*p != '\0') {
			if ((x = mbrtowc(0, p, strlen(p), &screen->sp)) == -1)
				return ERR;
			mbrtowc(&wc, p, x, &screen->sp);
			if (len + wcwidth(wc) > spc)
				break;
			len += wcwidth(wc);
			p += x;
		}
	}
#else
	len = l->text == NULL ? 0 : strlen(l->text);
	if (len > spc)
		len = spc;
#endif

	switch(l->justify) {
	case SLK_JUSTIFY_LEFT:
		x = 0;
		break;
	case SLK_JUSTIFY_CENTER:
		x = (spc - len) / 2;
		if (x + len > spc)
			x--;
		break;
	case SLK_JUSTIFY_RIGHT:
		x = spc - len;
		break;
	default:
		return ERR; /* impossible */
	}

	p = l->label;
	if (x != 0) {
		memset(p, ' ', x);
		p += x;
		spc -= x;
	}
	if (len != 0) {
		memcpy(p, l->text, len);
		p += len;
		spc -= len;
	}
	if (spc != 0) {
		memset(p, ' ', spc);
		p += spc;
	}
	*p = '\0'; /* Terminate for plab_norm. */

	return __slk_draw(screen, labnum);
}

/*
 * __slk_draw --
 *	Draws the specified key.
 */
static int
__slk_draw(SCREEN *screen, int labnum)
{
	const struct __slk_label *l;

	if (screen->slk_hidden)
		return OK;

	l = &screen->slk_labels[labnum];
	if (screen->is_term_slk)
		return ti_putp(screen->term,
		    ti_tiparm(screen->term,
		    t_plab_norm(screen->term), labnum + 1, l->label));
	else if (screen->slk_window != NULL)
		return mvwaddnstr(screen->slk_window, 0, l->x,
		    l->label, screen->slk_label_len);
	else
		return ERR;
}

/*
 * __slk_draw --
 *	Draws all the keys.
 */
static int
__slk_redraw(SCREEN *screen)
{
	int i, result = OK;

	for (i = 0; i < screen->slk_nlabels; i++) {
		if (__slk_draw(screen, i) == ERR)
			result = ERR;
	}
	return result;
}

cvs diff -r1.25 -r1.26 src/lib/libcurses/resize.c (expand / switch to context diff)
--- src/lib/libcurses/resize.c 2017/01/11 20:43:03 1.25
+++ src/lib/libcurses/resize.c 2017/01/24 17:27:30 1.26
@@ -1,4 +1,4 @@
-/*	$NetBSD: resize.c,v 1.25 2017/01/11 20:43:03 roy Exp $	*/
+/*	$NetBSD: resize.c,v 1.26 2017/01/24 17:27:30 roy 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.25 2017/01/11 20:43:03 roy Exp $");
+__RCSID("$NetBSD: resize.c,v 1.26 2017/01/24 17:27:30 roy Exp $");
 #endif
 #endif				/* not lint */
 
@@ -173,9 +173,15 @@
 	 * know the correct draw order. */
 	clearok(curscr, TRUE);
 
-	/* We know how to repaint the ripoffs */
-	__ripoffresize(_cursesi_screen);
+	if (result == OK) {
+		/* We know how to repaint the ripoffs */
+		__ripoffresize(_cursesi_screen);
 
+		/* We do need to reposition our slks. */
+		__slk_resize(_cursesi_screen, ncols);
+		__slk_noutrefresh(_cursesi_screen);
+	}
+
 	return result;
 }
 
@@ -209,6 +215,11 @@
 	_cursesi_screen->COLS = ncols;
 	LINES = rlines;
 	COLS = ncols;
+
+	if (_cursesi_screen->slk_window != NULL &&
+	    __resizewin(_cursesi_screen->slk_window,
+		        _cursesi_screen->slk_window->reqy, ncols) == ERR)
+		return ERR;
 
 	  /* tweak the flags now that we have updated the LINES and COLS */
 	for (list = _cursesi_screen->winlistp; list != NULL; list = list->nextp) {

cvs diff -r1.2 -r1.3 src/lib/libcurses/ripoffline.c (expand / switch to context diff)
--- src/lib/libcurses/ripoffline.c 2017/01/12 16:23:46 1.2
+++ src/lib/libcurses/ripoffline.c 2017/01/24 17:27:30 1.3
@@ -1,4 +1,4 @@
-/*	$NetBSD: ripoffline.c,v 1.2 2017/01/12 16:23:46 roy Exp $	*/
+/*	$NetBSD: ripoffline.c,v 1.3 2017/01/24 17:27:30 roy Exp $	*/
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ripoffline.c,v 1.2 2017/01/12 16:23:46 roy Exp $");
+__RCSID("$NetBSD: ripoffline.c,v 1.3 2017/01/24 17:27:30 roy Exp $");
 #endif				/* not lint */
 
 #include "curses.h"
@@ -103,6 +103,8 @@
 	*rtop = 0;
 	rip = screen->ripped;
 	for (i = 0, srip = ripoffs; i < nrips; i++, srip++) {
+		if (srip->nlines == 0)
+			continue;
 		nlines = srip->nlines < 0 ? -srip->nlines : srip->nlines;
 		w = __newwin(screen, nlines, 0,
 		    srip->nlines < 0 ? LINES - nlines : *rtop,
@@ -150,4 +152,24 @@
 		}
 		wnoutrefresh(rip->win);
 	}
+}
+
+/*
+ * __unripoffline --
+ *	Used by __slk_init to remove the ripoffline reservation it made
+ *	because the terminal natively supports soft label keys.
+ */
+int
+__unripoffline(int (*init)(WINDOW *, int))
+{
+	struct ripoff *rip;
+	int i, unripped = 0;
+
+	for (i = 0, rip = ripoffs; i < nrips; i++, rip++) {
+		if (rip->init == init) {
+			rip->nlines = 0;
+			unripped++;
+		}
+	}
+	return unripped;
 }

cvs diff -r1.29 -r1.30 src/lib/libcurses/screen.c (expand / switch to context diff)
--- src/lib/libcurses/screen.c 2017/01/11 20:43:03 1.29
+++ src/lib/libcurses/screen.c 2017/01/24 17:27:30 1.30
@@ -1,4 +1,4 @@
-/*	$NetBSD: screen.c,v 1.29 2017/01/11 20:43:03 roy Exp $	*/
+/*	$NetBSD: screen.c,v 1.30 2017/01/24 17:27:30 roy 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.29 2017/01/11 20:43:03 roy Exp $");
+__RCSID("$NetBSD: screen.c,v 1.30 2017/01/24 17:27:30 roy Exp $");
 #endif
 #endif					/* not lint */
 
@@ -179,6 +179,10 @@
 	    0, 0, 0, FALSE)) == NULL)
 		goto error_exit;
 
+	/* If Soft Label Keys are setup, they will ripoffline. */
+	if (__slk_init(new_screen) == ERR)
+		goto error_exit;
+
 	if (__ripoffscreen(new_screen, &rtop) == ERR)
 		goto error_exit;
 
@@ -191,7 +195,7 @@
 	__init_getch(new_screen);
 	__init_acs(new_screen);
 #ifdef HAVE_WCHAR
-	__init_get_wch( new_screen );
+	__init_get_wch(new_screen);
 	__init_wacs(new_screen);
 #endif /* HAVE_WCHAR */
 
@@ -239,6 +243,9 @@
 
 	  /* free the storage of the keymaps */
 	_cursesi_free_keymap(screen->base_keymap);
+
+	  /* free the Soft Label Keys */
+	__slk_free(screen);
 
 	free(screen->stdbuf);
 	free(screen->unget_list);