summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/newt/entry.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/newt/entry.c')
-rw-r--r--mdk-stage1/newt/entry.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/mdk-stage1/newt/entry.c b/mdk-stage1/newt/entry.c
new file mode 100644
index 000000000..154edba71
--- /dev/null
+++ b/mdk-stage1/newt/entry.c
@@ -0,0 +1,376 @@
+#include <ctype.h>
+#include <slang.h>
+#include <stdlib.h>
+#include <string.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 */
+ newtEntryFilter filter;
+ void * filterData;
+};
+
+static void entryDraw(newtComponent co);
+static void entryDestroy(newtComponent co);
+static struct eventResult entryEvent(newtComponent co,
+ struct event ev);
+
+static struct eventResult entryHandleKey(newtComponent co, int key);
+
+static struct componentOps entryOps = {
+ entryDraw,
+ entryEvent,
+ entryDestroy,
+ newtDefaultPlaceHandler,
+ newtDefaultMappedHandler,
+} ;
+
+void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd) {
+ struct entry * en = co->data;
+
+ if ((strlen(value) + 1) > (unsigned int)en->bufAlloced) {
+ free(en->buf);
+ en->bufAlloced = strlen(value) + 1;
+ en->buf = malloc(en->bufAlloced);
+ if (en->resultPtr) *en->resultPtr = en->buf;
+ }
+ memset(en->buf, 0, en->bufAlloced); /* clear the buffer */
+ strcpy(en->buf, value);
+ en->bufUsed = strlen(value);
+ en->firstChar = 0;
+ if (cursorAtEnd)
+ en->cursorPosition = en->bufUsed;
+ else
+ en->cursorPosition = 0;
+
+ entryDraw(co);
+} ;
+
+newtComponent newtEntry(int left, int top, const 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->isMapped = 0;
+ co->callback = NULL;
+
+ co->ops = &entryOps;
+
+ en->flags = flags;
+ en->cursorPosition = 0;
+ en->firstChar = 0;
+ en->bufUsed = 0;
+ en->bufAlloced = width + 1;
+ en->filter = NULL;
+
+ if (!(en->flags & NEWT_FLAG_DISABLED))
+ co->takesFocus = 1;
+ else
+ co->takesFocus = 0;
+
+ if (initialValue && strlen(initialValue) > (unsigned int)width) {
+ en->bufAlloced = strlen(initialValue) + 1;
+ }
+ en->buf = malloc(en->bufAlloced);
+ en->resultPtr = resultPtr;
+ if (en->resultPtr) *en->resultPtr = en->buf;
+
+ memset(en->buf, 0, en->bufAlloced);
+ if (initialValue) {
+ strcpy(en->buf, initialValue);
+ en->bufUsed = strlen(initialValue);
+ en->cursorPosition = en->bufUsed;
+ } else {
+ *en->buf = '\0';
+ en->bufUsed = 0;
+ en->cursorPosition = 0;
+ }
+
+ return co;
+}
+
+static void entryDraw(newtComponent co) {
+ struct entry * en = co->data;
+ int i;
+ char * chptr;
+ int len;
+
+ if (!co->isMapped) return;
+
+ if (en->flags & NEWT_FLAG_DISABLED)
+ SLsmg_set_color(NEWT_COLORSET_DISENTRY);
+ else
+ SLsmg_set_color(NEWT_COLORSET_ENTRY);
+
+ if (en->flags & NEWT_FLAG_HIDDEN) {
+ newtGotorc(co->top, co->left);
+ for (i = 0; i < co->width; i++)
+ SLsmg_write_char('_');
+ newtGotorc(co->top, co->left);
+
+ return;
+ }
+
+ newtGotorc(co->top, co->left);
+
+ 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;
+
+ if (en->flags & NEWT_FLAG_PASSWORD) {
+ char *tmpptr, *p;
+
+ tmpptr = alloca(strlen(chptr+2));
+ strcpy(tmpptr, chptr);
+ for (p = tmpptr; *p; p++)
+ *p = '*';
+ chptr = tmpptr;
+ }
+
+ 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);
+ }
+
+ if (en->flags & NEWT_FLAG_HIDDEN)
+ newtGotorc(co->top, co->left);
+ else
+ newtGotorc(co->top, co->left + (en->cursorPosition - en->firstChar));
+}
+
+void newtEntrySetFlags(newtComponent co, int flags, enum newtFlagsSense sense) {
+ struct entry * en = co->data;
+ int row, col;
+
+ en->flags = newtSetFlags(en->flags, flags, sense);
+
+ if (!(en->flags & NEWT_FLAG_DISABLED))
+ co->takesFocus = 1;
+ else
+ co->takesFocus = 0;
+
+ newtGetrc(&row, &col);
+ entryDraw(co);
+ newtGotorc(row, col);
+}
+
+static void entryDestroy(newtComponent co) {
+ struct entry * en = co->data;
+
+ free(en->buf);
+ free(en);
+ free(co);
+}
+
+static struct eventResult entryEvent(newtComponent co,
+ struct event ev) {
+ struct entry * en = co->data;
+ struct eventResult er;
+ int ch;
+
+ if (ev.when == EV_NORMAL) {
+ switch (ev.event) {
+ case EV_FOCUS:
+ newtCursorOn();
+ if (en->flags & NEWT_FLAG_HIDDEN)
+ newtGotorc(co->top, co->left);
+ else
+ newtGotorc(co->top, co->left +
+ (en->cursorPosition - en->firstChar));
+ er.result = ER_SWALLOWED;
+ break;
+
+ case EV_UNFOCUS:
+ newtCursorOff();
+ newtGotorc(0, 0);
+ er.result = ER_SWALLOWED;
+ if (co->callback)
+ co->callback(co, co->callbackData);
+ break;
+
+ case EV_KEYPRESS:
+ ch = ev.u.key;
+ if (en->filter)
+ ch = en->filter(co, en->filterData, ch, en->cursorPosition);
+ if (ch) er = entryHandleKey(co, ch);
+ break;
+
+ case EV_MOUSE:
+ if ((ev.u.mouse.type == MOUSE_BUTTON_DOWN) &&
+ (en->flags ^ NEWT_FLAG_HIDDEN)) {
+ if (strlen(en->buf) >= ev.u.mouse.x - co->left) {
+ en->cursorPosition = ev.u.mouse.x - co->left;
+ newtGotorc(co->top,
+ co->left +(en->cursorPosition - en->firstChar));
+ } else {
+ en->cursorPosition = strlen(en->buf);
+ newtGotorc(co->top,
+ co->left +(en->cursorPosition - en->firstChar));
+ }
+ }
+ break;
+ }
+ } else
+ er.result = ER_IGNORED;
+
+ return er;
+}
+
+static struct eventResult entryHandleKey(newtComponent co, int key) {
+ struct entry * en = co->data;
+ struct eventResult er;
+ char * chptr, * insPoint;
+
+ er.result = ER_SWALLOWED;
+ switch (key) {
+ case '\r': /* Return */
+ if (en->flags & NEWT_FLAG_RETURNEXIT) {
+ er.result = ER_EXITFORM;
+ } else {
+ er.result = ER_NEXTCOMP;
+ }
+ break;
+
+ 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_FLAG_SCROLL) && en->bufUsed >= co->width) {
+ SLtt_beep();
+ break;
+ }
+
+ if ((en->bufUsed + 1) == en->bufAlloced) {
+ en->bufAlloced += 20;
+ en->buf = realloc(en->buf, en->bufAlloced);
+ if (en->resultPtr) *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;
+}
+
+char * newtEntryGetValue(newtComponent co) {
+ struct entry * en = co->data;
+
+ return en->buf;
+}
+
+void newtEntrySetFilter(newtComponent co, newtEntryFilter filter, void * data) {
+ struct entry * en = co->data;
+ en->filter = filter;
+ en->filterData = data;
+}