Blame newt.c

Packit Service 8876fe
#include "config.h"
Packit Service 8876fe
Packit Service 8876fe
#include <slang.h>
Packit Service 8876fe
#include <stdio.h>
Packit Service 8876fe
#include <stdlib.h>
Packit Service 8876fe
#include <string.h>
Packit Service 8876fe
#include <sys/signal.h>
Packit Service 8876fe
#include <sys/time.h>
Packit Service 8876fe
#include <sys/types.h>
Packit Service 8876fe
#include <termios.h>
Packit Service 8876fe
#include <unistd.h>
Packit Service 8876fe
#include <wchar.h>
Packit Service 8876fe
Packit Service 8876fe
#ifdef HAVE_ALLOCA_H
Packit Service 8876fe
#include <alloca.h>
Packit Service 8876fe
#endif
Packit Service 8876fe
Packit Service 8876fe
#include "newt.h"
Packit Service 8876fe
#include "newt_pr.h"
Packit Service 8876fe
Packit Service 8876fe
struct Window {
Packit Service 8876fe
    int height, width, top, left;
Packit Service 8876fe
    SLsmg_Char_Type * buffer;
Packit Service 8876fe
    char * title;
Packit Service 8876fe
};
Packit Service 8876fe
Packit Service 8876fe
struct keymap {
Packit Service 8876fe
    char * str;
Packit Service 8876fe
    int code;
Packit Service 8876fe
    char * tc;
Packit Service 8876fe
};
Packit Service 8876fe
Packit Service 8876fe
static struct Window windowStack[20];
Packit Service 8876fe
static struct Window * currentWindow = NULL;
Packit Service 8876fe
Packit Service 8876fe
static char * helplineStack[20];
Packit Service 8876fe
static char ** currentHelpline = NULL;
Packit Service 8876fe
Packit Service 8876fe
static int cursorRow, cursorCol;
Packit Service 8876fe
static int cursorOn = 1;
Packit Service 8876fe
static int trashScreen = 0;
Packit Service 8876fe
extern int needResize;
Packit Service 8876fe
Packit Service 8876fe
static const char * const defaultHelpLine =
Packit Service 8876fe
"  <Tab>/<Alt-Tab> between elements   |  <Space> selects   |  <F12> next screen"
Packit Service 8876fe
;
Packit Service 8876fe
Packit Service 8876fe
const struct newtColors newtDefaultColorPalette = {
Packit Service 8876fe
	"white", "blue", 			/* root fg, bg */
Packit Service 8876fe
	"black", "lightgray",			/* border fg, bg */
Packit Service 8876fe
	"black", "lightgray",			/* window fg, bg */
Packit Service 8876fe
	"white", "black",			/* shadow fg, bg */
Packit Service 8876fe
	"red", "lightgray",			/* title fg, bg */
Packit Service 8876fe
	"lightgray", "red",			/* button fg, bg */
Packit Service 8876fe
	"red", "lightgray",			/* active button fg, bg */
Packit Service 8876fe
	"lightgray", "blue",			/* checkbox fg, bg */
Packit Service 8876fe
	"lightgray", "red",			/* active checkbox fg, bg */
Packit Service 8876fe
	"lightgray", "blue",			/* entry box fg, bg */
Packit Service 8876fe
	"blue", "lightgray",			/* label fg, bg */
Packit Service 8876fe
	"black", "lightgray",			/* listbox fg, bg */
Packit Service 8876fe
	"lightgray", "blue",			/* active listbox fg, bg */
Packit Service 8876fe
	"black", "lightgray",			/* textbox fg, bg */
Packit Service 8876fe
	"lightgray", "red",			/* active textbox fg, bg */
Packit Service 8876fe
	"white", "blue",			/* help line */
Packit Service 8876fe
	"lightgray", "blue",			/* root text */
Packit Service 8876fe
	"blue",					/* scale full */
Packit Service 8876fe
	"red",					/* scale empty */
Packit Service 8876fe
	"blue", "lightgray",			/* disabled entry fg, bg */
Packit Service 8876fe
	"black", "lightgray",			/* compact button fg, bg */
Packit Service 8876fe
	"lightgray", "red",			/* active & sel listbox */
Packit Service 8876fe
	"black", "brown"			/* selected listbox */
Packit Service 8876fe
};
Packit Service 8876fe
Packit Service 8876fe
static const struct keymap keymap[] = {
Packit Service 8876fe
	{ "\033OA", 		NEWT_KEY_UP, 		"ku" },
Packit Service 8876fe
	{ "\020", 		NEWT_KEY_UP, 		NULL }, /* emacs ^P */
Packit Service 8876fe
	{ "\033OB", 		NEWT_KEY_DOWN, 		"kd" },
Packit Service 8876fe
	{ "\016", 		NEWT_KEY_DOWN, 		NULL }, /* emacs ^N */
Packit Service 8876fe
	{ "\033OC", 		NEWT_KEY_RIGHT, 	"kr" },
Packit Service 8876fe
	{ "\006", 		NEWT_KEY_RIGHT, 	NULL }, /* emacs ^F */
Packit Service 8876fe
	{ "\033OD", 		NEWT_KEY_LEFT, 		"kl" },
Packit Service 8876fe
	{ "\002", 		NEWT_KEY_LEFT, 		NULL }, /* emacs ^B */
Packit Service 8876fe
	{ "\033OH",		NEWT_KEY_HOME, 		"kh" },
Packit Service 8876fe
	{ "\033[1~",		NEWT_KEY_HOME, 		NULL },
Packit Service 8876fe
	{ "\001",		NEWT_KEY_HOME, 		NULL }, /* emacs ^A */
Packit Service 8876fe
	{ "\033Ow",		NEWT_KEY_END, 		"kH" },
Packit Service 8876fe
        { "\033[4~",		NEWT_KEY_END, 		"@7" },
Packit Service 8876fe
        { "\005",		NEWT_KEY_END, 		NULL }, /* emacs ^E */
Packit Service 8876fe
Packit Service 8876fe
	{ "\033[3~",		NEWT_KEY_DELETE,	"kD" },
Packit Service 8876fe
	{ "\004",		NEWT_KEY_DELETE,	NULL }, /* emacs ^D */
Packit Service 8876fe
	{ "\033[2~", 		NEWT_KEY_INSERT,        "kI" },
Packit Service 8876fe
Packit Service 8876fe
	{ "\033\t",		NEWT_KEY_UNTAB,		"kB" },
Packit Service 8876fe
	{ "\033[Z",		NEWT_KEY_UNTAB,		NULL },
Packit Service 8876fe
Packit Service 8876fe
	{ "\033[5~",		NEWT_KEY_PGUP,		"kP" },
Packit Service 8876fe
	{ "\033[6~",		NEWT_KEY_PGDN,		"kN" },
Packit Service 8876fe
	{ "\033V",		NEWT_KEY_PGUP, 		NULL },
Packit Service 8876fe
	{ "\033v",		NEWT_KEY_PGUP, 		NULL },
Packit Service 8876fe
        { "\026",		NEWT_KEY_PGDN,		NULL },
Packit Service 8876fe
Packit Service 8876fe
	{ "\033[[A",		NEWT_KEY_F1,		NULL },
Packit Service 8876fe
	{ "\033[[B",		NEWT_KEY_F2,		NULL },
Packit Service 8876fe
	{ "\033[[C",		NEWT_KEY_F3,		NULL },
Packit Service 8876fe
	{ "\033[[D",		NEWT_KEY_F4,		NULL },
Packit Service 8876fe
	{ "\033[[E",		NEWT_KEY_F5,		NULL },
Packit Service 8876fe
Packit Service 8876fe
	{ "\033OP",		NEWT_KEY_F1,		NULL },
Packit Service 8876fe
	{ "\033OQ",		NEWT_KEY_F2,		NULL },
Packit Service 8876fe
	{ "\033OR",		NEWT_KEY_F3,		NULL },
Packit Service 8876fe
	{ "\033OS",		NEWT_KEY_F4,		NULL },
Packit Service 8876fe
Packit Service 8876fe
	{ "\033[11~",		NEWT_KEY_F1,		"k1" },
Packit Service 8876fe
	{ "\033[12~",		NEWT_KEY_F2,		"k2" },
Packit Service 8876fe
	{ "\033[13~",		NEWT_KEY_F3,		"k3" },
Packit Service 8876fe
	{ "\033[14~",		NEWT_KEY_F4,		"k4" },
Packit Service 8876fe
	{ "\033[15~",		NEWT_KEY_F5,		"k5" },
Packit Service 8876fe
	{ "\033[17~",		NEWT_KEY_F6,		"k6" },
Packit Service 8876fe
	{ "\033[18~",		NEWT_KEY_F7,		"k7" },
Packit Service 8876fe
	{ "\033[19~",		NEWT_KEY_F8,		"k8" },
Packit Service 8876fe
	{ "\033[20~",		NEWT_KEY_F9,            "k9" },
Packit Service 8876fe
	{ "\033[21~",		NEWT_KEY_F10,		"k;" },
Packit Service 8876fe
	{ "\033[23~",		NEWT_KEY_F11,		"F1" },
Packit Service 8876fe
	{ "\033[24~",		NEWT_KEY_F12,		"F2" },
Packit Service 8876fe
	{ "\033",		NEWT_KEY_ESCAPE,	"@2" },
Packit Service 8876fe
        { "\033",		NEWT_KEY_ESCAPE,	"@9" },
Packit Service 8876fe
Packit Service 8876fe
        { "\177",		NEWT_KEY_BKSPC,		NULL },
Packit Service 8876fe
        { "\010",		NEWT_KEY_BKSPC,		NULL },
Packit Service 8876fe
        
Packit Service 8876fe
	{ 0 },	/* LEAVE this one */
Packit Service 8876fe
};
Packit Service 8876fe
static void initKeymap();
Packit Service 8876fe
static void freeKeymap();
Packit Service 8876fe
Packit Service 8876fe
static const char ident[] = // ident friendly
Packit Service 8876fe
    "$Version: Newt windowing library v" VERSION " $"
Packit Service 8876fe
    "$Copyright: (C) 1996-2003 Red Hat, Inc. Written by Erik Troan $"
Packit Service 8876fe
    "$License: Lesser GNU Public License. $";
Packit Service 8876fe
Packit Service 8876fe
static newtSuspendCallback suspendCallback = NULL;
Packit Service 8876fe
static void * suspendCallbackData = NULL;
Packit Service 8876fe
Packit Service 8876fe
void newtSetSuspendCallback(newtSuspendCallback cb, void * data) {
Packit Service 8876fe
    suspendCallback = cb;
Packit Service 8876fe
    suspendCallbackData = data;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static void handleSigwinch(int signum) {
Packit Service 8876fe
    needResize = 1;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static int getkeyInterruptHook(void) {
Packit Service 8876fe
    return -1;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
int _newt_wstrlen(const char *str, int len) {
Packit Service 8876fe
	mbstate_t ps;
Packit Service 8876fe
	wchar_t tmp;
Packit Service 8876fe
	int nchars = 0;
Packit Service 8876fe
	
Packit Service 8876fe
	if (!str) return 0;
Packit Service 8876fe
	if (!len) return 0;
Packit Service 8876fe
	if (len < 0) len = strlen(str);
Packit Service 8876fe
	memset(&ps,0,sizeof(mbstate_t));
Packit Service 8876fe
	while (len > 0) {
Packit Service 8876fe
		int x,y;
Packit Service 8876fe
		
Packit Service 8876fe
		x = mbrtowc(&tmp,str,len,&ps);
Packit Service 8876fe
		if (x >0) {
Packit Service 8876fe
		    	str += x;
Packit Service 8876fe
			len -= x;
Packit Service 8876fe
			y = wcwidth(tmp);
Packit Service 8876fe
			if (y>0)
Packit Service 8876fe
			  nchars+=y;
Packit Service 8876fe
		} else break;
Packit Service 8876fe
	}
Packit Service 8876fe
	return nchars;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/** Trim a string to fit 
Packit Service 8876fe
 * @param title - string. NULL will be inserted if necessary
Packit Service 8876fe
 * @param chrs  - available space. (character cells)
Packit Service 8876fe
 */
Packit Service 8876fe
void trim_string(char *title, int chrs)
Packit Service 8876fe
{
Packit Service 8876fe
	char *p = title;
Packit Service 8876fe
	int ln;
Packit Service 8876fe
	int x = 0,y = 0;
Packit Service 8876fe
	wchar_t tmp;
Packit Service 8876fe
	mbstate_t ps;
Packit Service 8876fe
Packit Service 8876fe
	memset(&ps, 0, sizeof(ps));
Packit Service 8876fe
	ln = strlen(title);
Packit Service 8876fe
Packit Service 8876fe
	while (*p) {
Packit Service 8876fe
		x = mbrtowc(&tmp, p, ln, &ps);
Packit Service 8876fe
		if (x < 0) { // error
Packit Service 8876fe
			*p = '\0';
Packit Service 8876fe
			return;
Packit Service 8876fe
		}
Packit Service 8876fe
		y = wcwidth(tmp);
Packit Service 8876fe
		if (y > chrs) {
Packit Service 8876fe
			*p = '\0';
Packit Service 8876fe
			return;
Packit Service 8876fe
		} else {
Packit Service 8876fe
			p += x;
Packit Service 8876fe
			ln -= x;
Packit Service 8876fe
			chrs -= y;
Packit Service 8876fe
		}
Packit Service 8876fe
	}	
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static int getkey() {
Packit Service 8876fe
    int c;
Packit Service 8876fe
Packit Service 8876fe
    while ((c = SLang_getkey()) == '\xC') { /* if Ctrl-L redraw whole screen */
Packit Service 8876fe
        SLsmg_touch_lines(0, SLtt_Screen_Rows);
Packit Service 8876fe
        SLsmg_refresh();
Packit Service 8876fe
    }
Packit Service 8876fe
    return c;
Packit Service 8876fe
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static void updateColorset(char *fg, char *bg, char **fg_p, char **bg_p)
Packit Service 8876fe
{
Packit Service 8876fe
    if (*fg && fg_p)
Packit Service 8876fe
	*fg_p = fg;
Packit Service 8876fe
    if (*bg && bg_p)
Packit Service 8876fe
	*bg_p = bg;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/* parse color specifications (e.g. root=,black:border=red,blue)
Packit Service 8876fe
 * and update the palette
Packit Service 8876fe
 */
Packit Service 8876fe
static void parseColors(char *s, struct newtColors *palette)
Packit Service 8876fe
{
Packit Service 8876fe
    char *name, *str, *fg, *bg;
Packit Service 8876fe
Packit Service 8876fe
    for (str = s; (s = strtok(str, ";:\n\r\t ")); str = NULL) {
Packit Service 8876fe
	name = s;
Packit Service 8876fe
	if (!(s = strchr(s, '=')) || !*s)
Packit Service 8876fe
	    continue;
Packit Service 8876fe
	*s = '\0';
Packit Service 8876fe
	fg = ++s;
Packit Service 8876fe
	if (!(s = strchr(s, ',')) || !*s)
Packit Service 8876fe
	    continue;
Packit Service 8876fe
	*s = '\0';
Packit Service 8876fe
	bg = ++s;
Packit Service 8876fe
Packit Service 8876fe
	if (!strcmp(name, "root"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->rootFg, &palette->rootBg);
Packit Service 8876fe
	else if (!strcmp(name, "border"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->borderFg, &palette->borderBg);
Packit Service 8876fe
	else if (!strcmp(name, "window"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->windowFg, &palette->windowBg);
Packit Service 8876fe
	else if (!strcmp(name, "shadow"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->shadowFg, &palette->shadowBg);
Packit Service 8876fe
	else if (!strcmp(name, "title"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->titleFg, &palette->titleBg);
Packit Service 8876fe
	else if (!strcmp(name, "button"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->buttonFg, &palette->buttonBg);
Packit Service 8876fe
	else if (!strcmp(name, "actbutton"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->actButtonFg, &palette->actButtonBg);
Packit Service 8876fe
	else if (!strcmp(name, "checkbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->checkboxFg, &palette->checkboxBg);
Packit Service 8876fe
	else if (!strcmp(name, "actcheckbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->actCheckboxFg, &palette->actCheckboxBg);
Packit Service 8876fe
	else if (!strcmp(name, "entry"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->entryFg, &palette->entryBg);
Packit Service 8876fe
	else if (!strcmp(name, "label"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->labelFg, &palette->labelBg);
Packit Service 8876fe
	else if (!strcmp(name, "listbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->listboxFg, &palette->listboxBg);
Packit Service 8876fe
	else if (!strcmp(name, "actlistbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->actListboxFg, &palette->actListboxBg);
Packit Service 8876fe
	else if (!strcmp(name, "textbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->textboxFg, &palette->textboxBg);
Packit Service 8876fe
	else if (!strcmp(name, "acttextbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->actTextboxFg, &palette->actTextboxBg);
Packit Service 8876fe
	else if (!strcmp(name, "helpline"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->helpLineFg, &palette->helpLineBg);
Packit Service 8876fe
	else if (!strcmp(name, "roottext"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->rootTextFg, &palette->rootTextBg);
Packit Service 8876fe
	else if (!strcmp(name, "emptyscale"))
Packit Service 8876fe
	    updateColorset(fg, bg, NULL, &palette->emptyScale);
Packit Service 8876fe
	else if (!strcmp(name, "fullscale"))
Packit Service 8876fe
	    updateColorset(fg, bg, NULL, &palette->fullScale);
Packit Service 8876fe
	else if (!strcmp(name, "disentry"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->disabledEntryFg, &palette->disabledEntryBg);
Packit Service 8876fe
	else if (!strcmp(name, "compactbutton"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->compactButtonFg, &palette->compactButtonBg);
Packit Service 8876fe
	else if (!strcmp(name, "actsellistbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->actSelListboxFg, &palette->actSelListboxBg);
Packit Service 8876fe
	else if (!strcmp(name, "sellistbox"))
Packit Service 8876fe
	    updateColorset(fg, bg, &palette->selListboxFg, &palette->selListboxBg);
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static void initColors(void)
Packit Service 8876fe
{
Packit Service 8876fe
    char *colors, *colors_file, buf[16384];
Packit Service 8876fe
    FILE *f;
Packit Service 8876fe
    struct newtColors palette;
Packit Service 8876fe
Packit Service 8876fe
    palette = newtDefaultColorPalette;
Packit Service 8876fe
Packit Service 8876fe
    colors_file = getenv("NEWT_COLORS_FILE");
Packit Service 8876fe
#ifdef NEWT_COLORS_FILE
Packit Service 8876fe
    if (colors_file == NULL)
Packit Service 8876fe
	colors_file = NEWT_COLORS_FILE;
Packit Service 8876fe
#endif
Packit Service 8876fe
Packit Service 8876fe
    if ((colors = getenv("NEWT_COLORS"))) {
Packit Service 8876fe
	strncpy(buf, colors, sizeof (buf));
Packit Service 8876fe
	buf[sizeof (buf) - 1] = '\0';
Packit Service 8876fe
	parseColors(buf, &palette);
Packit Service 8876fe
    } else if (colors_file && *colors_file && (f = fopen(colors_file, "r"))) {
Packit Service 8876fe
	size_t r;
Packit Service 8876fe
	if ((r = fread(buf, 1, sizeof (buf) - 1, f)) > 0) {
Packit Service 8876fe
	    buf[r] = '\0';
Packit Service 8876fe
	    parseColors(buf, &palette);
Packit Service 8876fe
	}
Packit Service 8876fe
	fclose(f);
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    newtSetColors(palette);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtFlushInput(void) {
Packit Service 8876fe
    while (SLang_input_pending(0)) {
Packit Service 8876fe
	getkey();
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Refresh the screen
Packit Service 8876fe
 */
Packit Service 8876fe
void newtRefresh(void) {
Packit Service 8876fe
    SLsmg_refresh();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtSuspend(void) {
Packit Service 8876fe
    SLtt_set_cursor_visibility (1);
Packit Service 8876fe
    SLsmg_suspend_smg();
Packit Service 8876fe
    SLang_reset_tty();
Packit Service 8876fe
    SLtt_set_cursor_visibility (cursorOn);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 *  @brief Return after suspension.
Packit Service 8876fe
 *  @return 0 on success.
Packit Service 8876fe
 */
Packit Service 8876fe
int newtResume(void) {
Packit Service 8876fe
    SLsmg_resume_smg ();
Packit Service 8876fe
    SLsmg_refresh();
Packit Service 8876fe
    return SLang_init_tty(0, 0, 0);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtCls(void) {
Packit Service 8876fe
    SLsmg_set_color(NEWT_COLORSET_ROOT);
Packit Service 8876fe
    SLsmg_gotorc(0, 0);
Packit Service 8876fe
    SLsmg_erase_eos();
Packit Service 8876fe
Packit Service 8876fe
    newtRefresh();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Resize the screen
Packit Service 8876fe
 * @param redraw - boolean - should we redraw the screen?
Packit Service 8876fe
 */
Packit Service 8876fe
void newtResizeScreen(int redraw) {
Packit Service 8876fe
    /* we can't redraw from scratch, just redisplay SLang screen */
Packit Service 8876fe
    SLtt_get_screen_size();
Packit Service 8876fe
    /* SLsmg_reinit_smg(); */
Packit Service 8876fe
    if (redraw) {
Packit Service 8876fe
        SLsmg_touch_lines(0, SLtt_Screen_Rows);
Packit Service 8876fe
        newtRefresh();
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Initialize the newt library
Packit Service 8876fe
 * @return int - 0 for success, else < 0
Packit Service 8876fe
 */
Packit Service 8876fe
int newtInit(void) {
Packit Service 8876fe
    char * MonoValue, * MonoEnv = "NEWT_MONO";
Packit Service 8876fe
    const char *lang;
Packit Service 8876fe
    int ret;
Packit Service 8876fe
Packit Service 8876fe
    if ((lang = getenv("LC_ALL")) == NULL)
Packit Service 8876fe
        if ((lang = getenv("LC_CTYPE")) == NULL)
Packit Service 8876fe
            if ((lang = getenv("LANG")) == NULL)
Packit Service 8876fe
                lang = "";
Packit Service 8876fe
    /* slang doesn't support multibyte encodings except UTF-8,
Packit Service 8876fe
       avoid character corruption by redrawing the screen */
Packit Service 8876fe
    if (strstr (lang, ".euc") != NULL)
Packit Service 8876fe
	trashScreen = 1;
Packit Service 8876fe
Packit Service 8876fe
    (void) strlen(ident);
Packit Service 8876fe
Packit Service 8876fe
    SLutf8_enable(-1);
Packit Service 8876fe
    SLtt_get_terminfo();
Packit Service 8876fe
    SLtt_get_screen_size();
Packit Service 8876fe
Packit Service 8876fe
    MonoValue = getenv(MonoEnv);
Packit Service 8876fe
    if ( MonoValue != NULL )
Packit Service 8876fe
	SLtt_Use_Ansi_Colors = 0;
Packit Service 8876fe
Packit Service 8876fe
    if ((ret = SLsmg_init_smg()) < 0)
Packit Service 8876fe
	return ret;
Packit Service 8876fe
    if ((ret = SLang_init_tty(0, 0, 0)) < 0)
Packit Service 8876fe
	return ret;
Packit Service 8876fe
Packit Service 8876fe
    initColors();
Packit Service 8876fe
    newtCursorOff();
Packit Service 8876fe
    initKeymap();
Packit Service 8876fe
Packit Service 8876fe
    SLsignal_intr(SIGWINCH, handleSigwinch);
Packit Service 8876fe
    SLang_getkey_intr_hook = getkeyInterruptHook;
Packit Service 8876fe
Packit Service 8876fe
    return 0;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Closedown the newt library, tidying screen.
Packit Service 8876fe
 * @returns int , 0. (no errors reported)
Packit Service 8876fe
 */
Packit Service 8876fe
int newtFinished(void) {
Packit Service 8876fe
    if (currentWindow) {
Packit Service 8876fe
	for (; currentWindow >= windowStack; currentWindow--) {
Packit Service 8876fe
	    free(currentWindow->buffer);
Packit Service 8876fe
	    free(currentWindow->title);
Packit Service 8876fe
	}
Packit Service 8876fe
	currentWindow = NULL;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    if (currentHelpline) {
Packit Service 8876fe
	for (; currentHelpline >= helplineStack; currentHelpline--)
Packit Service 8876fe
	    free(*currentHelpline);
Packit Service 8876fe
	currentHelpline = NULL;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    freeKeymap();
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
Packit Service 8876fe
    newtCursorOn();
Packit Service 8876fe
    SLsmg_refresh();
Packit Service 8876fe
    SLsmg_reset_smg();
Packit Service 8876fe
    SLang_reset_tty();
Packit Service 8876fe
Packit Service 8876fe
    return 0;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Set the colors used.
Packit Service 8876fe
 * @param colors - newtColor struct used.
Packit Service 8876fe
 */
Packit Service 8876fe
void newtSetColors(struct newtColors colors) {
Packit Service 8876fe
    if (!SLtt_Use_Ansi_Colors) {
Packit Service 8876fe
        int i;
Packit Service 8876fe
Packit Service 8876fe
        for (i = 2; i < 25; i++)
Packit Service 8876fe
            SLtt_set_mono(i, NULL, 0);
Packit Service 8876fe
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_SELLISTBOX, NULL, SLTT_BOLD_MASK);
Packit Service 8876fe
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_ACTBUTTON, NULL, SLTT_REV_MASK);
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_ACTCHECKBOX, NULL, SLTT_REV_MASK);
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_ACTLISTBOX, NULL, SLTT_REV_MASK);
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_ACTTEXTBOX, NULL, SLTT_REV_MASK);
Packit Service 8876fe
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_ACTSELLISTBOX, NULL, SLTT_REV_MASK | SLTT_BOLD_MASK);
Packit Service 8876fe
        
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_DISENTRY, NULL, 0); // FIXME
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_FULLSCALE, NULL, SLTT_ULINE_MASK | SLTT_REV_MASK);
Packit Service 8876fe
        SLtt_set_mono(NEWT_COLORSET_EMPTYSCALE, NULL, SLTT_ULINE_MASK);
Packit Service 8876fe
        return;
Packit Service 8876fe
    }
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ROOT, "", colors.rootFg, colors.rootBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_BORDER, "", colors.borderFg, colors.borderBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_WINDOW, "", colors.windowFg, colors.windowBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_SHADOW, "", colors.shadowFg, colors.shadowBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_TITLE, "", colors.titleFg, colors.titleBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_BUTTON, "", colors.buttonFg, colors.buttonBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ACTBUTTON, "", colors.actButtonFg,
Packit Service 8876fe
			colors.actButtonBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_CHECKBOX, "", colors.checkboxFg,
Packit Service 8876fe
			colors.checkboxBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ACTCHECKBOX, "", colors.actCheckboxFg,
Packit Service 8876fe
			colors.actCheckboxBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ENTRY, "", colors.entryFg, colors.entryBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_LABEL, "", colors.labelFg, colors.labelBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_LISTBOX, "", colors.listboxFg,
Packit Service 8876fe
			colors.listboxBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ACTLISTBOX, "", colors.actListboxFg,
Packit Service 8876fe
			colors.actListboxBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_TEXTBOX, "", colors.textboxFg,
Packit Service 8876fe
			colors.textboxBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ACTTEXTBOX, "", colors.actTextboxFg,
Packit Service 8876fe
			colors.actTextboxBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_HELPLINE, "", colors.helpLineFg,
Packit Service 8876fe
			colors.helpLineBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ROOTTEXT, "", colors.rootTextFg,
Packit Service 8876fe
			colors.rootTextBg);
Packit Service 8876fe
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_EMPTYSCALE, "", "white",
Packit Service 8876fe
			colors.emptyScale);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_FULLSCALE, "", "white",
Packit Service 8876fe
			colors.fullScale);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_DISENTRY, "", colors.disabledEntryFg,
Packit Service 8876fe
			colors.disabledEntryBg);
Packit Service 8876fe
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_COMPACTBUTTON, "", colors.compactButtonFg,
Packit Service 8876fe
			colors.compactButtonBg);
Packit Service 8876fe
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_ACTSELLISTBOX, "", colors.actSelListboxFg,
Packit Service 8876fe
		   colors.actSelListboxBg);
Packit Service 8876fe
    SLtt_set_color(NEWT_COLORSET_SELLISTBOX, "", colors.selListboxFg,
Packit Service 8876fe
		   colors.selListboxBg);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtSetColor(int colorset, char *fg, char *bg) {
Packit Service 8876fe
    if (colorset < NEWT_COLORSET_ROOT ||
Packit Service 8876fe
        (colorset > NEWT_COLORSET_SELLISTBOX && colorset < NEWT_COLORSET_CUSTOM(0)) ||
Packit Service 8876fe
	    !SLtt_Use_Ansi_Colors)
Packit Service 8876fe
	return;
Packit Service 8876fe
Packit Service 8876fe
    SLtt_set_color(colorset, "", fg, bg);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/* Keymap handling - rewritten by Henning Makholm <henning@makholm.net>,
Packit Service 8876fe
 * November 2003.
Packit Service 8876fe
 */
Packit Service 8876fe
Packit Service 8876fe
struct kmap_trie_entry {
Packit Service 8876fe
    char alloced; /* alloced/not first element in array */
Packit Service 8876fe
    char c ;   /* character got from terminal */
Packit Service 8876fe
    int code;  /* newt key, or 0 if c does not make a complete sequence */
Packit Service 8876fe
    struct kmap_trie_entry *contseq; /* sub-trie for character following c */
Packit Service 8876fe
    struct kmap_trie_entry *next;    /* try this if char received != c */
Packit Service 8876fe
};
Packit Service 8876fe
Packit Service 8876fe
static struct kmap_trie_entry *kmap_trie_root = NULL;
Packit Service 8876fe
static int keyreader_buf_len = 10 ;
Packit Service 8876fe
static unsigned char default_keyreader_buf[10];
Packit Service 8876fe
static unsigned char *keyreader_buf = default_keyreader_buf;
Packit Service 8876fe
Packit Service 8876fe
#if 0 /* for testing of the keymap manipulation code */
Packit Service 8876fe
static void dumpkeys_recursive(struct kmap_trie_entry *curr, int i, FILE *f) {
Packit Service 8876fe
    int j, ps ;
Packit Service 8876fe
    char seen[256]={0};
Packit Service 8876fe
    if( curr && i >= keyreader_buf_len ) {
Packit Service 8876fe
        fprintf(f,"ARGH! Too long sequence!\n") ;
Packit Service 8876fe
        return ;
Packit Service 8876fe
    }
Packit Service 8876fe
    for(;curr;curr=curr->next) {
Packit Service 8876fe
        keyreader_buf[i] = curr->c ;
Packit Service 8876fe
        ps = seen[(unsigned char)curr->c]++ ;
Packit Service 8876fe
        if( ps || curr->code || (!curr->code && !curr->contseq) ) {
Packit Service 8876fe
            for(j=0;j<=i;j++) {
Packit Service 8876fe
                if( keyreader_buf[j] > 32 && keyreader_buf[j]<127 &&
Packit Service 8876fe
                    keyreader_buf[j] != '^' && keyreader_buf[j] != '\\' )
Packit Service 8876fe
                    fprintf(f,"%c",keyreader_buf[j]);
Packit Service 8876fe
                else if( keyreader_buf[j] > 0 && keyreader_buf[j]<=32 )
Packit Service 8876fe
                    fprintf(f,"^%c",keyreader_buf[j] + 0x40);
Packit Service 8876fe
                else
Packit Service 8876fe
                    fprintf(f,"\\%03o",
Packit Service 8876fe
                            (unsigned)(unsigned char)keyreader_buf[j]);
Packit Service 8876fe
            }
Packit Service 8876fe
            if( curr->code )
Packit Service 8876fe
                fprintf(f,": 0x%X\n",curr->code);
Packit Service 8876fe
            else
Packit Service 8876fe
                fprintf(f,": (just keymap)\n");
Packit Service 8876fe
        }
Packit Service 8876fe
        dumpkeys_recursive(curr->contseq,i+1,f);
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
static void dump_keymap(void) {
Packit Service 8876fe
    FILE *f = fopen("newt.keydump","wt");
Packit Service 8876fe
    if (f) {
Packit Service 8876fe
        dumpkeys_recursive(kmap_trie_root, 0, f);
Packit Service 8876fe
        fclose(f);
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
#endif
Packit Service 8876fe
Packit Service 8876fe
/* newtBindKey may overwrite a binding that is there already */
Packit Service 8876fe
static void newtBindKey(char *keyseq, int meaning) {
Packit Service 8876fe
    struct kmap_trie_entry *root = kmap_trie_root ;
Packit Service 8876fe
    struct kmap_trie_entry **curptr = &root ;
Packit Service 8876fe
Packit Service 8876fe
    /* Try to make sure the common matching buffer is long enough. */
Packit Service 8876fe
    if( strlen(keyseq) > keyreader_buf_len ) {
Packit Service 8876fe
        int i = strlen(keyseq)+10;
Packit Service 8876fe
        unsigned char *newbuf = malloc(i);
Packit Service 8876fe
        if (newbuf) {
Packit Service 8876fe
            if (keyreader_buf != default_keyreader_buf)
Packit Service 8876fe
                free(keyreader_buf);
Packit Service 8876fe
            keyreader_buf = newbuf;
Packit Service 8876fe
            keyreader_buf_len = i;
Packit Service 8876fe
        }
Packit Service 8876fe
    }
Packit Service 8876fe
    
Packit Service 8876fe
    if (*keyseq == 0) return; /* binding the empty sequence is meaningless */
Packit Service 8876fe
    
Packit Service 8876fe
    while(1) {
Packit Service 8876fe
        while ((*curptr) && (*curptr)->c != *keyseq)
Packit Service 8876fe
            curptr = &(*curptr)->next;
Packit Service 8876fe
        if ((*curptr)==0) {
Packit Service 8876fe
            struct kmap_trie_entry* fresh
Packit Service 8876fe
                =  calloc(strlen(keyseq),sizeof(struct kmap_trie_entry));
Packit Service 8876fe
            if (fresh == 0) return; /* despair! */
Packit Service 8876fe
	    fresh->alloced = 1;
Packit Service 8876fe
            *curptr = fresh;
Packit Service 8876fe
            while (keyseq[1]) {
Packit Service 8876fe
                fresh->contseq = fresh+1;
Packit Service 8876fe
                (fresh++)->c = *(keyseq++);
Packit Service 8876fe
            }
Packit Service 8876fe
            fresh->c = *keyseq;
Packit Service 8876fe
            fresh->code = meaning;
Packit Service 8876fe
            return;
Packit Service 8876fe
        }
Packit Service 8876fe
        if (keyseq[1]==0) {
Packit Service 8876fe
            (*curptr)->code = meaning;
Packit Service 8876fe
            return;
Packit Service 8876fe
        } else {
Packit Service 8876fe
            curptr = &(*curptr)->contseq;
Packit Service 8876fe
            keyseq++;
Packit Service 8876fe
        }
Packit Service 8876fe
    }      
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/* This function recursively inserts all entries in the "to" trie into
Packit Service 8876fe
   corresponding positions in the "from" trie, except positions that
Packit Service 8876fe
   are already defined in the "from" trie. */
Packit Service 8876fe
static void kmap_trie_fallback(struct kmap_trie_entry *to,
Packit Service 8876fe
                               struct kmap_trie_entry **from) {
Packit Service 8876fe
    if (*from == NULL)
Packit Service 8876fe
        *from = to ;
Packit Service 8876fe
    if (*from == to)
Packit Service 8876fe
        return ;
Packit Service 8876fe
    for (;to!=NULL;to=to->next) {
Packit Service 8876fe
        struct kmap_trie_entry **fromcopy = from ;
Packit Service 8876fe
        while ((*fromcopy) && (*fromcopy)->c != to->c)
Packit Service 8876fe
            fromcopy = &(*fromcopy)->next ;
Packit Service 8876fe
        if (*fromcopy) {
Packit Service 8876fe
            if ((*fromcopy)->code == 0)
Packit Service 8876fe
                (*fromcopy)->code = to->code;
Packit Service 8876fe
            kmap_trie_fallback(to->contseq, &(*fromcopy)->contseq);
Packit Service 8876fe
        } else {
Packit Service 8876fe
            *fromcopy = malloc(sizeof(struct kmap_trie_entry));
Packit Service 8876fe
            if (*fromcopy) {
Packit Service 8876fe
                **fromcopy = *to ;
Packit Service 8876fe
		(*fromcopy)->alloced = 1;
Packit Service 8876fe
                (*fromcopy)->next = 0 ;
Packit Service 8876fe
            }
Packit Service 8876fe
        }
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
int newtGetKey(void) {
Packit Service 8876fe
    int key, lastcode, errors = 0;
Packit Service 8876fe
    unsigned char *chptr = keyreader_buf, *lastmatch;
Packit Service 8876fe
    struct kmap_trie_entry *curr = kmap_trie_root;
Packit Service 8876fe
Packit Service 8876fe
    do {
Packit Service 8876fe
	key = getkey();
Packit Service 8876fe
	if (key == SLANG_GETKEY_ERROR) {
Packit Service 8876fe
	    if (needResize) {
Packit Service 8876fe
                needResize = 0;
Packit Service 8876fe
		return NEWT_KEY_RESIZE;
Packit Service 8876fe
            }
Packit Service 8876fe
Packit Service 8876fe
	    /* Ignore other signals, but assume that stdin disappeared (the
Packit Service 8876fe
	     * parent terminal was proably closed) if the error persists.
Packit Service 8876fe
	     */
Packit Service 8876fe
	    if (errors++ > 10)
Packit Service 8876fe
		return NEWT_KEY_ERROR;
Packit Service 8876fe
Packit Service 8876fe
	    continue;
Packit Service 8876fe
	}
Packit Service 8876fe
Packit Service 8876fe
	if (key == NEWT_KEY_SUSPEND && suspendCallback)
Packit Service 8876fe
	    suspendCallback(suspendCallbackData);
Packit Service 8876fe
    } while (key == NEWT_KEY_SUSPEND || key == SLANG_GETKEY_ERROR);
Packit Service 8876fe
Packit Service 8876fe
    /* Read more characters, matching against the trie as we go */
Packit Service 8876fe
    lastcode = *chptr = key;
Packit Service 8876fe
    lastmatch = chptr ;
Packit Service 8876fe
    while(1) {
Packit Service 8876fe
         while (curr->c != key) {
Packit Service 8876fe
             curr = curr->next ;
Packit Service 8876fe
             if (curr==NULL) goto break2levels;
Packit Service 8876fe
         }
Packit Service 8876fe
         if (curr->code) {
Packit Service 8876fe
             lastcode = curr->code;
Packit Service 8876fe
             lastmatch = chptr;
Packit Service 8876fe
         }
Packit Service 8876fe
         curr = curr->contseq;
Packit Service 8876fe
         if (curr==NULL) break;
Packit Service 8876fe
Packit Service 8876fe
         if (SLang_input_pending(5) <= 0)
Packit Service 8876fe
             break;
Packit Service 8876fe
Packit Service 8876fe
         if (chptr==keyreader_buf+keyreader_buf_len-1) break;
Packit Service 8876fe
         *++chptr = key = getkey();
Packit Service 8876fe
    }
Packit Service 8876fe
   break2levels:
Packit Service 8876fe
Packit Service 8876fe
      /* The last time the trie matched was at position lastmatch. Back
Packit Service 8876fe
       * up if we have read too many characters. */
Packit Service 8876fe
      while (chptr > lastmatch)
Packit Service 8876fe
          SLang_ungetkey(*chptr--);
Packit Service 8876fe
    
Packit Service 8876fe
      return lastcode;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Wait for a keystroke
Packit Service 8876fe
 */
Packit Service 8876fe
void newtWaitForKey(void) {
Packit Service 8876fe
    newtRefresh();
Packit Service 8876fe
Packit Service 8876fe
    getkey();
Packit Service 8876fe
    newtClearKeyBuffer();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Clear the keybuffer
Packit Service 8876fe
 */
Packit Service 8876fe
void newtClearKeyBuffer(void) {
Packit Service 8876fe
    while (SLang_input_pending(1)) {
Packit Service 8876fe
	getkey();
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * Open a new window.
Packit Service 8876fe
 * @param left. int Size; _not_ including border
Packit Service 8876fe
 * @param top: int size, _not_ including border
Packit Service 8876fe
 * @param width unsigned int
Packit Service 8876fe
 * @param height unsigned int
Packit Service 8876fe
 * @param title - title string
Packit Service 8876fe
 * @return zero on success
Packit Service 8876fe
 */
Packit Service 8876fe
int newtOpenWindow(int left, int top, 
Packit Service 8876fe
                   unsigned int width, unsigned int height,
Packit Service 8876fe
			  const char * title) {
Packit Service 8876fe
    int j, row, col;
Packit Service 8876fe
    int n;
Packit Service 8876fe
    int i;
Packit Service 8876fe
Packit Service 8876fe
    newtFlushInput();
Packit Service 8876fe
Packit Service 8876fe
    if (currentWindow && currentWindow - windowStack + 1
Packit Service 8876fe
	    >= sizeof (windowStack) / sizeof (struct Window))
Packit Service 8876fe
	return 1;
Packit Service 8876fe
Packit Service 8876fe
    if (!currentWindow) {
Packit Service 8876fe
	currentWindow = windowStack;
Packit Service 8876fe
    } else {
Packit Service 8876fe
	currentWindow++;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    currentWindow->left = left;
Packit Service 8876fe
    currentWindow->top = top;
Packit Service 8876fe
    currentWindow->width = width;
Packit Service 8876fe
    currentWindow->height = height;
Packit Service 8876fe
    currentWindow->title = title ? strdup(title) : NULL;
Packit Service 8876fe
Packit Service 8876fe
    currentWindow->buffer = malloc(sizeof(SLsmg_Char_Type) * (width + 5) * (height + 3));
Packit Service 8876fe
Packit Service 8876fe
    row = top - 1;
Packit Service 8876fe
    col = left - 2;
Packit Service 8876fe
    /* clip to the current screen bounds - msw */
Packit Service 8876fe
    if (row < 0)
Packit Service 8876fe
	row = 0;
Packit Service 8876fe
    if (col < 0)
Packit Service 8876fe
	col = 0;
Packit Service 8876fe
    if (left + width > SLtt_Screen_Cols)
Packit Service 8876fe
	width = SLtt_Screen_Cols - left;
Packit Service 8876fe
    if (top + height > SLtt_Screen_Rows)
Packit Service 8876fe
	height = SLtt_Screen_Rows - top;
Packit Service 8876fe
    n = 0;
Packit Service 8876fe
    for (j = 0; j < height + 3; j++, row++) {
Packit Service 8876fe
	SLsmg_gotorc(row, col);
Packit Service 8876fe
	SLsmg_read_raw(currentWindow->buffer + n,
Packit Service 8876fe
		       currentWindow->width + 5);
Packit Service 8876fe
	n += currentWindow->width + 5;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    newtTrashScreen();
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_set_color(NEWT_COLORSET_BORDER);
Packit Service 8876fe
    SLsmg_set_char_set(1);
Packit Service 8876fe
    SLsmg_draw_box(top - 1, left - 1, height + 2, width + 2);
Packit Service 8876fe
    SLsmg_set_char_set(0);
Packit Service 8876fe
Packit Service 8876fe
    if (currentWindow->title) {
Packit Service 8876fe
	trim_string (currentWindow->title, width-4);
Packit Service 8876fe
	i = wstrlen(currentWindow->title,-1) + 4;
Packit Service 8876fe
	i = ((width - i) / 2) + left;
Packit Service 8876fe
	SLsmg_gotorc(top - 1, i);
Packit Service 8876fe
	SLsmg_set_char_set(1);
Packit Service 8876fe
	SLsmg_write_char(SLSMG_RTEE_CHAR);
Packit Service 8876fe
	SLsmg_set_char_set(0);
Packit Service 8876fe
	SLsmg_write_char(' ');
Packit Service 8876fe
	SLsmg_set_color(NEWT_COLORSET_TITLE);
Packit Service 8876fe
	SLsmg_write_string((char *)currentWindow->title);
Packit Service 8876fe
	SLsmg_set_color(NEWT_COLORSET_BORDER);
Packit Service 8876fe
	SLsmg_write_char(' ');
Packit Service 8876fe
	SLsmg_set_char_set(1);
Packit Service 8876fe
	SLsmg_write_char(SLSMG_LTEE_CHAR);
Packit Service 8876fe
	SLsmg_set_char_set(0);
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_set_color(NEWT_COLORSET_WINDOW);
Packit Service 8876fe
    SLsmg_fill_region(top, left, height, width, ' ');
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_set_color(NEWT_COLORSET_SHADOW);
Packit Service 8876fe
    SLsmg_fill_region(top + height + 1, left, 1, width + 2, ' ');
Packit Service 8876fe
    SLsmg_fill_region(top, left + width + 1, height + 1, 1, ' ');
Packit Service 8876fe
Packit Service 8876fe
    for (i = top; i < (top + height + 1); i++) {
Packit Service 8876fe
	SLsmg_gotorc(i, left + width + 1);
Packit Service 8876fe
	SLsmg_write_string(" ");
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    return 0;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Draw a centered window.
Packit Service 8876fe
 * @param width - width in char cells
Packit Service 8876fe
 * @param height - no. of char cells.
Packit Service 8876fe
 * @param title - fixed title
Packit Service 8876fe
 * @returns zero on success
Packit Service 8876fe
 */
Packit Service 8876fe
int newtCenteredWindow(unsigned int width,unsigned int height, 
Packit Service 8876fe
                       const char * title) {
Packit Service 8876fe
    int top, left;
Packit Service 8876fe
Packit Service 8876fe
    top = (int)(SLtt_Screen_Rows - height) / 2;
Packit Service 8876fe
Packit Service 8876fe
    /* I don't know why, but this seems to look better */
Packit Service 8876fe
    if ((SLtt_Screen_Rows % 2) && (top % 2)) top--;
Packit Service 8876fe
Packit Service 8876fe
    left = (int)(SLtt_Screen_Cols - width) / 2;
Packit Service 8876fe
Packit Service 8876fe
    return newtOpenWindow(left, top, width, height, title);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Remove the top window
Packit Service 8876fe
 */
Packit Service 8876fe
void newtPopWindow(void) {
Packit Service 8876fe
    newtPopWindowNoRefresh();
Packit Service 8876fe
    newtRefresh();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtPopWindowNoRefresh(void) {
Packit Service 8876fe
    int j, row, col;
Packit Service 8876fe
    int n = 0;
Packit Service 8876fe
Packit Service 8876fe
    if (currentWindow == NULL)
Packit Service 8876fe
	return;
Packit Service 8876fe
Packit Service 8876fe
    row = col = 0;
Packit Service 8876fe
Packit Service 8876fe
    row = currentWindow->top - 1;
Packit Service 8876fe
    col = currentWindow->left - 2;
Packit Service 8876fe
    if (row < 0)
Packit Service 8876fe
	row = 0;
Packit Service 8876fe
    if (col < 0)
Packit Service 8876fe
	col = 0;
Packit Service 8876fe
    for (j = 0; j < currentWindow->height + 3; j++, row++) {
Packit Service 8876fe
	SLsmg_gotorc(row, col);
Packit Service 8876fe
	SLsmg_write_raw(currentWindow->buffer + n,
Packit Service 8876fe
			currentWindow->width + 5);
Packit Service 8876fe
	n += currentWindow->width + 5;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    free(currentWindow->buffer);
Packit Service 8876fe
    free(currentWindow->title);
Packit Service 8876fe
Packit Service 8876fe
    if (currentWindow == windowStack)
Packit Service 8876fe
	currentWindow = NULL;
Packit Service 8876fe
    else
Packit Service 8876fe
	currentWindow--;
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_set_char_set(0);
Packit Service 8876fe
Packit Service 8876fe
    newtTrashScreen();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtGetWindowPos(int * x, int * y) {
Packit Service 8876fe
    if (currentWindow) {
Packit Service 8876fe
	*x = currentWindow->left;
Packit Service 8876fe
	*y = currentWindow->top;
Packit Service 8876fe
    } else
Packit Service 8876fe
	*x = *y = 0;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtGetrc(int * row, int * col) {
Packit Service 8876fe
    *row = cursorRow;
Packit Service 8876fe
    *col = cursorCol;
Packit Service 8876fe
Packit Service 8876fe
    if (currentWindow) {
Packit Service 8876fe
	*row -= currentWindow->top;
Packit Service 8876fe
	*col -= currentWindow->left;
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtGotorc(int newRow, int newCol) {
Packit Service 8876fe
    if (currentWindow) {
Packit Service 8876fe
	newRow += currentWindow->top;
Packit Service 8876fe
	newCol += currentWindow->left;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    cursorRow = newRow;
Packit Service 8876fe
    cursorCol = newCol;
Packit Service 8876fe
    SLsmg_gotorc(cursorRow, cursorCol);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtDrawBox(int left, int top, int width, int height, int shadow) {
Packit Service 8876fe
    if (currentWindow) {
Packit Service 8876fe
	top += currentWindow->top;
Packit Service 8876fe
	left += currentWindow->left;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_draw_box(top, left, height, width);
Packit Service 8876fe
Packit Service 8876fe
    if (shadow) {
Packit Service 8876fe
	SLsmg_set_color(NEWT_COLORSET_SHADOW);
Packit Service 8876fe
	SLsmg_fill_region(top + height, left + 1, 1, width - 1, ' ');
Packit Service 8876fe
	SLsmg_fill_region(top + 1, left + width, height, 1, ' ');
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtClearBox(int left, int top, int width, int height) {
Packit Service 8876fe
    if (currentWindow) {
Packit Service 8876fe
	top += currentWindow->top;
Packit Service 8876fe
	left += currentWindow->left;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_fill_region(top, left, height, width, ' ');
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static void initKeymap(void) {
Packit Service 8876fe
    const struct keymap * curr;
Packit Service 8876fe
    struct kmap_trie_entry *kmap_trie_escBrack, *kmap_trie_escO;
Packit Service 8876fe
Packit Service 8876fe
    /* Here are some entries that will help in handling esc O foo and
Packit Service 8876fe
       esc [ foo as variants of each other. */
Packit Service 8876fe
    kmap_trie_root = calloc(3, sizeof (struct kmap_trie_entry));
Packit Service 8876fe
    kmap_trie_escBrack = kmap_trie_root + 1;
Packit Service 8876fe
    kmap_trie_escO = kmap_trie_root + 2;
Packit Service 8876fe
Packit Service 8876fe
    kmap_trie_root->alloced = 1;
Packit Service 8876fe
    kmap_trie_root->c = '\033';
Packit Service 8876fe
    kmap_trie_root->contseq = kmap_trie_escBrack;
Packit Service 8876fe
Packit Service 8876fe
    kmap_trie_escBrack->c = '[';
Packit Service 8876fe
    kmap_trie_escBrack->next = kmap_trie_escO;
Packit Service 8876fe
Packit Service 8876fe
    kmap_trie_escO->c = 'O';
Packit Service 8876fe
Packit Service 8876fe
    /* First bind built-in default bindings. They may be shadowed by
Packit Service 8876fe
       the termcap entries that get bound later. */
Packit Service 8876fe
    for (curr = keymap; curr->code; curr++) {
Packit Service 8876fe
        if (curr->str)
Packit Service 8876fe
            newtBindKey(curr->str,curr->code);
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    /* Then bind strings from termcap entries */
Packit Service 8876fe
    for (curr = keymap; curr->code; curr++) {
Packit Service 8876fe
	if (curr->tc) {
Packit Service 8876fe
            char *pc = SLtt_tgetstr(curr->tc);
Packit Service 8876fe
            if (pc) {
Packit Service 8876fe
                newtBindKey(pc,curr->code);
Packit Service 8876fe
            }
Packit Service 8876fe
        }
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    /* Finally, invent lowest-priority keybindings that correspond to
Packit Service 8876fe
       searching for esc-O-foo if esc-[-foo was not found and vice
Packit Service 8876fe
       versa.  That is needed because of strong confusion among
Packit Service 8876fe
       different emulators of VTxxx terminals; some terminfo/termcap
Packit Service 8876fe
       descriptions are apparently written by people who were not
Packit Service 8876fe
       aware of the differences between "applicataion" and "terminal"
Packit Service 8876fe
       keypad modes. Or perhaps they were, but tried to make their
Packit Service 8876fe
       description work with a program that puts the keyboard in the
Packit Service 8876fe
       wrong emulation mode. In short, one needs this: */
Packit Service 8876fe
    kmap_trie_fallback(kmap_trie_escO->contseq, &kmap_trie_escBrack->contseq);
Packit Service 8876fe
    kmap_trie_fallback(kmap_trie_escBrack->contseq, &kmap_trie_escO->contseq);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static void free_keys(struct kmap_trie_entry *kmap, struct kmap_trie_entry *parent, int prepare) {
Packit Service 8876fe
    if (kmap == NULL)
Packit Service 8876fe
	return;
Packit Service 8876fe
Packit Service 8876fe
    free_keys(kmap->contseq, kmap, prepare);
Packit Service 8876fe
    free_keys(kmap->next, kmap, prepare);
Packit Service 8876fe
Packit Service 8876fe
    if (!kmap->alloced && kmap - parent == 1)
Packit Service 8876fe
	    return;
Packit Service 8876fe
Packit Service 8876fe
    /* find first element in array */
Packit Service 8876fe
    while (!kmap->alloced)
Packit Service 8876fe
	kmap--;
Packit Service 8876fe
Packit Service 8876fe
    kmap->alloced += prepare ? 1 : -1;
Packit Service 8876fe
    if (!prepare && kmap->alloced == 1)
Packit Service 8876fe
	free(kmap);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
static void freeKeymap() {
Packit Service 8876fe
    free_keys(kmap_trie_root, NULL, 1);
Packit Service 8876fe
    free_keys(kmap_trie_root, NULL, 0);
Packit Service 8876fe
    kmap_trie_root = NULL;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
/**
Packit Service 8876fe
 * @brief Delay for a specified number of usecs
Packit Service 8876fe
 * @param int - number of usecs to wait for.
Packit Service 8876fe
 */
Packit Service 8876fe
void newtDelay(unsigned int usecs) {
Packit Service 8876fe
    usleep(usecs);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
struct eventResult newtDefaultEventHandler(newtComponent c,
Packit Service 8876fe
					   struct event ev) {
Packit Service 8876fe
    struct eventResult er;
Packit Service 8876fe
Packit Service 8876fe
    er.result = ER_IGNORED;
Packit Service 8876fe
    return er;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtRedrawHelpLine(void) {
Packit Service 8876fe
    char * buf;
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_set_color(NEWT_COLORSET_HELPLINE);
Packit Service 8876fe
Packit Service 8876fe
    if (currentHelpline) {
Packit Service 8876fe
	/* buffer size needs to be wide enough to hold all the multibyte
Packit Service 8876fe
	   currentHelpline + all the single byte ' ' to fill the line */
Packit Service 8876fe
	int wlen = wstrlen(*currentHelpline, -1);
Packit Service 8876fe
	int len;
Packit Service 8876fe
Packit Service 8876fe
	if (wlen > SLtt_Screen_Cols)
Packit Service 8876fe
	    wlen = SLtt_Screen_Cols;
Packit Service 8876fe
	len = strlen(*currentHelpline) + (SLtt_Screen_Cols - wlen);
Packit Service 8876fe
	buf = alloca(len + 1);
Packit Service 8876fe
	memset(buf, ' ', len);
Packit Service 8876fe
	memcpy(buf, *currentHelpline, strlen(*currentHelpline));
Packit Service 8876fe
	buf[len] = '\0';
Packit Service 8876fe
    } else {
Packit Service 8876fe
	buf = alloca(SLtt_Screen_Cols + 1);
Packit Service 8876fe
	memset(buf, ' ', SLtt_Screen_Cols);
Packit Service 8876fe
	buf[SLtt_Screen_Cols] = '\0';
Packit Service 8876fe
    }
Packit Service 8876fe
    SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
Packit Service 8876fe
    SLsmg_write_string(buf);
Packit Service 8876fe
    SLsmg_gotorc(cursorRow, cursorCol);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtPushHelpLine(const char * text) {
Packit Service 8876fe
    if (currentHelpline && currentHelpline - helplineStack + 1
Packit Service 8876fe
	    >= sizeof (helplineStack) / sizeof (char *))
Packit Service 8876fe
	return;
Packit Service 8876fe
Packit Service 8876fe
    if (!text)
Packit Service 8876fe
	text = defaultHelpLine;
Packit Service 8876fe
Packit Service 8876fe
    if (currentHelpline)
Packit Service 8876fe
	(*(++currentHelpline)) = strdup(text);
Packit Service 8876fe
    else {
Packit Service 8876fe
	currentHelpline = helplineStack;
Packit Service 8876fe
	*currentHelpline = strdup(text);
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    newtRedrawHelpLine();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtPopHelpLine(void) {
Packit Service 8876fe
    if (!currentHelpline) return;
Packit Service 8876fe
Packit Service 8876fe
    free(*currentHelpline);
Packit Service 8876fe
    if (currentHelpline == helplineStack)
Packit Service 8876fe
	currentHelpline = NULL;
Packit Service 8876fe
    else
Packit Service 8876fe
	currentHelpline--;
Packit Service 8876fe
Packit Service 8876fe
    newtRedrawHelpLine();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtDrawRootText(int col, int row, const char * text) {
Packit Service 8876fe
    SLsmg_set_color(NEWT_COLORSET_ROOTTEXT);
Packit Service 8876fe
Packit Service 8876fe
    if (col < 0) {
Packit Service 8876fe
	col = SLtt_Screen_Cols + col;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    if (row < 0) {
Packit Service 8876fe
	row = SLtt_Screen_Rows + row;
Packit Service 8876fe
    }
Packit Service 8876fe
Packit Service 8876fe
    SLsmg_gotorc(row, col);
Packit Service 8876fe
    SLsmg_write_string((char *)text);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
int newtSetFlags(int oldFlags, int newFlags, enum newtFlagsSense sense) {
Packit Service 8876fe
    switch (sense) {
Packit Service 8876fe
      case NEWT_FLAGS_SET:
Packit Service 8876fe
	return oldFlags | newFlags;
Packit Service 8876fe
Packit Service 8876fe
      case NEWT_FLAGS_RESET:
Packit Service 8876fe
	return oldFlags & (~newFlags);
Packit Service 8876fe
Packit Service 8876fe
      case NEWT_FLAGS_TOGGLE:
Packit Service 8876fe
	return oldFlags ^ newFlags;
Packit Service 8876fe
Packit Service 8876fe
      default:
Packit Service 8876fe
	return oldFlags;
Packit Service 8876fe
    }
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtBell(void)
Packit Service 8876fe
{
Packit Service 8876fe
    SLtt_beep();
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtGetScreenSize(int * cols, int * rows) {
Packit Service 8876fe
    if (rows) *rows = SLtt_Screen_Rows;
Packit Service 8876fe
    if (cols) *cols = SLtt_Screen_Cols;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtDefaultPlaceHandler(newtComponent c, int newLeft, int newTop) {
Packit Service 8876fe
    c->left = newLeft;
Packit Service 8876fe
    c->top = newTop;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtDefaultMappedHandler(newtComponent c, int isMapped) {
Packit Service 8876fe
    c->isMapped = isMapped;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtCursorOff(void) {
Packit Service 8876fe
    cursorOn = 0;
Packit Service 8876fe
    SLtt_set_cursor_visibility (cursorOn);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtCursorOn(void) {
Packit Service 8876fe
    cursorOn = 1;
Packit Service 8876fe
    SLtt_set_cursor_visibility (cursorOn);
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtTrashScreen(void) {
Packit Service 8876fe
    if (trashScreen)
Packit Service 8876fe
	SLsmg_touch_lines(0, SLtt_Screen_Rows);
Packit Service 8876fe
}
Packit Service 8876fe
     
Packit Service 8876fe
void newtComponentGetPosition(newtComponent co, int * left, int * top) {
Packit Service 8876fe
    if (left) *left = co->left;
Packit Service 8876fe
    if (top) *top = co->top;
Packit Service 8876fe
}
Packit Service 8876fe
Packit Service 8876fe
void newtComponentGetSize(newtComponent co, int * width, int * height) {
Packit Service 8876fe
    if (width) *width = co->width;
Packit Service 8876fe
    if (height) *height = co->height;
Packit Service 8876fe
}