~ubuntu-branches/ubuntu/dapper/newt/dapper-security

« back to all changes in this revision

Viewing changes to entry.c

  • Committer: Bazaar Package Importer
  • Author(s): Junichi Uekawa
  • Date: 2002-03-31 09:38:18 UTC
  • Revision ID: james.westby@ubuntu.com-20020331093818-t3cla7103r07qnyw
Tags: upstream-0.50.17
ImportĀ upstreamĀ versionĀ 0.50.17

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <ctype.h>
 
2
#include <slang.h>
 
3
#include <stdlib.h>
 
4
#include <string.h>
 
5
 
 
6
#include "newt.h"
 
7
#include "newt_pr.h"
 
8
 
 
9
struct entry {
 
10
    int flags;
 
11
    char * buf;
 
12
    char ** resultPtr;
 
13
    int bufAlloced;
 
14
    int bufUsed;                /* amount of the buffer that's been used */
 
15
    int cursorPosition;         /* cursor *in the string* on on screen */
 
16
    int firstChar;              /* first character position being shown */
 
17
    newtEntryFilter filter;
 
18
    void * filterData;
 
19
};
 
20
 
 
21
static void entryDraw(newtComponent co);
 
22
static void entryDestroy(newtComponent co);
 
23
static struct eventResult entryEvent(newtComponent co,
 
24
                                     struct event ev);
 
25
 
 
26
static struct eventResult entryHandleKey(newtComponent co, int key);
 
27
 
 
28
static struct componentOps entryOps = {
 
29
    entryDraw,
 
30
    entryEvent,
 
31
    entryDestroy,
 
32
    newtDefaultPlaceHandler,
 
33
    newtDefaultMappedHandler,
 
34
} ;
 
35
 
 
36
void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd) {
 
37
    struct entry * en = co->data;
 
38
 
 
39
    if ((strlen(value) + 1) > (unsigned int)en->bufAlloced) {
 
40
        free(en->buf);
 
41
        en->bufAlloced = strlen(value) + 1;
 
42
        en->buf = malloc(en->bufAlloced);
 
43
        if (en->resultPtr) *en->resultPtr = en->buf;
 
44
    }
 
45
    memset(en->buf, 0, en->bufAlloced);         /* clear the buffer */
 
46
    strcpy(en->buf, value);
 
47
    en->bufUsed = strlen(value);
 
48
    en->firstChar = 0;
 
49
    if (cursorAtEnd)
 
50
        en->cursorPosition = en->bufUsed;
 
51
    else
 
52
        en->cursorPosition = 0;
 
53
 
 
54
    entryDraw(co);
 
55
} ;
 
56
 
 
57
newtComponent newtEntry(int left, int top, const char * initialValue, int width,
 
58
                        char ** resultPtr, int flags) {
 
59
    newtComponent co;
 
60
    struct entry * en;
 
61
 
 
62
    co = malloc(sizeof(*co));
 
63
    en = malloc(sizeof(struct entry));
 
64
    co->data = en;
 
65
 
 
66
    co->top = top;
 
67
    co->left = left;
 
68
    co->height = 1;
 
69
    co->width = width;
 
70
    co->isMapped = 0;
 
71
    co->callback = NULL;
 
72
 
 
73
    co->ops = &entryOps;
 
74
 
 
75
    en->flags = flags;
 
76
    en->cursorPosition = 0;
 
77
    en->firstChar = 0;
 
78
    en->bufUsed = 0;
 
79
    en->bufAlloced = width + 1;
 
80
    en->filter = NULL;
 
81
 
 
82
    if (!(en->flags & NEWT_FLAG_DISABLED))
 
83
        co->takesFocus = 1;
 
84
    else
 
85
        co->takesFocus = 0;
 
86
 
 
87
    if (initialValue && strlen(initialValue) > (unsigned int)width) {
 
88
        en->bufAlloced = strlen(initialValue) + 1;
 
89
    }
 
90
    en->buf = malloc(en->bufAlloced);
 
91
    en->resultPtr = resultPtr;
 
92
    if (en->resultPtr) *en->resultPtr = en->buf;
 
93
 
 
94
    memset(en->buf, 0, en->bufAlloced);
 
95
    if (initialValue) {
 
96
        strcpy(en->buf, initialValue);
 
97
        en->bufUsed = strlen(initialValue);
 
98
        en->cursorPosition = en->bufUsed;
 
99
    } else {
 
100
        *en->buf = '\0';
 
101
        en->bufUsed = 0;
 
102
        en->cursorPosition = 0;
 
103
    }
 
104
 
 
105
    return co;
 
106
}
 
107
 
 
108
static void entryDraw(newtComponent co) {
 
109
    struct entry * en = co->data;
 
110
    int i;
 
111
    char * chptr;
 
112
    int len;
 
113
 
 
114
    if (!co->isMapped) return;
 
115
 
 
116
    if (en->flags & NEWT_FLAG_DISABLED)
 
117
        SLsmg_set_color(NEWT_COLORSET_DISENTRY);
 
118
    else
 
119
        SLsmg_set_color(NEWT_COLORSET_ENTRY);
 
120
 
 
121
    if (en->flags & NEWT_FLAG_HIDDEN) {
 
122
        newtGotorc(co->top, co->left);
 
123
        for (i = 0; i < co->width; i++)
 
124
            SLsmg_write_char('_');
 
125
        newtGotorc(co->top, co->left);
 
126
 
 
127
        return;
 
128
    }
 
129
 
 
130
    newtGotorc(co->top, co->left);
 
131
 
 
132
    if (en->cursorPosition < en->firstChar) {
 
133
        /* scroll to the left */
 
134
        en->firstChar = en->cursorPosition;
 
135
    } else if ((en->firstChar + co->width) <= en->cursorPosition) {
 
136
        /* scroll to the right */
 
137
        en->firstChar = en->cursorPosition - co->width + 1;
 
138
    }
 
139
 
 
140
    chptr = en->buf + en->firstChar;
 
141
 
 
142
    if (en->flags & NEWT_FLAG_PASSWORD) {
 
143
        char *tmpptr, *p;
 
144
 
 
145
        tmpptr = alloca(strlen(chptr+2));
 
146
        strcpy(tmpptr, chptr);
 
147
        for (p = tmpptr; *p; p++)
 
148
            *p = '*';
 
149
        chptr = tmpptr;
 
150
    }                   
 
151
 
 
152
    len = strlen(chptr);
 
153
 
 
154
    if (len <= co->width) {
 
155
        i = len;
 
156
        SLsmg_write_string(chptr);
 
157
        while (i < co->width) {
 
158
            SLsmg_write_char('_');
 
159
            i++;
 
160
        }
 
161
    } else {
 
162
        SLsmg_write_nstring(chptr, co->width);
 
163
    }
 
164
 
 
165
    if (en->flags & NEWT_FLAG_HIDDEN)
 
166
        newtGotorc(co->top, co->left);
 
167
    else
 
168
        newtGotorc(co->top, co->left + (en->cursorPosition - en->firstChar));
 
169
}
 
170
 
 
171
void newtEntrySetFlags(newtComponent co, int flags, enum newtFlagsSense sense) {
 
172
    struct entry * en = co->data;
 
173
    int row, col;
 
174
 
 
175
    en->flags = newtSetFlags(en->flags, flags, sense);
 
176
 
 
177
    if (!(en->flags & NEWT_FLAG_DISABLED))
 
178
        co->takesFocus = 1;
 
179
    else
 
180
        co->takesFocus = 0;
 
181
 
 
182
    newtGetrc(&row, &col);
 
183
    entryDraw(co);
 
184
    newtGotorc(row, col);
 
185
}
 
186
 
 
187
static void entryDestroy(newtComponent co) {
 
188
    struct entry * en = co->data;
 
189
 
 
190
    free(en->buf);
 
191
    free(en);
 
192
    free(co);
 
193
}
 
194
 
 
195
static struct eventResult entryEvent(newtComponent co,
 
196
                                     struct event ev) {
 
197
    struct entry * en = co->data;
 
198
    struct eventResult er;
 
199
    int ch;
 
200
 
 
201
    if (ev.when == EV_NORMAL) {
 
202
        switch (ev.event) {
 
203
        case EV_FOCUS:
 
204
            newtCursorOn();
 
205
            if (en->flags & NEWT_FLAG_HIDDEN)
 
206
                newtGotorc(co->top, co->left);
 
207
            else
 
208
                newtGotorc(co->top, co->left +
 
209
                           (en->cursorPosition - en->firstChar));
 
210
            er.result = ER_SWALLOWED;
 
211
            break;
 
212
 
 
213
        case EV_UNFOCUS:
 
214
            newtCursorOff();
 
215
            newtGotorc(0, 0);
 
216
            er.result = ER_SWALLOWED;
 
217
            if (co->callback)
 
218
                co->callback(co, co->callbackData);
 
219
            break;
 
220
 
 
221
        case EV_KEYPRESS:
 
222
            ch = ev.u.key;
 
223
            if (en->filter)
 
224
                ch = en->filter(co, en->filterData, ch, en->cursorPosition);
 
225
            if (ch) er = entryHandleKey(co, ch);
 
226
            break;
 
227
 
 
228
        case EV_MOUSE:
 
229
            if ((ev.u.mouse.type == MOUSE_BUTTON_DOWN) &&
 
230
                (en->flags ^ NEWT_FLAG_HIDDEN)) {
 
231
                if (strlen(en->buf) >= ev.u.mouse.x - co->left) {
 
232
                    en->cursorPosition = ev.u.mouse.x - co->left;
 
233
                    newtGotorc(co->top,
 
234
                               co->left +(en->cursorPosition - en->firstChar));
 
235
                } else {
 
236
                    en->cursorPosition = strlen(en->buf);
 
237
                    newtGotorc(co->top,
 
238
                               co->left +(en->cursorPosition - en->firstChar));
 
239
                }
 
240
            }
 
241
            break;
 
242
        }
 
243
    } else
 
244
        er.result = ER_IGNORED;
 
245
 
 
246
    return er;
 
247
}
 
248
 
 
249
static struct eventResult entryHandleKey(newtComponent co, int key) {
 
250
    struct entry * en = co->data;
 
251
    struct eventResult er;
 
252
    char * chptr, * insPoint;
 
253
 
 
254
    er.result = ER_SWALLOWED;
 
255
    switch (key) {
 
256
      case '\r':                                /* Return */
 
257
        if (en->flags & NEWT_FLAG_RETURNEXIT) {
 
258
            er.result = ER_EXITFORM;
 
259
        } else {
 
260
            er.result = ER_NEXTCOMP;
 
261
        }
 
262
        break;
 
263
 
 
264
      case '\001':                              /* ^A */
 
265
      case NEWT_KEY_HOME:
 
266
        en->cursorPosition = 0;
 
267
        break;
 
268
 
 
269
      case '\005':                              /* ^E */
 
270
      case NEWT_KEY_END:
 
271
        en->cursorPosition = en->bufUsed;
 
272
        break;
 
273
 
 
274
      case '\013':                              /* ^K */
 
275
        en->bufUsed = en->cursorPosition;
 
276
        memset(en->buf + en->bufUsed, 0, en->bufAlloced - en->bufUsed);
 
277
        break;
 
278
 
 
279
      case '\002':                              /* ^B */
 
280
      case NEWT_KEY_LEFT:
 
281
        if (en->cursorPosition)
 
282
            en->cursorPosition--;
 
283
        break;
 
284
 
 
285
      case '\004':
 
286
      case NEWT_KEY_DELETE:
 
287
        chptr = en->buf + en->cursorPosition;
 
288
        if (*chptr) {
 
289
            chptr++;
 
290
            while (*chptr) {
 
291
                *(chptr - 1) = *chptr;
 
292
                chptr++;
 
293
            }
 
294
            *(chptr - 1) = '\0';
 
295
            en->bufUsed--;
 
296
        }
 
297
        break;
 
298
 
 
299
      case NEWT_KEY_BKSPC:
 
300
        if (en->cursorPosition) {
 
301
            /* if this isn't true, there's nothing to erase */
 
302
            chptr = en->buf + en->cursorPosition;
 
303
            en->bufUsed--;
 
304
            en->cursorPosition--;
 
305
            while (*chptr) {
 
306
                *(chptr - 1) = *chptr;
 
307
                chptr++;
 
308
            }
 
309
            *(chptr - 1) = '\0';
 
310
        }
 
311
        break;
 
312
 
 
313
      case '\006':                              /* ^B */
 
314
      case NEWT_KEY_RIGHT:
 
315
        if (en->cursorPosition < en->bufUsed)
 
316
            en->cursorPosition++;
 
317
        break;
 
318
 
 
319
      default:
 
320
        if ((key >= 0x20 && key <= 0x7e) || (key >= 0xa0 && key <= 0xff)) {
 
321
            if (!(en->flags & NEWT_FLAG_SCROLL) && en->bufUsed >= co->width) {
 
322
                SLtt_beep();
 
323
                break;
 
324
            }
 
325
 
 
326
            if ((en->bufUsed + 1) == en->bufAlloced) {
 
327
                en->bufAlloced += 20;
 
328
                en->buf = realloc(en->buf, en->bufAlloced);
 
329
                if (en->resultPtr) *en->resultPtr = en->buf;
 
330
                memset(en->buf + en->bufUsed + 1, 0, 20);
 
331
            }
 
332
 
 
333
            if (en->cursorPosition == en->bufUsed) {
 
334
                en->bufUsed++;
 
335
            } else {
 
336
                /* insert the new character */
 
337
 
 
338
                /* chptr is the last character in the string */
 
339
                chptr = (en->buf + en->bufUsed) - 1;
 
340
                if ((en->bufUsed + 1) == en->bufAlloced) {
 
341
                    /* this string fills the buffer, so clip it */
 
342
                    chptr--;
 
343
                } else
 
344
                    en->bufUsed++;
 
345
 
 
346
                insPoint = en->buf + en->cursorPosition;
 
347
 
 
348
                while (chptr >= insPoint) {
 
349
                    *(chptr + 1) = *chptr;
 
350
                    chptr--;
 
351
                }
 
352
 
 
353
            }
 
354
 
 
355
            en->buf[en->cursorPosition++] = key;
 
356
        } else {
 
357
            er.result = ER_IGNORED;
 
358
        }
 
359
    }
 
360
 
 
361
    entryDraw(co);
 
362
 
 
363
    return er;
 
364
}
 
365
 
 
366
char * newtEntryGetValue(newtComponent co) {
 
367
    struct entry * en = co->data;
 
368
 
 
369
    return en->buf;
 
370
}
 
371
 
 
372
void newtEntrySetFilter(newtComponent co, newtEntryFilter filter, void * data) {
 
373
    struct entry * en = co->data;
 
374
    en->filter = filter;
 
375
    en->filterData = data;
 
376
}