File: edline.c

package info (click to toggle)
alevt 1%3A1.5.1-4
  • links: PTS
  • area: main
  • in suites: potato
  • size: 616 kB
  • ctags: 632
  • sloc: ansic: 6,216; makefile: 141; perl: 104; sh: 16
file content (156 lines) | stat: -rw-r--r-- 2,674 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <stdlib.h>
#include <string.h>
#include "vt.h"
#include "misc.h"
#include "xio.h"
#include "edline.h"

static void
do_exit(struct edline *el, u8 *buf)
{
    xio_set_cursor(el->xw, 999, 999);
    xio_set_handler(el->xw, el->old_handler, el->old_data);
    el->exit_func(el->exit_data, buf);
    free(el);
}

static void
redraw(struct edline *el)
{
    u8 buf[40];
    u8 *p;
    int l;

    p = el->buf;
    l = el->len;

    if (l > 39 - el->plen)
    {
	l = 39 - el->plen;
	p = el->buf + el->len - l;
    }

    memset(buf, ' ', sizeof(buf));
    memcpy(buf, el->prompt, el->plen);
    memcpy(buf + el->plen, p, l);

    xio_set_cursor(el->xw, el->plen + l, 24);
    xio_put_line(el->xw, 24, buf);
}

static void
ev_handler(struct edline *el, struct vt_event *ev)
{
    switch (ev->type)
    {
	case EV_KEY:
	    switch (ev->i1)
	    {
		case '\e':
		case '\3':
		    do_exit(el, 0);
		    return;
		case '\r':
		case '\n':
		    el->buf[el->len] = 0;
		    do_exit(el, el->buf);
		    return;
		case KEY_INS:
		    xio_query_selection(el->xw);
		    return;
		case KEY_LEFT:
		case '\b':
		    if (el->len)
		    {
			el->len--;
			redraw(el);
		    }
		    else
			do_exit(el, 0);
		    return;
		case 0x20 ... 0x7e:
		case 0xa0 ... 0xff:
		    if (el->len < (int)sizeof(el->buf)-1)
		    {
			el->buf[el->len++] = ev->i1;
			redraw(el);
			return;
		    }
		    break;
	    }
	    xio_bell(el->xw);
	    return;
	case EV_SELECTION:
	{
	    u8 *p = ev->p1;
	    int n = ev->i1;

	    while (n-- && el->len < (int)sizeof(el->buf)-1)
	    {
		if (*p >= 0x20 && *p <= 0x7e || *p >= 0xa0 && *p <= 0xff)
		    el->buf[el->len++] = *p;
		p++;
	    }
	    redraw(el);
	    return;
	}
	case EV_MOUSE:
	    if (ev->i4 == 24)
	    {
		if (ev->i1 == 2)
		    xio_query_selection(el->xw);
		else
		    xio_bell(el->xw);
		return;
	    }
	    break;
    }
    el->old_handler(el->old_data, ev);
}




struct edline *
edline_new(struct xio_win *xw, u8 *prompt, u8 *str, void *exit_func, void *data)
{
    struct edline *el;
    int plen, slen;

    if ((plen = strlen(prompt)) > 20)
	goto fail1;
    if ((slen = strlen(str)) > (int)sizeof(el->buf) - 1)
	goto fail1;

    if (not(el = malloc(sizeof(*el))))
	goto fail1;

    el->xw = xw;
    el->prompt = prompt;
    el->exit_func = exit_func;
    el->exit_data = data;

    el->old_handler = xw->handler;	//TODO: func to retrieve curr handler
    el->old_data = xw->data;
    xio_set_handler(el->xw, ev_handler, el);

    el->plen = plen;
    el->len = slen;
    strcpy(el->buf, str);

    redraw(el);
    return el;


fail2:
    free(el);
fail1:
    return 0;
}


void
edline_abort(struct edline *el)
{
    do_exit(el, 0);
}