--- /dev/null
+OBJS = newt.o test.o button.o form.o checkbox.o entry.o
+LIBS = -lslang -lm -lefence
+CFLAGS = -g -Wall
+
+PROGS = test
+
+SOURCES = $(subst .o,.c,$(OBJS))
+
+ifeq (.depend,$(wildcard .depend))
+TARGET=$(PROGS)
+else
+TARGET=depend $(PROGS)
+endif
+
+all: $(TARGET)
+
+test: $(OBJS)
+ gcc -g -o test $(OBJS) $(LIBS)
+
+veryclean: clean
+ rm -f .depend
+
+clean:
+ rm -f $(PROGS) $(OBJS) core
+
+depend:
+ $(CPP) $(CFLAGS) -M $(SOURCES) > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
--- /dev/null
+#include <slang/slang.h>
+#include <stdlib.h>
+
+#include "newt.h"
+#include "newt_pr.h"
+
+struct button {
+ char * text;
+ char bgColor;
+};
+
+static void buttonDrawIt(newtComponent co, int active, int pushed);
+static void buttonDrawText(newtComponent co, int active, int pushed);
+
+static void buttonDraw(newtComponent c);
+static void buttonDestroy(newtComponent co);
+static struct eventResult buttonEvent(struct newtComponent * c,
+ struct event ev);
+
+static struct componentOps buttonOps = {
+ buttonDraw,
+ buttonEvent,
+ buttonDestroy,
+} ;
+
+newtComponent newtButton(int left, int row, char * text) {
+ newtComponent co;
+ struct button * bu;
+
+ co = malloc(sizeof(*co));
+ bu = malloc(sizeof(struct button));
+ co->data = bu;
+
+ bu->text = strdup(text);
+ co->ops = &buttonOps;
+
+ co->height = 4;
+ co->width = strlen(text) + 5;
+ co->top = row;
+ co->left = left;
+ co->takesFocus = 1;
+
+ newtGotorc(co->top, co->left);
+ bu->bgColor = (SLsmg_char_at() >> 8) & 0xFF;
+
+ return co;
+}
+
+static void buttonDestroy(newtComponent co) {
+ struct button * bu = co->data;
+
+ free(bu->text);
+ free(bu);
+ free(co);
+}
+
+static void buttonDraw(newtComponent co) {
+ buttonDrawIt(co, 0, 0);
+}
+
+static void buttonDrawIt(newtComponent co, int active, int pushed) {
+ struct button * bu = co->data;
+
+ SLsmg_set_color(COLORSET_BUTTON);
+ if (pushed) {
+ SLsmg_set_color(COLORSET_BUTTON);
+ newtDrawBox(co->left + 1, co->top + 1, co->width - 1, 3, 0);
+
+ SLsmg_set_color(bu->bgColor);
+ newtClearBox(co->left, co->top, co->width, 1);
+ newtClearBox(co->left, co->top, 1, co->height);
+ } else {
+ newtDrawBox(co->left, co->top, co->width - 1, 3, 1);
+ }
+
+ buttonDrawText(co, active, pushed);
+}
+
+static void buttonDrawText(newtComponent co, int active, int pushed) {
+ struct button * bu = co->data;
+
+ if (pushed) pushed = 1;
+
+ if (active)
+ SLsmg_set_color(COLORSET_ACTBUTTON);
+ else
+ SLsmg_set_color(COLORSET_BUTTON);
+
+ newtGotorc(co->top + 1 + pushed, co->left + 1 + pushed);
+ SLsmg_write_char(' ');
+ SLsmg_write_string(bu->text);
+ SLsmg_write_char(' ');
+}
+
+static struct eventResult buttonEvent(struct newtComponent * co,
+ struct event ev) {
+ struct eventResult er;
+
+ switch (ev.event) {
+ case EV_FOCUS:
+ buttonDrawIt(co, 1, 0);
+ er.result = ER_SWALLOWED;
+ break;
+
+ case EV_UNFOCUS:
+ buttonDrawIt(co, 0, 0);
+ er.result = ER_SWALLOWED;
+ break;
+
+ case EV_KEYPRESS:
+ if (ev.u.key == ' ' || ev.u.key == '\r') {
+ /* look pushed */
+ buttonDrawIt(co, 1, 1);
+ newtRefresh();
+ newtDelay(300000);
+ buttonDrawIt(co, 1, 0);
+ newtRefresh();
+ newtDelay(300000);
+
+ er.result = ER_EXITFORM;
+ } else
+ er.result = ER_IGNORED;
+ break;
+ }
+
+ return er;
+}
--- /dev/null
+#include <slang/slang.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "newt.h"
+#include "newt_pr.h"
+
+struct checkbox {
+ char * text;
+ char * seq;
+ char * result;
+ newtComponent prevButton, lastButton;
+ char isRadio;
+ char value;
+};
+
+static void cbDrawIt(newtComponent c, int active);
+
+static void cbDraw(newtComponent c);
+static void cbDestroy(newtComponent co);
+struct eventResult cbEvent(struct newtComponent * co, struct event ev);
+
+static struct componentOps cbOps = {
+ cbDraw,
+ cbEvent,
+ cbDestroy,
+} ;
+
+newtComponent newtRadiobutton(int left, int top, char * text, int isDefault,
+ newtComponent prevButton) {
+ newtComponent co;
+ newtComponent curr;
+ struct checkbox * rb;
+ char initialValue;
+
+ if (isDefault)
+ initialValue = '*';
+ else
+ initialValue = ' ';
+
+ co = newtCheckbox(left, top, text, initialValue, " *", NULL);
+ rb = co->data;
+ rb->isRadio = 1;
+
+ rb->prevButton = prevButton;
+
+ for (curr = co; curr; curr = rb->prevButton) {
+ rb = curr->data;
+ rb->lastButton = co;
+ }
+
+ return co;
+}
+
+newtComponent newtCheckbox(int left, int top, char * text, char defValue,
+ char * seq, char * result) {
+ newtComponent co;
+ struct checkbox * cb;
+
+ if (!seq) seq = " *";
+
+ co = malloc(sizeof(*co));
+ cb = malloc(sizeof(struct checkbox));
+ co->data = cb;
+
+ if (result)
+ cb->result = result;
+ else
+ cb->result = &cb->value;
+
+ cb->text = strdup(text);
+ cb->seq = strdup(seq);
+ defValue ? (*cb->result = defValue) : (*cb->result = cb->seq[0]);
+ cb->isRadio = 0;
+
+ co->ops = &cbOps;
+
+ co->height = 1;
+ co->width = strlen(text) + 4;
+ co->top = top;
+ co->left = left;
+ co->takesFocus = 1;
+
+ return co;
+}
+
+static void cbDraw(newtComponent c) {
+ cbDrawIt(c, 0);
+}
+
+static void cbDrawIt(newtComponent c, int active) {
+ struct checkbox * cb = c->data;
+
+ SLsmg_set_color(COLORSET_CHECKBOX);
+
+ newtGotorc(c->top, c->left);
+
+ if (cb->isRadio)
+ SLsmg_write_string("( ) ");
+ else
+ SLsmg_write_string("[ ] ");
+
+ SLsmg_write_string(cb->text);
+
+ if (active)
+ SLsmg_set_color(COLORSET_ACTCHECKBOX);
+
+ newtGotorc(c->top, c->left + 1);
+ SLsmg_write_char(*cb->result);
+}
+
+static void cbDestroy(newtComponent co) {
+ struct checkbox * cb = co->data;
+
+ free(cb->text);
+ free(cb->seq);
+ free(cb);
+ free(co);
+}
+
+struct eventResult cbEvent(struct newtComponent * co, struct event ev) {
+ struct eventResult er;
+ struct checkbox * cb = co->data;
+ struct checkbox * rb;
+ newtComponent curr;
+ char * cur;
+
+ switch (ev.event) {
+ case EV_FOCUS:
+ cbDrawIt(co, 1);
+ er.result = ER_SWALLOWED;
+ break;
+
+ case EV_UNFOCUS:
+ cbDrawIt(co, 0);
+ er.result = ER_SWALLOWED;
+ break;
+
+ case EV_KEYPRESS:
+ if (ev.u.key == ' ' || ev.u.key == '\r') {
+ if (cb->isRadio) {
+ /* find the one that's turned off */
+ curr = cb->lastButton;
+ rb = curr->data;
+ while (curr && rb->value == rb->seq[0]) {
+ curr = rb->prevButton;
+ if (curr) rb = curr->data;
+ }
+ if (curr) {
+ rb->value = rb->seq[0];
+ cbDrawIt(curr, 0);
+ }
+ cb->value = cb->seq[1];
+ cbDrawIt(co, 1);
+ } else {
+ cur = strchr(cb->seq, *cb->result);
+ if (!cur)
+ *cb->result = *cb->seq;
+ else {
+ cur++;
+ if (! *cur)
+ *cb->result = *cb->seq;
+ else
+ *cb->result = *cur;
+ }
+ cbDrawIt(co, 1);
+ er.result = ER_SWALLOWED;
+ }
+ } else {
+ er.result = ER_IGNORED;
+ }
+ }
+
+ return er;
+}
--- /dev/null
+#include <ctype.h>
+#include <slang/slang.h>
+#include <stdlib.h>
+
+#include "newt.h"
+#include "newt_pr.h"
+
+struct entry {
+ int flags;
+ char * buf;
+ char ** resultPtr;
+ int bufAlloced;
+ int bufUsed; /* amount of the buffer that's been used */
+ int cursorPosition; /* cursor *in the string* on on screen */
+ int firstChar; /* first character position being shown */
+};
+
+static void entryDraw(newtComponent co);
+static void entryDestroy(newtComponent co);
+static struct eventResult entryEvent(struct newtComponent * co,
+ struct event ev);
+
+static struct eventResult entryHandleKey(struct newtComponent * co, int key);
+
+static struct componentOps entryOps = {
+ entryDraw,
+ entryEvent,
+ entryDestroy,
+} ;
+
+newtComponent newtEntry(int left, int top, char * initialValue, int width,
+ char ** resultPtr, int flags) {
+ newtComponent co;
+ struct entry * en;
+
+ co = malloc(sizeof(*co));
+ en = malloc(sizeof(struct entry));
+ co->data = en;
+
+ co->top = top;
+ co->left = left;
+ co->height = 1;
+ co->width = width;
+ co->takesFocus = 1;
+
+ co->ops = &entryOps;
+
+ en->flags = flags;
+ en->cursorPosition = 0;
+ en->firstChar = 0;
+ en->bufUsed = 0;
+ en->bufAlloced = width + 1;
+
+ if (initialValue && strlen(initialValue) > width) {
+ en->bufAlloced = strlen(initialValue) + 1;
+ }
+ en->buf = malloc(en->bufAlloced);
+ *resultPtr = en->buf;
+ en->resultPtr = resultPtr;
+
+ memset(en->buf, 0, en->bufAlloced);
+ if (initialValue) {
+ strcpy(en->buf, initialValue);
+ en->bufUsed = strlen(initialValue);
+ }
+
+ return co;
+}
+
+static void entryDraw(newtComponent co) {
+ struct entry * en = co->data;
+ int i;
+ char * chptr;
+ int len;
+
+ if (en->flags & NEWT_ENTRY_HIDDEN) {
+ newtGotorc(co->top, co->left);
+ SLsmg_set_color(COLORSET_ENTRY);
+ for (i = 0; i < co->width; i++)
+ SLsmg_write_char('_');
+ newtGotorc(co->top, co->left);
+
+ return;
+ }
+
+ newtGotorc(co->top, co->left);
+ SLsmg_set_color(COLORSET_ENTRY);
+
+ if (en->cursorPosition < en->firstChar) {
+ /* scroll to the left */
+ en->firstChar = en->cursorPosition;
+ } else if ((en->firstChar + co->width) <= en->cursorPosition) {
+ /* scroll to the right */
+ en->firstChar = en->cursorPosition - co->width + 1;
+ }
+
+ chptr = en->buf + en->firstChar;
+ len = strlen(chptr);
+
+ if (len <= co->width) {
+ i = len;
+ SLsmg_write_string(chptr);
+ while (i < co->width) {
+ SLsmg_write_char('_');
+ i++;
+ }
+ } else {
+ SLsmg_write_nstring(chptr, co->width);
+ }
+
+ newtGotorc(co->top, co->left + (en->cursorPosition - en->firstChar));
+}
+
+static void entryDestroy(newtComponent co) {
+ struct entry * en = co->data;
+
+ free(en->buf);
+ free(en);
+ free(co);
+}
+
+static struct eventResult entryEvent(struct newtComponent * co,
+ struct event ev) {
+ struct entry * en = co->data;
+ struct eventResult er;
+
+ switch (ev.event) {
+ case EV_FOCUS:
+ /*SLtt_set_cursor_visibility(0);*/
+ newtGotorc(co->top, co->left + (en->cursorPosition - en->firstChar));
+ er.result = ER_SWALLOWED;
+ break;
+
+ case EV_UNFOCUS:
+ /*SLtt_set_cursor_visibility(1);*/
+ newtGotorc(0, 0);
+ er.result = ER_SWALLOWED;
+ break;
+
+ case EV_KEYPRESS:
+ er = entryHandleKey(co, ev.u.key);
+ break;
+ }
+
+ return er;
+}
+
+static struct eventResult entryHandleKey(struct newtComponent * co, int key) {
+ struct entry * en = co->data;
+ struct eventResult er;
+ char * chptr, * insPoint;
+
+ er.result = ER_SWALLOWED;
+ switch (key) {
+ case '\001': /* ^A */
+ case NEWT_KEY_HOME:
+ en->cursorPosition = 0;
+ break;
+
+ case '\005': /* ^E */
+ case NEWT_KEY_END:
+ en->cursorPosition = en->bufUsed;
+ break;
+
+ case '\013': /* ^K */
+ en->bufUsed = en->cursorPosition;
+ memset(en->buf + en->bufUsed, 0, en->bufAlloced - en->bufUsed);
+ break;
+
+ case '\002': /* ^B */
+ case NEWT_KEY_LEFT:
+ if (en->cursorPosition)
+ en->cursorPosition--;
+ break;
+
+ case '\004':
+ case NEWT_KEY_DELETE:
+ chptr = en->buf + en->cursorPosition;
+ if (*chptr) {
+ chptr++;
+ while (*chptr) {
+ *(chptr - 1) = *chptr;
+ chptr++;
+ }
+ *(chptr - 1) = '\0';
+ en->bufUsed--;
+ }
+ break;
+
+ case NEWT_KEY_BKSPC:
+ if (en->cursorPosition) {
+ /* if this isn't true, there's nothing to erase */
+ chptr = en->buf + en->cursorPosition;
+ en->bufUsed--;
+ en->cursorPosition--;
+ while (*chptr) {
+ *(chptr - 1) = *chptr;
+ chptr++;
+ }
+ *(chptr - 1) = '\0';
+ }
+ break;
+
+ case '\006': /* ^B */
+ case NEWT_KEY_RIGHT:
+ if (en->cursorPosition < en->bufUsed)
+ en->cursorPosition++;
+ break;
+
+ default:
+ if ((key >= 0x20 && key <= 0x7e) || (key >= 0xa0 && key <= 0xff)) {
+ if (!(en->flags & NEWT_ENTRY_SCROLL) && en->bufUsed == co->width) {
+ SLtt_beep();
+ break;
+ }
+
+ if ((en->bufUsed + 1) == en->bufAlloced) {
+ en->bufAlloced += 20;
+ en->buf = realloc(en->buf, en->bufAlloced);
+ *en->resultPtr = en->buf;
+ memset(en->buf + en->bufUsed + 1, 0, 20);
+ }
+
+ if (en->cursorPosition == en->bufUsed) {
+ en->bufUsed++;
+ } else {
+ /* insert the new character */
+
+ /* chptr is the last character in the string */
+ chptr = (en->buf + en->bufUsed) - 1;
+ if ((en->bufUsed + 1) == en->bufAlloced) {
+ /* this string fills the buffer, so clip it */
+ chptr--;
+ } else
+ en->bufUsed++;
+
+ insPoint = en->buf + en->cursorPosition;
+
+ while (chptr >= insPoint) {
+ *(chptr + 1) = *chptr;
+ chptr--;
+ }
+
+ }
+
+ en->buf[en->cursorPosition++] = key;
+ } else {
+ er.result = ER_IGNORED;
+ }
+ }
+
+ entryDraw(co);
+
+ return er;
+}
--- /dev/null
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "newt.h"
+#include "newt_pr.h"
+
+struct newtForm {
+ int numCompsAlloced;
+ newtComponent * comps;
+ int numComps;
+ int currComp;
+};
+
+newtForm newtCreateForm(void) {
+ newtForm form;
+
+ form = malloc(sizeof(*form));
+ form->numCompsAlloced = 5;
+ form->numComps = 0;
+ form->currComp = -1;
+ form->comps = malloc(sizeof(*(form->comps)) * form->numCompsAlloced);
+
+ return form;
+}
+
+static void gotoComponent(newtForm form, int newComp);
+
+void newtAddComponentToForm(newtForm form, newtComponent co) {
+ if (form->numCompsAlloced == form->numComps) {
+ form->numCompsAlloced += 5;
+ form->comps = realloc(form->comps,
+ sizeof(*(form->comps)) * form->numCompsAlloced);
+ }
+
+ form->comps[form->numComps++] = co;
+}
+
+void newtAddComponentsToForm(newtForm form, ...) {
+ va_list ap;
+ newtComponent co;
+
+ va_start(ap, form);
+
+ while ((co = va_arg(ap, newtComponent)))
+ newtAddComponentToForm(form, co);
+
+ va_end(ap);
+}
+
+newtComponent newtRunForm(newtForm form) {
+ int i;
+ newtComponent co;
+ struct event ev;
+ struct eventResult er;
+ int key, new;
+
+ /* first, draw all of the components */
+ for (i = 0; i < form->numComps; i++) {
+ co = form->comps[i];
+ co->ops->draw(co);
+ }
+
+ if (form->currComp == -1)
+ gotoComponent(form, 0);
+
+ do {
+ co = form->comps[form->currComp];
+
+ /*newtGotorc(0, 0);*/
+ newtRefresh();
+ key = newtGetKey();
+
+ er.result = ER_IGNORED;
+
+ /* handle system wide events */
+ switch (key) {
+ case NEWT_KEY_TAB:
+ new = form->currComp + 1;
+ if (new == form->numComps) new = 0;
+ gotoComponent(form, new);
+ er.result = ER_SWALLOWED;
+ break;
+ }
+
+ /* handle component specific events */
+ if (er.result == ER_IGNORED) {
+ ev.event = EV_KEYPRESS;
+ ev.u.key = key;
+ er = co->ops->event(co, ev);
+ }
+
+ /* handle default events */
+ if (er.result == ER_IGNORED) {
+ switch (key) {
+ case NEWT_KEY_UP:
+ case NEWT_KEY_LEFT:
+ case NEWT_KEY_BKSPC:
+ if (form->currComp == 0)
+ new = form->numComps - 1;
+ else
+ new = form->currComp - 1;
+
+ gotoComponent(form, new);
+ break;
+
+ case NEWT_KEY_DOWN:
+ case NEWT_KEY_RIGHT:
+ case NEWT_KEY_ENTER:
+ new = form->currComp + 1;
+ if (new == form->numComps) new = 0;
+ gotoComponent(form, new);
+ break;
+ }
+ }
+
+ } while (er.result != ER_EXITFORM);
+
+ newtRefresh();
+
+ return form->comps[form->currComp];
+}
+
+/* this also destroys all of the components on the form */
+void newtDestroyForm(newtForm form) {
+ int i;
+ newtComponent co;
+
+ /* first, destroy all of the components */
+ for (i = 0; i < form->numComps; i++) {
+ co = form->comps[i];
+ if (co->ops->destroy) {
+ co->ops->destroy(co);
+ } else {
+ if (co->data) free(co->data);
+ free(co);
+ }
+ }
+
+ free(form->comps);
+ free(form);
+}
+
+static void gotoComponent(newtForm form, int newComp) {
+ newtComponent co;
+ struct event ev;
+
+ if (form->currComp != -1) {
+ ev.event = EV_UNFOCUS;
+ co = form->comps[form->currComp];
+ co->ops->event(co, ev);
+ }
+
+ form->currComp = newComp;
+
+ ev.event = EV_FOCUS;
+ co = form->comps[form->currComp];
+ co->ops->event(co, ev);
+}
--- /dev/null
+#include <slang/slang.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "newt.h"
+#include "newt_pr.h"
+
+/* this function will be in a future version of slang - I'll just prototype
+ it myself for now XXX */
+void SLsmg_write_color_chars (unsigned short *s, unsigned int len);
+
+struct Window {
+ int height, width, top, left;
+ short * buffer;
+};
+
+struct keymap {
+ char * str;
+ int code;
+ char * tc;
+};
+
+struct Window windowStack[20];
+struct Window * currentWindow = NULL;
+
+struct newtColors newtDefaultColorPalette = {
+ "white", "blue", /* root fg, bg */
+ "black", "lightgray", /* border fg, bg */
+ "black", "lightgray", /* window fg, bg */
+ "white", "black", /* shadow fg, bg */
+ "red", "lightgray", /* title fg, bg */
+ "blue", "magenta", /* button fg, bg */
+ "magenta", "blue", /* active button fg, bg */
+ "black", "green", /* checkbox fg, fg */
+ "green", "black", /* active checkbox fg, bg */
+ "yellow", "red", /* entry box fg, bg */
+};
+
+struct keymap keymap[] = {
+ { "\033OA", NEWT_KEY_UP, "kh" },
+ { "\033[A", NEWT_KEY_UP, "ku" },
+ { "\033OB", NEWT_KEY_DOWN, "kd" },
+ { "\033[B", NEWT_KEY_DOWN, "kd" },
+ { "\033[C", NEWT_KEY_RIGHT, "kr" },
+ { "\033OC", NEWT_KEY_RIGHT, "kr" },
+ { "\033[D", NEWT_KEY_LEFT, "kl" },
+ { "\033OD", NEWT_KEY_LEFT, "kl" },
+ { "\033[H", NEWT_KEY_HOME, "kh" },
+ { "\033[1~", NEWT_KEY_HOME, "kh" },
+ { "\033Ow", NEWT_KEY_END, "kH" },
+ { "\033[4~", NEWT_KEY_END, "kH" },
+
+ { "\033[3~", NEWT_KEY_DELETE, "kl" },
+
+ { NULL, 0, NULL }, /* LEAVE this one */
+};
+char keyPrefix = '\033';
+
+void newtRefresh(void) {
+ SLsmg_refresh();
+}
+
+void newtCls(void) {
+ SLsmg_set_color(COLORSET_ROOT);
+ SLsmg_gotorc(0, 0);
+ SLsmg_erase_eos();
+
+ newtRefresh();
+}
+
+int newtInit(void) {
+ SLtt_get_terminfo();
+
+ SLtt_Use_Ansi_Colors = 1;
+
+ SLsmg_init_smg();
+ SLang_init_tty(0, 0, 0);
+
+ newtSetColors(newtDefaultColorPalette);
+ /*initKeymap();*/
+
+ /*SLtt_set_cursor_visibility(0);*/
+
+ return 0;
+}
+
+int newtFinished(void) {
+ SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
+ SLsmg_refresh();
+ SLsmg_reset_smg();
+ SLang_reset_tty();
+
+ return 0;
+}
+
+void newtSetColors(struct newtColors colors) {
+ SLtt_set_color(COLORSET_ROOT, "", colors.rootFg, colors.rootBg);
+ SLtt_set_color(COLORSET_BORDER, "", colors.borderFg, colors.borderBg);
+ SLtt_set_color(COLORSET_WINDOW, "", colors.windowFg, colors.windowBg);
+ SLtt_set_color(COLORSET_SHADOW, "", colors.shadowFg, colors.shadowBg);
+ SLtt_set_color(COLORSET_TITLE, "", colors.titleFg, colors.titleBg);
+ SLtt_set_color(COLORSET_BUTTON, "", colors.buttonFg, colors.buttonBg);
+ SLtt_set_color(COLORSET_ACTBUTTON, "", colors.actButtonFg,
+ colors.actButtonBg);
+ SLtt_set_color(COLORSET_CHECKBOX, "", colors.checkboxFg, colors.checkboxBg);
+ SLtt_set_color(COLORSET_ACTCHECKBOX, "", colors.actCheckboxFg,
+ colors.actCheckboxBg);
+ SLtt_set_color(COLORSET_ENTRY, "", colors.entryFg, colors.entryBg);
+}
+
+int newtGetKey(void) {
+ int key;
+ char buf[10], * chptr = buf;
+ struct keymap * curr;
+
+ key = SLang_getkey();
+
+ switch (key) {
+ case 0x7f:
+ return NEWT_KEY_BKSPC;
+
+ case 0x08:
+ return NEWT_KEY_BKSPC;
+
+ default:
+ if (key != keyPrefix) return key;
+ }
+
+ memset(buf, 0, sizeof(buf));
+
+ *chptr++ = key;
+ while (SLang_input_pending(1)) {
+ key = SLang_getkey();
+ *chptr++ = key;
+
+ /* this search should use bsearch(), but when we only look through
+ a list of 20 (or so) keymappings, it's probably faster just to
+ do a inline linear search */
+
+ for (curr = keymap; curr->code; curr++) {
+ if (curr->str) {
+ if (!strcmp(curr->str, buf))
+ return curr->code;
+ }
+ }
+ }
+
+ for (curr = keymap; curr->code; curr++) {
+ if (curr->str) {
+ if (!strcmp(curr->str, buf))
+ return curr->code;
+ }
+ }
+
+ /* Looks like we were a bit overzealous in reading characters. Return
+ just the first character, and put everything else back in the buffer
+ for later */
+
+ chptr--;
+ while (chptr > buf)
+ SLang_ungetkey(*chptr--);
+
+ return *chptr;
+}
+
+void newtWaitForKey(void) {
+ newtRefresh();
+
+ SLang_getkey();
+ newtClearKeyBuffer();
+}
+
+void newtClearKeyBuffer(void) {
+ while (SLang_input_pending(1)) {
+ SLang_getkey();
+ }
+}
+
+int newtOpenWindow(int left, int top, int width, int height,
+ char * title) {
+ int i, j, row, col;
+ int n = 0;
+
+ if (!currentWindow) {
+ currentWindow = windowStack;
+ } else {
+ currentWindow++;
+ }
+
+ currentWindow->left = left;
+ currentWindow->top = top;
+ currentWindow->width = width;
+ currentWindow->height = height;
+
+ currentWindow->buffer = malloc(sizeof(short) * (width + 3) * (height + 3));
+
+ row = top - 1;
+ for (j = 0; j < height + 3; j++, row++) {
+ col = left - 1;
+ for (i = 0; i < width + 3; i++, col++) {
+ SLsmg_gotorc(row, col);
+ currentWindow->buffer[n++] = SLsmg_char_at();
+ }
+ }
+
+ SLsmg_set_color(COLORSET_BORDER);
+ SLsmg_draw_box(top - 1, left - 1, height + 2, width + 2);
+
+ if (title) {
+ i = strlen(title) + 4;
+ i = ((width - i) / 2) + left;
+ SLsmg_gotorc(top - 1, i);
+ SLsmg_set_char_set(1);
+ SLsmg_write_char(SLSMG_RTEE_CHAR);
+ SLsmg_set_char_set(0);
+ SLsmg_write_char(' ');
+ SLsmg_set_color(COLORSET_TITLE);
+ SLsmg_write_string(title);
+ SLsmg_set_color(COLORSET_BORDER);
+ SLsmg_write_char(' ');
+ SLsmg_set_char_set(1);
+ SLsmg_write_char(SLSMG_LTEE_CHAR);
+ SLsmg_set_char_set(0);
+ }
+
+ SLsmg_set_color(COLORSET_WINDOW);
+ SLsmg_fill_region(top, left, height, width, ' ');
+
+ SLsmg_set_color(COLORSET_SHADOW);
+ SLsmg_fill_region(top + height + 1, left, 1, width + 2, ' ');
+ SLsmg_fill_region(top, left + width + 1, height + 1, 1, ' ');
+
+ for (i = top; i < (top + height + 1); i++) {
+ SLsmg_gotorc(i, left + width + 1);
+ SLsmg_write_string(" ");
+ }
+
+ return 0;
+}
+
+void newtPopWindow(void) {
+ int j, row, col;
+ int n = 0;
+
+ row = col = 0;
+
+ row = currentWindow->top - 1;
+ col = currentWindow->left - 1;
+ for (j = 0; j < currentWindow->height + 3; j++, row++) {
+ SLsmg_gotorc(row, col);
+ SLsmg_write_color_chars(currentWindow->buffer + n,
+ currentWindow->width + 3);
+ n += currentWindow->width + 3;
+ }
+
+ free(currentWindow->buffer);
+
+ if (currentWindow == windowStack)
+ currentWindow = NULL;
+ else
+ currentWindow--;
+
+ SLsmg_set_char_set(0);
+
+ newtRefresh();
+}
+
+void newtGotorc(int row, int col) {
+ if (!currentWindow)
+ SLsmg_gotorc(row, col);
+ else
+ SLsmg_gotorc(row + currentWindow->top, col + currentWindow->left);
+}
+
+void newtDrawBox(int left, int top, int width, int height, int shadow) {
+ if (currentWindow) {
+ top += currentWindow->top;
+ left += currentWindow->left;
+ }
+
+ SLsmg_draw_box(top, left, height, width);
+
+ if (shadow) {
+ SLsmg_set_color(COLORSET_SHADOW);
+ SLsmg_fill_region(top + height, left + 1, 1, width - 1, ' ');
+ SLsmg_fill_region(top + 1, left + width, height, 1, ' ');
+ }
+}
+
+void newtClearBox(int left, int top, int width, int height) {
+ if (currentWindow) {
+ top += currentWindow->top;
+ left += currentWindow->left;
+ }
+
+ SLsmg_fill_region(top, left, height, width, ' ');
+}
+
+#if 0
+/* This doesn't seem to work quite right. I don't know why not, but when
+ I rsh from an rxvt into a box and run this code, the machine returns
+ console key's (\033[B) rather then xterm ones (\033OB). */
+static void initKeymap(void) {
+ struct keymap * curr;
+
+ for (curr = keymap; curr->code; curr++) {
+ if (!curr->str)
+ curr->str = SLtt_tgetstr(curr->tc);
+ }
+
+ /* Newt's keymap handling is a bit broken. It assumes that any extended
+ keystrokes begin with ESC. If you're using a homebrek terminal you
+ will probably need to fix this, or just yell at me and I'll be so
+ ashamed of myself for doing it this way I'll fix it */
+
+ keyPrefix = 0x1b; /* ESC */
+}
+#endif
+
+void newtDelay(int usecs) {
+ fd_set set;
+ struct timeval tv;
+
+ FD_ZERO(&set);
+
+ tv.tv_sec = usecs / 1000000;
+ tv.tv_usec = usecs % 1000000;
+
+ select(0, &set, &set, &set, &tv);
+}
--- /dev/null
+#ifndef H_NEWT
+#define H_NEWT
+
+struct newtColors {
+ char * rootFg, * rootBg;
+ char * borderFg, * borderBg;
+ char * windowFg, * windowBg;
+ char * shadowFg, * shadowBg;
+ char * titleFg, * titleBg;
+ char * buttonFg, * buttonBg;
+ char * actButtonFg, * actButtonBg;
+ char * checkboxFg, * checkboxBg;
+ char * actCheckboxFg, * actCheckboxBg;
+ char * entryFg, * entryBg;
+};
+
+extern struct newtColors newtDefaultColorPalette;
+
+int newtInit(void);
+int newtFinished(void);
+void newtCls(void);
+void newtWaitForKey(void);
+void newtClearKeyBuffer(void);
+void newtDelay(int usecs);
+/* top, left are *not* counting the border */
+int newtOpenWindow(int left, int top, int width, int height,
+ char * title);
+void newtPopWindow(void);
+void newtSetColors(struct newtColors colors);
+void newtRefresh(void);
+
+/* Components */
+
+typedef struct newtComponent * newtComponent;
+typedef struct newtForm * newtForm;
+
+newtComponent newtButton(int left, int top, char * text);
+newtComponent newtCheckbox(int left, int top, char * text, char defValue,
+ char * seq, char * result);
+newtComponent newtRadiobutton(int left, int top, char * text, int isDefault,
+ newtComponent prevButton);
+
+#define NEWT_ENTRY_SCROLL (1 << 0)
+#define NEWT_ENTRY_HIDDEN (1 << 1)
+
+newtComponent newtEntry(int left, int top, char * initialValue, int width,
+ char ** resultPtr, int flags);
+
+/* Forms */
+
+newtForm newtCreateForm(void);
+void newtAddComponentToForm(newtForm form, newtComponent co);
+void newtAddComponentsToForm(newtForm form, ...);
+newtComponent newtRunForm(newtForm form);
+
+/* this also destroys all of the components on the form */
+void newtDestroyForm(newtForm form);
+
+/* Key codes */
+
+#define NEWT_KEY_TAB '\t'
+#define NEWT_KEY_ENTER '\r'
+#define NEWT_KEY_RETURN NEWT_KEY_ENTER
+
+#define NEWT_KEY_EXTRA_BASE 0x8000
+#define NEWT_KEY_UP NEWT_KEY_EXTRA_BASE + 1
+#define NEWT_KEY_DOWN NEWT_KEY_EXTRA_BASE + 2
+#define NEWT_KEY_LEFT NEWT_KEY_EXTRA_BASE + 4
+#define NEWT_KEY_RIGHT NEWT_KEY_EXTRA_BASE + 5
+#define NEWT_KEY_BKSPC NEWT_KEY_EXTRA_BASE + 6
+#define NEWT_KEY_DELETE NEWT_KEY_EXTRA_BASE + 7
+#define NEWT_KEY_HOME NEWT_KEY_EXTRA_BASE + 8
+#define NEWT_KEY_END NEWT_KEY_EXTRA_BASE + 9
+
+#endif /* H_NEWT */
--- /dev/null
+#ifndef H_NEWT_PR
+#define H_NEWT_PR
+
+#define COLORSET_ROOT 2
+#define COLORSET_BORDER 3
+#define COLORSET_WINDOW 4
+#define COLORSET_SHADOW 5
+#define COLORSET_TITLE 6
+#define COLORSET_BUTTON 7
+#define COLORSET_ACTBUTTON 8
+#define COLORSET_CHECKBOX 9
+#define COLORSET_ACTCHECKBOX 10
+#define COLORSET_ENTRY 11
+
+void newtGotorc(int row, int col);
+void newtDrawBox(int left, int top, int width, int height, int shadow);
+void newtClearBox(int left, int top, int width, int height);
+
+int newtGetKey(void);
+
+struct newtComponent {
+ /* common data */
+ int height, width;
+ int top, left;
+ int takesFocus;
+
+ struct componentOps * ops;
+
+ void * data;
+} ;
+
+enum eventResultTypes { ER_IGNORED, ER_SWALLOWED, ER_EXITFORM };
+struct eventResult {
+ enum eventResultTypes result;
+};
+
+enum eventTypes { EV_FOCUS, EV_UNFOCUS, EV_KEYPRESS };
+
+struct event {
+ enum eventTypes event;
+ union {
+ int key;
+ } u;
+} ;
+
+struct componentOps {
+ void (* draw)(struct newtComponent * c);
+ struct eventResult (* event)(struct newtComponent * c, struct event ev);
+ void (* destroy)(struct newtComponent * c);
+} ;
+
+#endif /* H_NEWT_PR */
--- /dev/null
+#include <slang/slang.h>
+
+void printall(int offset) {
+ int n = 0;
+ int i, j;
+
+ SLsmg_gotorc(0, offset);
+ SLsmg_write_string(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
+ for (i = 0; i < 16; i++) {
+ SLsmg_gotorc(i + 1, offset);
+ SLsmg_printf("%x", i);
+ for (j = 0; j < 16; j++) {
+ SLsmg_gotorc(i + 1, (j + 1) * 2 + offset);
+ SLsmg_write_char(n++);
+ }
+ }
+}
+
+int main(void) {
+ char n = 0;
+
+ SLtt_get_terminfo();
+
+ SLtt_Use_Ansi_Colors = 1;
+
+ SLsmg_init_smg();
+ SLang_init_tty(4, 0, 0);
+
+ SLsmg_cls();
+
+ printall(0);
+ SLsmg_set_char_set(1);
+ printall(40);
+
+ SLsmg_refresh();
+ SLang_getkey();
+
+ SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
+ SLsmg_refresh();
+ SLsmg_reset_smg();
+ SLang_reset_tty();
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <slang/slang.h>
+
+int main(void) {
+ char n = 0;
+ int i;
+ char * buf;
+
+ SLtt_get_terminfo();
+ SLang_init_tty(4, 0, 0);
+
+ buf = SLtt_tgetstr("ku");
+ if (!buf) {
+ printf("termcap entry not found for kl\n\r");
+ } else {
+ printf("termcap entry found for kl: ", buf);
+ while (*buf) {
+ printf("0x%02x ", *buf++);
+ }
+ printf("\n\r");
+ }
+
+ printf("\n\r");
+
+ printf("Press a key: ");
+ fflush(stdout);
+
+ SLang_input_pending(50);
+
+ printf("\n\r");
+ printf("You pressed: ");
+
+ while (SLang_input_pending(1)) {
+ i = SLang_getkey();
+ printf("0x%02x ", i);
+ }
+
+ printf("\n\r");
+
+ SLang_reset_tty();
+}
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "newt.h"
+
+void main(void) {
+ newtComponent b1, b2, c1, c2, r1, r2, r3, e1, e2, e3;
+ newtForm f;
+ char result, result2;
+ char * enr1, * enr2, * enr3;
+
+ newtInit();
+ newtCls();
+
+ newtOpenWindow(2, 5, 30, 10, "first window");
+ newtOpenWindow(20, 10, 40, 13, "window 2");
+
+ f = newtCreateForm();
+
+ b1 = newtButton(3, 1, "Push me");
+ b2 = newtButton(18, 1, "Not me");
+ c1 = newtCheckbox(3, 6, "Check here", ' ', NULL, &result);
+ c2 = newtCheckbox(3, 7, "Not here ", '*', NULL, &result2);
+ r1 = newtRadiobutton(20, 6, "Choice 1", 0, NULL);
+ r2 = newtRadiobutton(20, 7, "Choice 2", 1, r1);
+ r3 = newtRadiobutton(20, 8, "Choice 3", 0, r2);
+
+ e1 = newtEntry(3, 10, "", 20, &enr1, 0);
+ e2 = newtEntry(3, 11, "Default", 20, &enr2, NEWT_ENTRY_SCROLL);
+ e3 = newtEntry(3, 12, NULL, 20, &enr3, NEWT_ENTRY_HIDDEN);
+
+ newtAddComponentsToForm(f, b1, b2, c1, c2, NULL);
+ newtAddComponentsToForm(f, r1, r2, r3, e1, e2, e3, NULL);
+
+ newtRunForm(f);
+
+ enr1 = strdup(enr1);
+ enr2 = strdup(enr2);
+ enr3 = strdup(enr3);
+
+ newtDestroyForm(f);
+
+ newtPopWindow();
+ newtPopWindow();
+ newtFinished();
+
+ printf("got string 1: %s\n", enr1);
+ printf("got string 2: %s\n", enr2);
+ printf("got string 3: %s\n", enr3);
+}