]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
Initial revision
authorewt <ewt>
Mon, 25 Mar 1996 01:59:25 +0000 (01:59 +0000)
committerewt <ewt>
Mon, 25 Mar 1996 01:59:25 +0000 (01:59 +0000)
Makefile [new file with mode: 0644]
button.c [new file with mode: 0644]
checkbox.c [new file with mode: 0644]
entry.c [new file with mode: 0644]
form.c [new file with mode: 0644]
newt.c [new file with mode: 0644]
newt.h [new file with mode: 0644]
newt_pr.h [new file with mode: 0644]
showchars.c [new file with mode: 0644]
showkey.c [new file with mode: 0644]
test.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..811994c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,32 @@
+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
+
diff --git a/button.c b/button.c
new file mode 100644 (file)
index 0000000..f29c30c
--- /dev/null
+++ b/button.c
@@ -0,0 +1,127 @@
+#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;
+}
diff --git a/checkbox.c b/checkbox.c
new file mode 100644 (file)
index 0000000..4bc1ff7
--- /dev/null
@@ -0,0 +1,175 @@
+#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;
+}
diff --git a/entry.c b/entry.c
new file mode 100644 (file)
index 0000000..7ab4b4d
--- /dev/null
+++ b/entry.c
@@ -0,0 +1,255 @@
+#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;
+}
diff --git a/form.c b/form.c
new file mode 100644 (file)
index 0000000..fe6dcfe
--- /dev/null
+++ b/form.c
@@ -0,0 +1,158 @@
+#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);
+}
diff --git a/newt.c b/newt.c
new file mode 100644 (file)
index 0000000..0ce8c29
--- /dev/null
+++ b/newt.c
@@ -0,0 +1,334 @@
+#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);
+}
diff --git a/newt.h b/newt.h
new file mode 100644 (file)
index 0000000..820e67c
--- /dev/null
+++ b/newt.h
@@ -0,0 +1,75 @@
+#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 */
diff --git a/newt_pr.h b/newt_pr.h
new file mode 100644 (file)
index 0000000..e8dfbff
--- /dev/null
+++ b/newt_pr.h
@@ -0,0 +1,52 @@
+#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 */
diff --git a/showchars.c b/showchars.c
new file mode 100644 (file)
index 0000000..0fc117f
--- /dev/null
@@ -0,0 +1,44 @@
+#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;
+}
diff --git a/showkey.c b/showkey.c
new file mode 100644 (file)
index 0000000..51d9193
--- /dev/null
+++ b/showkey.c
@@ -0,0 +1,41 @@
+#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();
+}
diff --git a/test.c b/test.c
new file mode 100644 (file)
index 0000000..6329d40
--- /dev/null
+++ b/test.c
@@ -0,0 +1,51 @@
+#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);
+}