~ubuntu-branches/ubuntu/gutsy/alevt/gutsy

« back to all changes in this revision

Viewing changes to edit.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Schoepf
  • Date: 2002-03-17 15:09:36 UTC
  • Revision ID: james.westby@ubuntu.com-20020317150936-yglzziwcc0luz55k
Tags: upstream-1.6.0
ImportĀ upstreamĀ versionĀ 1.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include "vt.h"
 
5
#include "misc.h"
 
6
#include "xio.h"
 
7
#include "vbi.h"
 
8
#include "edit.h"
 
9
 
 
10
static void edwin_event(struct edwin *w, struct vt_event *ev);
 
11
 
 
12
static void
 
13
cursor(struct edwin *w, int x, int y)
 
14
{
 
15
    u8 buf0[40];
 
16
    u8 buf1[40];
 
17
    u8 buf2[32];
 
18
 
 
19
    if (w->edline)
 
20
        return;
 
21
    if (x < 0 || x >= W || y < 0 || y >= H)
 
22
        return;
 
23
    if (y == 0 && x < 8)
 
24
        return;
 
25
 
 
26
    xio_get_line(w->xw, 0, buf0);
 
27
    xio_get_line(w->xw, y, buf1);
 
28
 
 
29
    sprintf(buf2, "%2d\3%02x  \7    ", y, buf1[x]);
 
30
    buf2[6] = "CI"[w->mode];
 
31
    memcpy(buf0, buf2, 8);
 
32
 
 
33
    xio_put_line(w->xw, 0, buf0);
 
34
    xio_set_cursor(w->xw, w->x = x, w->y = y);
 
35
}
 
36
 
 
37
static void
 
38
adv_cursor(struct edwin *w)
 
39
{
 
40
    if (w->x < W-1)
 
41
        cursor(w, w->x+1, w->y);
 
42
    else if (w->y < H-1)
 
43
        cursor(w, 0, w->y+1);
 
44
    else
 
45
        cursor(w, 8, 0);
 
46
}
 
47
 
 
48
static void
 
49
set_char(struct edwin *w, int c)
 
50
{
 
51
    u8 buf[40];
 
52
 
 
53
    xio_get_line(w->xw, w->y, buf);
 
54
    buf[w->x] = c;
 
55
    xio_put_line(w->xw, w->y, buf);
 
56
}
 
57
 
 
58
static int
 
59
get_char(struct edwin *w)
 
60
{
 
61
    u8 buf[40];
 
62
 
 
63
    xio_get_line(w->xw, w->y, buf);
 
64
    return buf[w->x];
 
65
}
 
66
 
 
67
static void
 
68
set_gfx(struct edwin *w, int i)
 
69
{
 
70
    int c = get_char(w);
 
71
 
 
72
    if ((c & 0xa0) != 0x20)
 
73
        c = 0x20;
 
74
    switch (i)
 
75
    {
 
76
        case 1: c ^= 0x10;      break;
 
77
        case 2: c ^= 0x40;      break;
 
78
        case 4: c ^= 0x04;      break;
 
79
        case 5: c ^= 0x08;      break;
 
80
        case 7: c ^= 0x01;      break;
 
81
        case 8: c ^= 0x02;      break;
 
82
        case 0: c = 0x20;       break;
 
83
        case 9: c = 0x7f;       break;
 
84
        case 3: c ^= 0x5f;      break;
 
85
        case 6: c ^= 0x5f;      break;
 
86
    }
 
87
    set_char(w, c);
 
88
}
 
89
 
 
90
static void
 
91
set_mode(struct edwin *w, int on, int off)
 
92
{
 
93
    u8 buf[40];
 
94
    int x, c;
 
95
 
 
96
    xio_get_line(w->xw, w->y, buf);
 
97
 
 
98
    for (c = x = 0; x <= w->x; ++x)
 
99
        if (buf[x] == on || buf[x] == off)
 
100
            c = buf[x];
 
101
    if (c == on)
 
102
        set_char(w, off);
 
103
    else
 
104
        set_char(w, on);
 
105
}
 
106
 
 
107
static void
 
108
del_char(struct edwin *w)
 
109
{
 
110
    u8 buf[40];
 
111
    int x;
 
112
 
 
113
    xio_get_line(w->xw, w->y, buf);
 
114
    for (x = w->x; x < W-1; ++x)
 
115
        buf[x] = buf[x+1];
 
116
    buf[x] = ' ';
 
117
    xio_put_line(w->xw, w->y, buf);
 
118
}
 
119
 
 
120
static void
 
121
ins_char(struct edwin *w, int c)
 
122
{
 
123
    u8 buf[40];
 
124
    int x, t;
 
125
 
 
126
    xio_get_line(w->xw, w->y, buf);
 
127
    for (x = w->x; x < W; ++x)
 
128
        t = buf[x], buf[x] = c, c = t;
 
129
    xio_put_line(w->xw, w->y, buf);
 
130
}
 
131
 
 
132
static void
 
133
del_line(struct edwin *w)
 
134
{
 
135
    u8 buf[40];
 
136
    int y;
 
137
    
 
138
    for (y = w->y; y < H-1; ++y)
 
139
    {
 
140
        xio_get_line(w->xw, y+1, buf);
 
141
        xio_put_line(w->xw, y, buf);
 
142
    }
 
143
}
 
144
 
 
145
static void
 
146
ins_line(struct edwin *w)
 
147
{
 
148
    u8 buf[40];
 
149
    u8 buf2[40];
 
150
    int y;
 
151
    
 
152
    memset(buf2, ' ', sizeof(buf2));
 
153
    for (y = w->y; y < H; ++y)
 
154
    {
 
155
        xio_get_line(w->xw, y, buf);
 
156
        xio_put_line(w->xw, y, buf2);
 
157
        memcpy(buf2, buf, sizeof(buf2));
 
158
    }
 
159
}
 
160
 
 
161
 
 
162
static void
 
163
do_save(struct edwin *w, u8 *name)
 
164
{
 
165
    u8 buf[40];
 
166
    int x, y;
 
167
    FILE *fp;
 
168
 
 
169
    w->edline = 0;
 
170
    xio_put_line(w->xw, 24, w->tmpbuf);
 
171
    cursor(w, w->x, w->y);
 
172
 
 
173
    if (name == 0 || *name == 0)
 
174
        return;
 
175
 
 
176
    fp = fopen(name, "w");
 
177
    if (fp == 0)
 
178
    {
 
179
        ioerror(name);
 
180
        return;
 
181
    }
 
182
    for (y = 0; y < 25; ++y)
 
183
    {
 
184
        xio_get_line(w->xw, y, buf);
 
185
        if (y == 0)
 
186
            memset(buf, ' ', 8);
 
187
        if (y == 0)
 
188
            fprintf(fp, "#ifndef HELP_HEADER\n");
 
189
        if (y == 5)
 
190
            fprintf(fp, "#else\nHELP_HEADER\n#endif\n");
 
191
        fprintf(fp, "\"");
 
192
        for (x = 0; x < 40; ++x)
 
193
            if ((buf[x] & 0x7f) < 0x20 || buf[x] == 0x7f || buf[x] == '"')
 
194
            {
 
195
                if (x == 39 || buf[x+1] < '0' || buf[x+1] > '9')
 
196
                    fprintf(fp, "\\%o", buf[x]);
 
197
                else
 
198
                    fprintf(fp, "\\%03o", buf[x]);
 
199
            }
 
200
            else
 
201
                fprintf(fp, "%c", buf[x]);
 
202
        fprintf(fp, "\",\n");
 
203
    }
 
204
    fclose(fp);
 
205
    error("%s dumped", name);
 
206
}
 
207
 
 
208
static void
 
209
save(struct edwin *w)
 
210
{
 
211
    u8 name[64];
 
212
 
 
213
    if (w->subno == ANY_SUB)
 
214
        sprintf(name, "vt%03x.out", w->pgno);
 
215
    else
 
216
        sprintf(name, "vt%03x-%02x.out", w->pgno, w->subno & 0xff);
 
217
 
 
218
    xio_get_line(w->xw, 24, w->tmpbuf);
 
219
    w->edline = edline_new(w->xw, "Save as:\2", name, do_save, w);
 
220
}
 
221
 
 
222
 
 
223
struct edwin *
 
224
edwin_new(struct xio *xio, struct vbi *vbi, int pgno, int subno)
 
225
{
 
226
    struct edwin *w;
 
227
    struct vt_page *vtp;
 
228
    u8 buf[64];
 
229
    int i;
 
230
 
 
231
    if (not(w = malloc(sizeof(*w))))
 
232
        goto fail1;
 
233
 
 
234
    if (not(w->xw = xio_open_win(xio, 0)))
 
235
        goto fail2;
 
236
 
 
237
    w->pgno = pgno;
 
238
    w->subno = subno;
 
239
 
 
240
    vtp = vbi_query_page(vbi, pgno, subno);
 
241
    if (vtp)
 
242
        for (i = 0; i < 25; ++i)
 
243
            xio_put_line(w->xw, i, vtp->data[i]);
 
244
    else
 
245
        xio_clear_win(w->xw);
 
246
    
 
247
    w->mode = 1;
 
248
    w->edline = 0;
 
249
    if (w->subno == ANY_SUB)
 
250
        sprintf(buf, "Editor %03x", w->pgno);
 
251
    else
 
252
        sprintf(buf, "Editor %03x/%x", w->pgno, w->subno);
 
253
    xio_title(w->xw, buf);
 
254
    xio_set_concealed(w->xw, w->reveal = 1);
 
255
    xio_set_handler(w->xw, edwin_event, w);
 
256
    cursor(w, W/2, H/2);
 
257
    return w;
 
258
 
 
259
fail2:
 
260
    free(w);
 
261
fail1:
 
262
    return 0;
 
263
}
 
264
 
 
265
static void
 
266
edwin_close(struct edwin *w)
 
267
{
 
268
    if (w->edline)
 
269
        edline_abort(w->edline);
 
270
    xio_close_win(w->xw, 1);
 
271
    free(w);
 
272
}
 
273
 
 
274
static int
 
275
ins_key(struct edwin *w, int key, int shift)
 
276
{
 
277
    switch (key)
 
278
    {
 
279
        case '\17': /* ^O for the bullet */
 
280
            key = 0x7f;
 
281
            // fall through
 
282
        case 0x20 ... 0x7e:
 
283
        case 0xa0 ... 0xff:
 
284
            set_char(w, key);
 
285
            adv_cursor(w);
 
286
            return 1;
 
287
        case '\t':
 
288
            w->mode = 0;
 
289
            return 2;
 
290
    }
 
291
    return 0;
 
292
}
 
293
 
 
294
static int
 
295
cmd_key(struct edwin *w, int key, int shift)
 
296
{
 
297
    switch (key)
 
298
    {
 
299
        case '\e':
 
300
        case 'q':               edwin_close(w);                 return 1;
 
301
        case '\r':
 
302
        case '\n':              w->x = W; adv_cursor(w);        return 1;
 
303
        case '\t':              w->mode = 1;                    return 2;
 
304
        case KEY_F(1):          save(w);                        return 1;
 
305
 
 
306
        case KEY_INS:
 
307
            if (shift)
 
308
                ins_line(w);
 
309
            else
 
310
                ins_char(w, ' ');
 
311
            return 2;
 
312
 
 
313
        case '\b':
 
314
            if (shift || w->x == 0)
 
315
                return 0;
 
316
            w->x--;
 
317
            //fall through
 
318
        case 0x7f:
 
319
        case KEY_DEL:
 
320
            if (shift)
 
321
                del_line(w);
 
322
            else
 
323
                del_char(w);
 
324
            return 2;
 
325
 
 
326
        case KEY_LEFT:          cursor(w, w->x - 1, w->y);      return 1;
 
327
        case KEY_RIGHT:         cursor(w, w->x + 1, w->y);      return 1;
 
328
        case KEY_UP:            cursor(w, w->x, w->y - 1);      return 1;
 
329
        case KEY_DOWN:          cursor(w, w->x, w->y + 1);      return 1;
 
330
 
 
331
        case 'k': /*black*/     set_char(w, 0x00);              return 2;
 
332
        case 'K':               set_char(w, 0x10);              return 2;
 
333
        case 'r': /*red*/       set_char(w, 0x01);              return 2;
 
334
        case 'R':               set_char(w, 0x11);              return 2;
 
335
        case 'g': /*green*/     set_char(w, 0x02);              return 2;
 
336
        case 'G':               set_char(w, 0x12);              return 2;
 
337
        case 'y': /*yellow*/    set_char(w, 0x03);              return 2;
 
338
        case 'Y':               set_char(w, 0x13);              return 2;
 
339
        case 'b': /*blue*/      set_char(w, 0x04);              return 2;
 
340
        case 'B':               set_char(w, 0x14);              return 2;
 
341
        case 'v': /*violet*/    set_char(w, 0x05);              return 2;
 
342
        case 'V':               set_char(w, 0x15);              return 2;
 
343
        case 'c': /*cyan*/      set_char(w, 0x06);              return 2;
 
344
        case 'C':               set_char(w, 0x16);              return 2;
 
345
        case 'w': /*white*/     set_char(w, 0x07);              return 2;
 
346
        case 'W':               set_char(w, 0x17);              return 2;
 
347
 
 
348
        case 's': /*new bg*/    set_char(w, 0x1d);              return 2;
 
349
        case 'S': /*blk bg*/    set_char(w, 0x1c);              return 2;
 
350
        case 'e': /*concealed*/ set_char(w, 0x18);              return 2;
 
351
        case 'E': xio_set_concealed(w->xw, w->reveal ^= 1);     return 1;
 
352
 
 
353
        case '0' ... '9':       set_gfx(w, key - '0');          return 2;
 
354
 
 
355
        case 'f': /*flash*/     set_mode(w, 0x08, 0x09);        return 2;
 
356
        case 'd': /*dbl*/       set_mode(w, 0x0d, 0x0c);        return 2;
 
357
        case 'h': /*hold gfx*/  set_mode(w, 0x1e, 0x1f);        return 2;
 
358
        case 'x': /*box*/       set_mode(w, 0x0b, 0x0a);        return 2;
 
359
 
 
360
        case ' ':
 
361
            set_char(w, key);
 
362
            return 2;
 
363
    }
 
364
    return 0;
 
365
}
 
366
 
 
367
static void
 
368
edwin_event(struct edwin *w, struct vt_event *ev)
 
369
{
 
370
    int i;
 
371
 
 
372
    switch (ev->type)
 
373
    {
 
374
        case EV_CLOSE:
 
375
            edwin_close(w);
 
376
            break;
 
377
 
 
378
        case EV_KEY:
 
379
            i = 0;
 
380
            if (w->mode == 1)
 
381
                i = ins_key(w, ev->i1, ev->i2);
 
382
            if (not i)
 
383
                i |= cmd_key(w, ev->i1, ev->i2);
 
384
            if (i & 2)
 
385
                cursor(w, w->x, w->y);
 
386
            if (i == 0)
 
387
                xio_bell(w->xw);
 
388
            break;
 
389
 
 
390
        case EV_MOUSE:
 
391
            cursor(w, ev->i3, ev->i4);
 
392
            break;
 
393
    }
 
394
}