~ubuntu-branches/ubuntu/feisty/minicom/feisty

« back to all changes in this revision

Viewing changes to src/window.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin A. Godisch
  • Date: 2006-10-27 05:41:23 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061027054123-9cyfsdx649zetdrv
Tags: 2.2-3
* Added upstream NEWS file, closes: #394827.
* Fixed spelling errors, closes: #395449.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#endif
20
20
 
21
21
#include "rcsid.h"
22
 
RCSID("$Id: window.c,v 1.3 2003/04/21 23:56:46 al-guest Exp $")
 
22
RCSID("$Id: window.c,v 1.18 2005/11/06 19:20:57 al-guest Exp $")
 
23
 
 
24
#include <limits.h>
 
25
#include <stdarg.h>
 
26
#include <wchar.h>
23
27
 
24
28
#include "port.h"
25
 
#include "window.h"
26
 
#include "charmap.h"
 
29
#include "minicom.h"
27
30
#include "intl.h"
28
31
 
29
32
/* Status line code on/off. */
36
39
#endif
37
40
 
38
41
/* Don't want to include all header stuff for three prototypes from sysdep.c */
39
 
#if __STDC__
 
42
#ifdef __STDC__
40
43
  int setcbreak(int);
41
44
  int wxgetch(void);
42
45
  void getrowcols(int *rows, int *cols);
55
58
#define swap(x, y) { int d = (x); (x) = (y); (y) = d; }
56
59
 
57
60
/* Terminal capabilities */
58
 
static char *CM, *IS, *RS, *AC, *EA;
59
 
static char *ME, *SE, *UE, *AE;
60
 
static char *AS, *MB, *MD, *MR, *SO, *US;
61
 
static char *CE, *Al, *Dl, *AL, *DL;
62
 
static char *CS, *SF, *SR, *VB, *BL;
63
 
static char *VE, *VI, *KS, *KE;
64
 
static char *CD, *CL, *IC, *DC;
65
 
static char *BC, *CR, *NL;
66
 
#if ST_LINE
67
 
static char *TS, *FS, *DS;
 
61
static const char *CM, *IS, *RS, *AC, *EA;
 
62
static const char *ME, *SE, *UE, *AE;
 
63
static const char *AS, *MB, *MD, *MR, *SO, *US;
 
64
static const char *CE, *Al, *Dl, *AL, *DL;
 
65
static const char *CS, *SF, *SR, *VB, *BL;
 
66
static const char *VE, *VI, *KS, *KE;
 
67
static const char *CD, *CL, *IC, *DC;
 
68
static const char *CR, *NL;
 
69
#ifdef ST_LINE
 
70
static const char *TS, *FS, *DS;
68
71
#endif
69
72
 
70
73
/* Special characters */
104
107
 * and the output will look much less 'jerky'. (I hope :-)
105
108
 */
106
109
#ifdef SMOOTH
107
 
static WIN *curwin = NIL_WIN;
108
 
extern WIN *us;
 
110
static WIN *curwin = NULL;
 
111
WIN *us;
109
112
#endif
110
113
 
111
114
int useattr = 1;
112
115
int dirflush = 1;
113
 
extern int LINES, COLS;
 
116
int LINES, COLS;
114
117
int usecolor = 0;
115
118
WIN *stdwin;
116
 
char *_tptr = CNULL;
 
119
/*
 
120
 * The following is an external pointer to the termcap info.
 
121
 * If it's NOT zero then the main program has already
 
122
 * read the termcap for us. No sense in doing it twice.
 
123
 */
 
124
char *_tptr = NULL;
117
125
int screen_ibmpc = 0;
118
126
int screen_iso = 0;
119
127
int w_init = 0;
120
 
#if ST_LINE
121
128
int use_status = 0; /* Turned on in main() */
122
 
#else
123
 
int use_status = 0;
124
 
#endif
125
129
 
126
130
/* Standard vt100 map (ac cpability) */
127
 
static char *def_ac = "+\273,\253aaffggjjkkllmmnnooqqssttuuvvwwxx";
 
131
static const char *def_ac = "+\273,\253aaffggjjkkllmmnnooqqssttuuvvwwxx";
128
132
 
129
 
#if DEBUG
 
133
#ifdef DEBUG
130
134
 
131
135
/*
132
136
 * Debug to stdout
133
137
 */
134
 
int debug(s, a1, a2, a3, a4)
135
 
char *s;
136
 
int a1, a2, a3, a4;
 
138
int debug(char *s, ...)
137
139
{
138
140
  char lala[80];
 
141
  va_list ap;
139
142
 
140
 
  snprintf(lala, sizeof(lala), s, a1, a2, a3, a4);
 
143
  va_start(ap, s);
 
144
  vsnprintf(lala, sizeof(lala), s, ap);
 
145
  va_end(ap);
141
146
  write(2, lala, strlen(lala));
142
 
  return(0);
 
147
  return 0;
143
148
}
144
149
#endif
145
150
 
148
153
/*
149
154
 * Flush the screen buffer
150
155
 */
151
 
void wflush()
 
156
void wflush(void)
152
157
{
153
158
  int todo, done;
154
159
 
155
160
  todo = _bufpos - _bufstart;
156
161
  _bufpos = _bufstart;
157
162
 
158
 
  while(todo > 0) {
159
 
        done = write(1, _bufpos, todo);
160
 
        if (done > 0) {
161
 
                todo -= done;
162
 
                _bufpos += done;
163
 
        }
164
 
        if (done < 0 && errno != EINTR) break;
 
163
  while (todo > 0) {
 
164
    done = write(1, _bufpos, todo);
 
165
    if (done > 0) {
 
166
      todo -= done;
 
167
      _bufpos += done;
 
168
    }
 
169
    if (done < 0 && errno != EINTR)
 
170
      break;
165
171
  }
166
172
  _bufpos = _bufstart;
167
173
}
169
175
/*
170
176
 * Output a raw character to the screen
171
177
 */
172
 
static int outchar(c)
173
 
int c;
 
178
static int outchar(int c)
174
179
{
175
180
  *_bufpos++ = c;
176
 
  if (_bufpos >= _buffend) wflush();
 
181
  if (_bufpos >= _buffend)
 
182
    wflush();
177
183
#if defined(SMOOTH)
178
 
  if (curwin == us && (c == '\n' || c == '\r')) wflush();
 
184
  if (curwin == us && (c == '\n' || c == '\r'))
 
185
    wflush();
179
186
#endif
180
 
  return(0);
 
187
  return 0;
181
188
}
182
189
 
183
190
/*
184
191
 * Output a raw string to the screen.
185
192
 */
186
 
static void outstr(s)
187
 
char *s;
 
193
static void outstr(const char *s)
188
194
{
189
195
  tputs(s, 1, outchar);
190
196
}
193
199
/*
194
200
 * Turn off all attributes
195
201
 */
196
 
static void _attroff()
 
202
static void _attroff(void)
197
203
{
198
 
  if (ME != CNULL)
199
 
        outstr(ME);
 
204
  if (ME != NULL)
 
205
    outstr(ME);
200
206
  else {
201
 
        if (SE != CNULL) outstr(SE);
202
 
        if (UE != CNULL) outstr(UE);
 
207
    if (SE != NULL)
 
208
      outstr(SE);
 
209
    if (UE != NULL)
 
210
      outstr(UE);
203
211
  }
204
 
  if (AE != CNULL) outstr(AE);
 
212
  if (AE != NULL)
 
213
    outstr(AE);
205
214
}
206
215
 
207
216
/*
208
217
 * Turn some attributes on
209
218
 */
210
 
static void _attron(attr)
211
 
char attr;
 
219
static void _attron(char attr)
212
220
{
213
221
  if (!usecolor || (attr & XA_REVERSE) == 0) {
214
 
        /* Reverse standout does not look too good.. */
215
 
        if (attr & XA_BOLD      && MD != CNULL)  outstr(MD);
216
 
        if (attr & XA_STANDOUT   && SO != CNULL)  outstr(SO);
217
 
        if (attr & XA_UNDERLINE  && US != CNULL)  outstr(US);
 
222
    /* Reverse standout does not look too good.. */
 
223
    if (attr & XA_BOLD  && MD != NULL)
 
224
      outstr(MD);
 
225
    if (attr & XA_STANDOUT && SO != NULL)
 
226
      outstr(SO);
 
227
    if (attr & XA_UNDERLINE && US != NULL)
 
228
      outstr(US);
218
229
  }
219
 
  if (attr & XA_REVERSE   && MR != CNULL)  outstr(MR);
220
 
  if (attr & XA_BLINK      && MB != CNULL)  outstr(MB);
221
 
  if (attr & XA_ALTCHARSET && AS != CNULL)  outstr(AS);
 
230
  if (attr & XA_REVERSE && MR != NULL)
 
231
    outstr(MR);
 
232
  if (attr & XA_BLINK && MB != NULL)
 
233
    outstr(MB);
 
234
  if (attr & XA_ALTCHARSET && AS != NULL)
 
235
    outstr(AS);
222
236
}
223
237
 
224
238
/*
225
239
 * Set the colors
226
240
 */
227
 
static void _colson(color)
228
 
char color;
 
241
static void _colson(char color)
229
242
{
230
243
  char buf[12];
231
244
  sprintf(buf, "\033[%d;%dm", COLFG(color) + 30, COLBG(color) + 40);
232
245
  outstr(buf);
233
246
}
234
 
  
 
247
 
235
248
/*
236
249
 * Set global attributes, if different.
237
250
 */
238
 
static void _setattr(attr, color)
239
 
char attr, color;
 
251
static void _setattr(char attr, char color)
240
252
{
241
 
  if (!useattr) return;
 
253
  if (!useattr)
 
254
    return;
242
255
 
243
256
  if (!usecolor) {
244
 
        curcolor = color;
245
 
        if (attr == curattr) return;
246
 
        curattr = attr;
247
 
        _attroff();
248
 
        _attron(attr);
249
 
        return;
 
257
    curcolor = color;
 
258
    if (attr == curattr)
 
259
      return;
 
260
    curattr = attr;
 
261
    _attroff();
 
262
    _attron(attr);
 
263
    return;
250
264
  }
251
 
  if (attr == curattr && color == curcolor) return;
 
265
  if (attr == curattr && color == curcolor)
 
266
    return;
252
267
  _attroff();
253
268
  _colson(color);
254
269
  _attron(attr);
259
274
/*
260
275
 * Goto (x, y) in stdwin
261
276
 */
262
 
static void _gotoxy(x, y)
263
 
int x, y;
 
277
static void _gotoxy(int x, int y)
264
278
{
265
279
  int oldattr = -1;
266
280
 
267
 
#if ST_LINE
 
281
#ifdef ST_LINE
268
282
  int tmp;
269
283
 
270
284
  /* Sanity check. */
271
 
  if (x >= COLS || y > LINES || (x == curx && y == cury)) return;
 
285
  if (x >= COLS || y > LINES || (x == curx && y == cury))
 
286
    return;
272
287
 
273
288
  if (use_status) {
274
 
        /* Leaving status line? */
275
 
        if (cury == LINES && y < cury) {
276
 
                outstr(FS);
277
 
                /* Re-set attributes. */
278
 
                tmp = curattr;
279
 
                curattr = -1;
280
 
                _setattr(tmp, curcolor);
281
 
                outstr(tgoto(CM, x, y));
282
 
                curx = x; cury = y;
283
 
                return;
284
 
        }
285
 
        /* Writing on status line? */
286
 
        else if (y == LINES) {
287
 
                /* From normal screen? */
288
 
                if (cury < y) {
289
 
                        outstr(tgoto(TS, x, x));
290
 
                        curx = x;
291
 
                        cury = y;
292
 
                        /* Set the right attributes. */
293
 
                        tmp = curattr;
294
 
                        curattr = -1;
295
 
                        _setattr(tmp, curcolor);
296
 
                        return;
297
 
                }
298
 
        }
 
289
    /* Leaving status line? */
 
290
    if (cury == LINES && y < cury) {
 
291
      outstr(FS);
 
292
      /* Re-set attributes. */
 
293
      tmp = curattr;
 
294
      curattr = -1;
 
295
      _setattr(tmp, curcolor);
 
296
      outstr(tgoto(CM, x, y));
 
297
      curx = x; cury = y;
 
298
      return;
 
299
    }
 
300
    /* Writing on status line? */
 
301
    else if (y == LINES) {
 
302
      /* From normal screen? */
 
303
      if (cury < y) {
 
304
        outstr(tgoto(TS, x, x));
 
305
        curx = x;
 
306
        cury = y;
 
307
        /* Set the right attributes. */
 
308
        tmp = curattr;
 
309
        curattr = -1;
 
310
        _setattr(tmp, curcolor);
 
311
        return;
 
312
      }
 
313
    }
299
314
  }
300
315
#else
301
316
  /* Sanity check. */
302
317
  if (x >= COLS || y >= LINES || (x == curx && y == cury)) {
303
318
#  if 0
304
 
        if (x >= COLS || y >= LINES)
305
 
                fprintf(stderr, "OOPS: (x, y) == (%d, %d)\n",
306
 
                        COLS, LINES);
 
319
    if (x >= COLS || y >= LINES)
 
320
      fprintf(stderr, "OOPS: (x, y) == (%d, %d)\n",
 
321
          COLS, LINES);
307
322
#  endif
308
 
        return;
 
323
    return;
309
324
  }
310
325
#endif
311
326
 
312
327
  if (!_mv_standout && curattr != XA_NORMAL) {
313
 
        oldattr = curattr;
314
 
        _setattr(XA_NORMAL, curcolor);
 
328
    oldattr = curattr;
 
329
    _setattr(XA_NORMAL, curcolor);
315
330
  }
316
 
  if (CR != CNULL && y == cury && x == 0)
317
 
        outstr(CR);
 
331
  if (CR != NULL && y == cury && x == 0)
 
332
    outstr(CR);
318
333
#if 0 /* Hmm, sometimes NL only works in the first column */
319
 
  else if (NL != CNULL && x == curx && y == cury + 1)
320
 
        outstr(NL);
 
334
  else if (NL != NULL && x == curx && y == cury + 1)
 
335
    outstr(NL);
321
336
#else
322
 
  else if (NL != CNULL && x == 0 && x == curx && y == cury + 1)
323
 
        outstr(NL);
 
337
  else if (NL != NULL && x == 0 && x == curx && y == cury + 1)
 
338
    outstr(NL);
324
339
#endif
325
 
  else if (BC != CNULL && y == cury && x == curx - 1)
326
 
        outstr(BC);
327
 
  else  
328
 
        outstr(tgoto(CM, x, y));
 
340
  else if (BC != NULL && y == cury && x == curx - 1)
 
341
    outstr(BC);
 
342
  else
 
343
    outstr(tgoto(CM, x, y));
329
344
  curx = x;
330
345
  cury = y;
331
 
  if (oldattr != -1) _setattr(oldattr, curcolor);
 
346
  if (oldattr != -1)
 
347
    _setattr(oldattr, curcolor);
332
348
}
333
349
 
334
350
/*
337
353
 *                 0: only write to memory, not to screen
338
354
 *                 1: write to both screen and memory
339
355
 */
340
 
static void _write(c, doit, x, y,attr, color)
341
 
int c, doit;
342
 
int x, y;
343
 
char attr, color;
 
356
static void _write(wchar_t c, int doit, int x, int y, char attr, char color)
344
357
{
345
358
  ELM *e;
346
359
 
349
362
   * character is automatically restored.
350
363
   */
351
364
  if (_has_am && y >= LINES - 1 && x >= COLS - 1) {
352
 
        doit = 0;
353
 
        sflag = 1;
354
 
        oldc.value = c;
355
 
        oldc.attr = attr;
356
 
        oldc.color = color;
 
365
    doit = 0;
 
366
    sflag = 1;
 
367
    oldc.value = c;
 
368
    oldc.attr = attr;
 
369
    oldc.color = color;
357
370
  }
358
 
#if ST_LINE
359
 
  if (x < COLS && y <= LINES) {
 
371
#ifdef ST_LINE
 
372
  if (x < COLS && y <= LINES)
360
373
#else
361
 
  if (x < COLS && y < LINES) {
 
374
  if (x < COLS && y < LINES)
362
375
#endif
363
 
     if (doit != 0) {
364
 
        static int x0=-1, y0=-1, c0=0;
365
 
        static char attr0, color0;
366
 
        if (x!=x0+1 || y!=y0 || attr!=attr0 || color!=color0 || !(c0&128)) {
367
 
                _gotoxy(x, y);
368
 
                _setattr(attr, color);
369
 
        }
370
 
        x0=x; y0=y; attr0=attr; color0=color; c0=c;
371
 
        (void) outchar((screen_ibmpc || screen_iso || (attr & XA_ALTCHARSET)) ? c : wcharmap[(unsigned char)c]); 
372
 
        /* a little test at 10.3.1998 / jl */
373
 
        /* (void) outchar((unsigned char) c); */
374
 
 
375
 
        curx++;
376
 
     }
377
 
     if (doit >= 0) {
378
 
        e = &gmap[x + y * COLS];
379
 
        e->value = c;
380
 
        e->attr = attr;
381
 
        e->color = color;
382
 
     }
 
376
  {
 
377
    if (doit != 0) {
 
378
      static int x0 = -1, y0 = -1, c0 = 0;
 
379
      static char attr0, color0;
 
380
      if (x!=x0+1 || y!=y0 || attr!=attr0 || color!=color0 || !(c0&128)) {
 
381
        _gotoxy(x, y);
 
382
        _setattr(attr, color);
 
383
      }
 
384
      x0 = x; y0 = y; attr0 = attr; color0 = color; c0 = c;
 
385
      if ((attr & XA_ALTCHARSET) != 0)
 
386
        outchar((char)c);
 
387
      else {
 
388
        char buf[MB_LEN_MAX];
 
389
        size_t i, len;
 
390
 
 
391
        len = one_wctomb(buf, c);
 
392
        for (i = 0; i < (size_t)len; i++)
 
393
        outchar(buf[i]);
 
394
      }
 
395
 
 
396
      curx++;
 
397
    }
 
398
    if (doit >= 0) {
 
399
      e = &gmap[x + y * COLS];
 
400
      e->value = c;
 
401
      e->attr = attr;
 
402
      e->color = color;
 
403
    }
383
404
  }
384
405
}
385
406
 
386
407
/*
387
408
 * Set cursor type.
388
409
 */
389
 
static void _cursor(type)
390
 
int type;
 
410
static void _cursor(int type)
391
411
{
392
412
  _curstype = type;
393
413
 
394
 
  if (type == CNORMAL && VE != CNULL) outstr(VE);
395
 
  if (type == CNONE && VE != CNULL && VI != CNULL) outstr(VI);
 
414
  if (type == CNORMAL && VE != NULL)
 
415
    outstr(VE);
 
416
  if (type == CNONE && VE != NULL && VI != NULL)
 
417
    outstr(VI);
396
418
}
397
419
 
398
420
 
406
428
/*
407
429
 * Resize a window
408
430
 */
409
 
void wresize(win, lines, cols)
410
 
WIN *win;
411
 
int lines, cols;
 
431
void wresize(WIN *win, int lines, int cols)
412
432
{
413
433
  int x, y;
414
434
  ELM *oldmap, *newmap, *e, *n;
415
435
 
416
 
  if ((newmap = (ELM *)malloc((lines + 1) * cols * sizeof(ELM))) == (ELM *)NULL)
417
 
        return;
 
436
  if ((newmap = malloc((lines + 1) * cols * sizeof(ELM))) == NULL)
 
437
    return;
418
438
  if (win == stdwin)
419
 
        oldmap = gmap;
 
439
    oldmap = gmap;
420
440
  else
421
 
        oldmap = win->map;
 
441
    oldmap = win->map;
422
442
 
423
 
  for(y = 0; y < lines; y++)
424
 
        for(x = 0; x < cols; x++) {
425
 
                n = &newmap[y + x * cols];
426
 
                if (x < win->xs && y < win->ys) {
427
 
                        e = &oldmap[y + x * COLS];
428
 
                        n->value = e->value;
429
 
                        n->color = e->color;
430
 
                        n->attr = e->attr;
431
 
                } else {
432
 
                        n->value = ' ';
433
 
                        n->color = win->color;
434
 
                        n->attr = win->attr;
435
 
                }
436
 
        }
437
 
  if (win->sy2 == win->y2) win->sy2 = win->y1 + lines - 1;
 
443
  for (y = 0; y < lines; y++)
 
444
    for (x = 0; x < cols; x++) {
 
445
      n = &newmap[y + x * cols];
 
446
      if (x < win->xs && y < win->ys) {
 
447
        e = &oldmap[y + x * COLS];
 
448
        n->value = e->value;
 
449
        n->color = e->color;
 
450
        n->attr = e->attr;
 
451
      } else {
 
452
        n->value = ' ';
 
453
        n->color = win->color;
 
454
        n->attr = win->attr;
 
455
      }
 
456
    }
 
457
  if (win->sy2 == win->y2)
 
458
    win->sy2 = win->y1 + lines - 1;
438
459
  win->y2 = win->y1 + lines - 1;
439
460
  win->ys = lines;
440
461
  win->xs = cols;
441
462
  free(oldmap);
442
463
  if (win == stdwin) {
443
 
        gmap = newmap;
444
 
        LINES = lines;
445
 
        COLS = cols;
 
464
    gmap = newmap;
 
465
    LINES = lines;
 
466
    COLS = cols;
446
467
  } else
447
 
        win->map = newmap;
 
468
    win->map = newmap;
448
469
}
449
470
#endif
450
471
 
451
472
/*
452
473
 * Create a new window.
453
474
 */
454
 
/*ARGSUSED*/
455
 
WIN *wopen(x1, y1, x2, y2, border, attr, fg, bg, direct, histlines, doclr)
456
 
int x1, y1, x2, y2;
457
 
int border;
458
 
int attr, fg, bg, direct;
459
 
int histlines;
460
 
int doclr;
 
475
WIN *wopen(int x1, int y1, int x2, int y2, int border, int attr,
 
476
           int fg, int bg, int direct, int histlines, int doclr)
461
477
{
462
478
  WIN *w;
463
479
  ELM *e;
467
483
  int offs;
468
484
  int xattr;
469
485
#ifdef SMOOTH
470
 
  curwin = NIL_WIN;
 
486
  curwin = NULL;
471
487
#endif
472
488
 
473
 
  if ((w = (WIN *)malloc(sizeof(WIN))) == (WIN *)0) return(w);
474
 
  
 
489
  if ((w = malloc(sizeof(WIN))) == NULL)
 
490
    return w;
 
491
 
475
492
  offs = (border != BNONE);
476
 
  if (!screen_ibmpc && AS) 
477
 
        xattr = attr | XA_ALTCHARSET;
 
493
  if (!screen_ibmpc && AS)
 
494
    xattr = attr | XA_ALTCHARSET;
478
495
  else
479
 
        xattr = attr;
 
496
    xattr = attr;
480
497
 
481
 
  if (x1 < offs) x1 = offs;
482
 
  if (y1 < offs) y1 = offs;
 
498
  if (x1 > x2)
 
499
    swap(x1, x2);
 
500
  if (y1 > y2)
 
501
    swap(y1, y2);
 
502
  if (x1 < offs)
 
503
    x1 = offs;
 
504
  if (y1 < offs)
 
505
    y1 = offs;
483
506
#if 0
484
 
  if (x2 >= COLS - offs) x2 = COLS - offs - 1;
485
 
  if (y2 >= LINES - offs) y2 = LINES - offs - 1;
 
507
  if (x2 >= COLS - offs)
 
508
    x2 = COLS - offs - 1;
 
509
  if (y2 >= LINES - offs)
 
510
    y2 = LINES - offs - 1;
486
511
#endif
487
 
  if (x1 > x2) swap(x1, x2);
488
 
  if (y1 > y2) swap(y1, y2);
489
512
 
490
513
  w->xs = x2 - x1 + 1;
491
514
  w->ys = y2 - y1 + 1;
511
534
  w->direct = direct;
512
535
 
513
536
  if (border != BNONE) {
514
 
        x1--; x2++;
515
 
        y1--; y2++;
 
537
    x1--;
 
538
    x2++;
 
539
    y1--;
 
540
    y2++;
516
541
  }
517
542
  /* Store whatever we are overlapping */
518
543
  bytes = (y2 - y1 + 1) * (x2 - x1 + 1) * sizeof(ELM) + 100;
519
 
  if ((e = (ELM *)malloc(bytes)) == (ELM *)0) {
520
 
        free(w);
521
 
        return((WIN *)0);
 
544
  if ((e = malloc(bytes)) == NULL) {
 
545
        free(w);
 
546
        return NULL;
522
547
  }
523
548
  w->map = e;
524
549
  /* How many bytes is one line */
525
550
  bytes = (x2 - x1 + 1) * sizeof(ELM);
526
551
  /* Loop */
527
 
  for(y = y1; y <= y2; y++) {
528
 
        memcpy(e, gmap + COLS * y + x1, bytes);
529
 
        e += (x2 - x1 + 1);
 
552
  for (y = y1; y <= y2; y++) {
 
553
    memcpy(e, gmap + COLS * y + x1, bytes);
 
554
    e += (x2 - x1 + 1);
530
555
  }
531
 
  
532
 
#if HISTORY
 
556
 
533
557
  /* Do we want history? */
534
558
  w->histline = w->histlines = 0;
535
 
  w->histbuf = (ELM *)0;
 
559
  w->histbuf = NULL;
536
560
  if (histlines) {
537
 
        /* Reserve some memory. */
538
 
        bytes = w->xs * histlines * sizeof(ELM);
539
 
        if ((w->histbuf = (ELM *)malloc(bytes)) == NULL) {
540
 
                free(w->map);
541
 
                free(w);
542
 
                return((WIN *)0);
543
 
        }
544
 
        w->histlines = histlines;
 
561
    /* Reserve some memory. */
 
562
    bytes = w->xs * histlines * sizeof(ELM);
 
563
    if ((w->histbuf = malloc(bytes)) == NULL) {
 
564
      free(w->map);
 
565
      free(w);
 
566
      return NULL;
 
567
    }
 
568
    w->histlines = histlines;
545
569
 
546
 
        /* Clear the history buf. */
547
 
        e = w->histbuf;
548
 
        for(y = 0; y < w->xs * histlines; y++) {
549
 
                e->value = ' ';
550
 
                e->attr = attr;
551
 
                e->color = color;
552
 
                e++;
553
 
        }
 
570
    /* Clear the history buf. */
 
571
    e = w->histbuf;
 
572
    for (y = 0; y < w->xs * histlines; y++) {
 
573
      e->value = ' ';
 
574
      e->attr = attr;
 
575
      e->color = color;
 
576
      e++;
 
577
    }
554
578
  }
555
 
#endif
556
579
 
557
580
  /* And draw the window */
558
581
  if (border) {
559
 
        _write(border == BSINGLE ? S_UL : D_UL, w->direct, x1, y1,
560
 
                                        xattr, color);
561
 
        for(x = x1 + 1; x < x2; x++)
562
 
                _write(border == BSINGLE ? S_HOR : D_HOR, w->direct, x, y1,
563
 
                                        xattr, color);
564
 
        _write(border == BSINGLE ? S_UR : D_UR, w->direct, x2, y1,
565
 
                                        xattr, color);
566
 
        for(y = y1 + 1; y < y2; y++) {
567
 
                _write(border == BSINGLE ? S_VER : D_VER, w->direct, x1, y,
568
 
                                        xattr, color);
569
 
                for(x = x1 + 1; x < x2; x++)
570
 
                        _write(' ', w->direct, x, y, attr, color);
571
 
                _write(border == BSINGLE ? S_VER : D_VER, w->direct, x2, y,
572
 
                                        xattr, color);
573
 
        }
574
 
        _write(border == BSINGLE ? S_LL : D_LL, w->direct, x1, y2,
575
 
                                        xattr, color);
576
 
        for(x = x1 + 1; x < x2; x++)
577
 
                _write(border == BSINGLE ? S_HOR : D_HOR, w->direct,
578
 
                                        x, y2, xattr, color);
579
 
        _write(border == BSINGLE ? S_LR : D_LR, w->direct, x2, y2,
580
 
                                        xattr, color);
581
 
        if (w->direct) _gotoxy(x1 + 1, y1 + 1);
 
582
    _write(border == BSINGLE ? S_UL : D_UL, w->direct, x1, y1, xattr, color);
 
583
    for (x = x1 + 1; x < x2; x++)
 
584
      _write(border == BSINGLE ? S_HOR : D_HOR, w->direct, x, y1, xattr, color);
 
585
    _write(border == BSINGLE ? S_UR : D_UR, w->direct, x2, y1, xattr, color);
 
586
    for (y = y1 + 1; y < y2; y++) {
 
587
      _write(border == BSINGLE ? S_VER : D_VER, w->direct, x1, y, xattr, color);
 
588
      for (x = x1 + 1; x < x2; x++)
 
589
        _write(' ', w->direct, x, y, attr, color);
 
590
      _write(border == BSINGLE ? S_VER : D_VER, w->direct, x2, y, xattr, color);
 
591
    }
 
592
    _write(border == BSINGLE ? S_LL : D_LL, w->direct, x1, y2, xattr, color);
 
593
    for (x = x1 + 1; x < x2; x++)
 
594
      _write(border == BSINGLE ? S_HOR : D_HOR, w->direct, x, y2, xattr, color);
 
595
    _write(border == BSINGLE ? S_LR : D_LR, w->direct, x2, y2, xattr, color);
 
596
    if (w->direct)
 
597
      _gotoxy(x1 + 1, y1 + 1);
582
598
  } else
583
 
        if (doclr) winclr(w);
584
 
  wcursor(w, CNORMAL);  
 
599
    if (doclr)
 
600
      winclr(w);
 
601
  wcursor(w, CNORMAL);
585
602
 
586
 
  if (w->direct) wflush();
587
 
  return(w);
 
603
  if (w->direct)
 
604
    wflush();
 
605
  return w;
588
606
}
589
607
 
590
608
/*
591
609
 * Close a window.
592
610
 */
593
 
void wclose(win, replace)
594
 
WIN *win;
595
 
int replace;
 
611
void wclose(WIN *win, int replace)
596
612
{
597
613
  ELM *e;
598
614
  int x, y;
599
615
 
600
616
#ifdef SMOOTH
601
 
  curwin = NIL_WIN;
 
617
  curwin = NULL;
602
618
#endif
603
619
 
604
 
  if (!win) return;
 
620
  if (!win)
 
621
    return;
605
622
 
606
623
  if (win == stdwin) {
607
 
        win_end();
608
 
        return;
 
624
    win_end();
 
625
    return;
609
626
  }
610
627
  e = win->map;
611
628
 
612
629
  if (win->border) {
613
 
        win->x1--; win->x2++;
614
 
        win->y1--; win->y2++;
 
630
    win->x1--;
 
631
    win->x2++;
 
632
    win->y1--;
 
633
    win->y2++;
615
634
  }
616
635
  wcursor(win, win->o_cursor);
617
636
  if (replace) {
618
 
        for(y = win->y1; y <= win->y2; y++) {
619
 
                /* temporal way to avoid 'half-character' problem */
620
 
                /* in multibyte characters such as Japanese -- from here */
621
 
                ELM *g;
622
 
                g = gmap + (y * stdwin->xs);
623
 
                for(x = 0 ; x < win->x1; x++) {
624
 
                        _write(g->value, 1, x, y, g->attr, g->color);
625
 
                        g++;
626
 
                }
627
 
                /* to here */
628
 
                for(x = win->x1; x <= win->x2; x++) {
629
 
                        _write(e->value, 1, x, y, e->attr, e->color);
630
 
                        e++;
631
 
                }
632
 
        }
633
 
        _gotoxy(win->o_curx, win->o_cury);
634
 
        _setattr(win->o_attr, win->o_color);
 
637
    for (y = win->y1; y <= win->y2; y++) {
 
638
      /* temporal way to avoid 'half-character' problem */
 
639
      /* in multibyte characters such as Japanese -- from here */
 
640
      ELM *g;
 
641
      g = gmap + (y * stdwin->xs);
 
642
      for (x = 0 ; x < win->x1; x++) {
 
643
        _write(g->value, 1, x, y, g->attr, g->color);
 
644
        g++;
 
645
      }
 
646
      /* to here */
 
647
      for (x = win->x1; x <= win->x2; x++) {
 
648
        _write(e->value, 1, x, y, e->attr, e->color);
 
649
        e++;
 
650
      }
 
651
    }
 
652
    _gotoxy(win->o_curx, win->o_cury);
 
653
    _setattr(win->o_attr, win->o_color);
635
654
  }
636
655
  free(win->map);
637
 
#if HISTORY
638
 
  if (win->histbuf) free(win->histbuf);
639
 
#endif
 
656
  if (win->histbuf)
 
657
    free(win->histbuf);
640
658
  free(win);    /* 1.1.98 dickey@clark.net  */
641
659
  wflush();
642
660
}
647
665
/*
648
666
 * Clear screen & restore keyboard modes
649
667
 */
650
 
void wleave()
 
668
void wleave(void)
651
669
{
652
670
  oldx = curx;
653
671
  oldy = cury;
654
672
  ocursor = _curstype;
655
673
 
656
 
  (void) setcbreak(0); /* Normal */
 
674
  setcbreak(0); /* Normal */
657
675
  _gotoxy(0, LINES - 1);
658
676
  _setattr(XA_NORMAL, COLATTR(WHITE, BLACK));
659
677
  _cursor(CNORMAL);
660
 
  if (CL != CNULL)
661
 
        outstr(CL);
 
678
  if (CL != NULL)
 
679
    outstr(CL);
662
680
  else
663
 
        outstr("\n");
664
 
#if ST_LINE
665
 
  if (DS) outstr(DS);
 
681
    outstr("\n");
 
682
#ifdef ST_LINE
 
683
  if (DS)
 
684
    outstr(DS);
666
685
#endif
667
 
  if (KE != CNULL) outstr(KE);
668
 
  if (RS != CNULL) outstr(RS);
 
686
  if (KE != NULL)
 
687
    outstr(KE);
 
688
  if (RS != NULL)
 
689
    outstr(RS);
669
690
  wflush();
670
691
}
671
692
 
672
 
void wreturn()
 
693
void wreturn(void)
673
694
{
674
695
  int x, y;
675
696
  ELM *e;
676
697
 
677
698
#ifdef SMOOTH
678
 
  curwin = NIL_WIN;
 
699
  curwin = NULL;
679
700
#endif
680
701
 
681
702
  curattr = -1;
682
703
  curcolor = -1;
683
704
 
684
 
  (void) setcbreak(1); /* Cbreak, no echo */
685
 
 
686
 
  if (IS != CNULL) outstr(IS); /* Initialization string */
687
 
  if (EA != CNULL) outstr(EA); /* Graphics init. */
688
 
  if (KS != CNULL) outstr(KS); /* Keypad mode */
689
 
  
 
705
  setcbreak(1); /* Cbreak, no echo */
 
706
 
 
707
  if (IS != NULL)
 
708
    outstr(IS); /* Initialization string */
 
709
  if (EA != NULL)
 
710
    outstr(EA); /* Graphics init. */
 
711
  if (KS != NULL)
 
712
    outstr(KS); /* Keypad mode */
 
713
 
690
714
  _gotoxy(0, 0);
691
715
  _cursor(ocursor);
692
716
 
693
717
  e = gmap;
694
 
  for(y = 0; y <LINES; y++) {
695
 
        for(x = 0; x < COLS; x++) {
696
 
                _write(e->value, -1, x, y, e->attr, e->color);
697
 
                e++;
698
 
        }
 
718
  for (y = 0; y <LINES; y++) {
 
719
    for(x = 0; x < COLS; x++) {
 
720
      _write(e->value, -1, x, y, e->attr, e->color);
 
721
      e++;
 
722
    }
699
723
  }
700
724
  _gotoxy(oldx, oldy);
701
725
  wflush();
704
728
/*
705
729
 * Redraw the whole window.
706
730
 */
707
 
void wredraw(w, newdirect)
708
 
WIN *w;
709
 
int newdirect;
 
731
void wredraw(WIN *w, int newdirect)
710
732
{
711
733
  int minx, maxx, miny, maxy;
712
734
  ELM *e;
720
742
  addcnt = stdwin->xs - w->xs;
721
743
 
722
744
  if (w->border) {
723
 
        minx--;
724
 
        maxx++;
725
 
        miny--;
726
 
        maxy++;
727
 
        addcnt -= 2;
 
745
    minx--;
 
746
    maxx++;
 
747
    miny--;
 
748
    maxy++;
 
749
    addcnt -= 2;
728
750
  }
729
751
 
730
752
  _gotoxy(minx, miny);
731
753
  _cursor(CNONE);
732
754
  e = gmap + (miny * stdwin->xs) + minx;
733
755
 
734
 
  for(y = miny; y <= maxy; y++) {
735
 
        for(x = minx; x <= maxx; x++) {
736
 
                _write(e->value, -1, x, y, e->attr, e->color);
737
 
                e++;
738
 
        }
739
 
        e += addcnt;
 
756
  for (y = miny; y <= maxy; y++) {
 
757
    for(x = minx; x <= maxx; x++) {
 
758
      _write(e->value, -1, x, y, e->attr, e->color);
 
759
      e++;
 
760
    }
 
761
    e += addcnt;
740
762
  }
741
763
  _gotoxy(w->x1 + w->curx, w->y1 + w->cury);
742
764
  _cursor(w->cursor);
747
769
/*
748
770
 * Clear to end of line, low level.
749
771
 */
750
 
static int _wclreol(w)
751
 
WIN *w;
 
772
static int _wclreol(WIN *w)
752
773
{
753
774
  int x;
754
775
  int doit = 1;
755
776
  int y;
756
 
  
 
777
 
757
778
#ifdef SMOOTH
758
779
  curwin = w;
759
780
#endif
760
781
  y = w->cury + w->y1;
761
782
 
762
783
  if (w->direct && (w->x2 == COLS - 1) && CE) {
763
 
        _gotoxy(w->curx + w->x1, y);
764
 
        _setattr(w->attr, w->color);
765
 
        outstr(CE);
766
 
        doit = 0;
767
 
  }
768
 
  for(x = w->curx + w->x1; x <= w->x2; x++) {
769
 
        _write(' ', (w->direct && doit) ? 1 : 0, x, y, w->attr, w->color);
770
 
  }
771
 
  return(doit); 
 
784
    _gotoxy(w->curx + w->x1, y);
 
785
    _setattr(w->attr, w->color);
 
786
    outstr(CE);
 
787
    doit = 0;
 
788
  }
 
789
  for (x = w->curx + w->x1; x <= w->x2; x++) {
 
790
    _write(' ', (w->direct && doit) ? 1 : 0, x, y, w->attr, w->color);
 
791
  }
 
792
  return doit;
772
793
}
773
794
 
774
795
/*
775
796
 * Scroll a window.
776
797
 */
777
 
void wscroll(win, dir)
778
 
WIN *win;
779
 
int dir;
 
798
void wscroll(WIN *win, int dir)
780
799
{
781
800
  ELM *e, *f;
782
801
  char *src, *dst;
793
812
   * If the window *is* the physical screen, we can scroll very simple.
794
813
   * This improves performance on slow screens (eg ATARI ST) dramatically.
795
814
   */
796
 
  if (win->direct && SF != CNULL &&
797
 
        (dir == S_UP || SR != CNULL) && (LINES == win->sy2 - win->sy1 + 1)) {
798
 
        doit = 0;
799
 
        phys_scr = 1;
800
 
        _setattr(win->attr, win->color);
801
 
        if (dir == S_UP) {
802
 
                _gotoxy(0, LINES - 1);
803
 
                outstr(SF);
804
 
        } else {
805
 
                _gotoxy(0, 0);
806
 
                outstr(SR);
807
 
        }
 
815
  if (win->direct && SF != NULL &&
 
816
      (dir == S_UP || SR != NULL) && (LINES == win->sy2 - win->sy1 + 1)) {
 
817
    doit = 0;
 
818
    phys_scr = 1;
 
819
    _setattr(win->attr, win->color);
 
820
    if (dir == S_UP) {
 
821
      _gotoxy(0, LINES - 1);
 
822
      outstr(SF);
 
823
    } else {
 
824
      _gotoxy(0, 0);
 
825
      outstr(SR);
 
826
    }
808
827
  }
809
828
  /*
810
829
   * If the window is as wide as the physical screen, we can
811
830
   * scroll it with insert/delete line (or set scroll region - vt100!)
812
831
   */
813
832
  else if (win->direct && win->xs == COLS &&
814
 
                ((CS != CNULL && SF != CNULL && SR != CNULL)
815
 
                || (Dl != CNULL && Al != CNULL))) {
816
 
        doit = 0;
817
 
        phys_scr = 1;
818
 
        _setattr(win->attr, win->color);
819
 
        if (CS != CNULL && SF != CNULL && SR != CNULL) { /* Scrolling Region */
820
 
                /* If the scroll region we want to initialize already is as
821
 
                 * big as the physical screen, we don't _have_ to
822
 
                 * initialize it.
823
 
                 */
824
 
                if (win->sy2 == LINES - 1 && win->sy1 == 0) fs = 1;
825
 
                if (!fs) {
826
 
                        outstr(tgoto(CS, win->sy2, win->sy1));
827
 
                        cury = 0;
828
 
                }       
829
 
                if (dir == S_UP) {
830
 
                        _gotoxy(0, win->sy2);
831
 
                        outstr(SF);
832
 
                } else {
833
 
                        _gotoxy(0, win->sy1);
834
 
                        outstr(SR);
835
 
                }
836
 
                if (!fs) {
837
 
                        outstr(tgoto(CS, LINES - 1, 0));
838
 
                        cury = 0;
839
 
                }       
840
 
                _gotoxy(0, win->sy2);
841
 
        } else { /* Use insert/delete line */
842
 
                if (dir == S_UP) {
843
 
                        _gotoxy(0, win->sy1);
844
 
                        outstr(Dl);
845
 
                        _gotoxy(0, win->sy2);
846
 
                        outstr(Al);
847
 
                } else {
848
 
                        _gotoxy(0, win->sy2);
849
 
                        outstr(Dl);
850
 
                        _gotoxy(0, win->sy1);
851
 
                        outstr(Al);
852
 
                }
853
 
        }
 
833
      ((CS != NULL && SF != NULL && SR != NULL)
 
834
       || (Dl != NULL && Al != NULL))) {
 
835
    doit = 0;
 
836
    phys_scr = 1;
 
837
    _setattr(win->attr, win->color);
 
838
    if (CS != NULL && SF != NULL && SR != NULL) { /* Scrolling Region */
 
839
      /* If the scroll region we want to initialize already is as
 
840
       * big as the physical screen, we don't _have_ to
 
841
       * initialize it.
 
842
       */
 
843
      if (win->sy2 == LINES - 1 && win->sy1 == 0)
 
844
        fs = 1;
 
845
      if (!fs) {
 
846
        outstr(tgoto(CS, win->sy2, win->sy1));
 
847
        cury = 0;
 
848
      }
 
849
      if (dir == S_UP) {
 
850
        _gotoxy(0, win->sy2);
 
851
        outstr(SF);
 
852
      } else {
 
853
        _gotoxy(0, win->sy1);
 
854
        outstr(SR);
 
855
      }
 
856
      if (!fs) {
 
857
        outstr(tgoto(CS, LINES - 1, 0));
 
858
        cury = 0;
 
859
      }
 
860
      _gotoxy(0, win->sy2);
 
861
    } else { /* Use insert/delete line */
 
862
      if (dir == S_UP) {
 
863
        _gotoxy(0, win->sy1);
 
864
        outstr(Dl);
 
865
        _gotoxy(0, win->sy2);
 
866
        outstr(Al);
 
867
      } else {
 
868
        _gotoxy(0, win->sy2);
 
869
        outstr(Dl);
 
870
        _gotoxy(0, win->sy1);
 
871
        outstr(Al);
 
872
      }
 
873
    }
854
874
  }
855
875
 
856
876
  /* If a terminal has automatic margins, we can't write
858
878
   * the non-visible character that is now visible.
859
879
   */
860
880
  if (sflag && win->sy2 == (LINES - 1) && win->sy1 != win->sy2) {
861
 
        if (dir == S_UP) {
862
 
                _write(oldc.value, 1, COLS - 1, LINES - 2,
863
 
                        oldc.attr, oldc.color);
864
 
        }
865
 
        sflag = 0;
 
881
    if (dir == S_UP) {
 
882
      _write(oldc.value, 1, COLS - 1, LINES - 2,
 
883
             oldc.attr, oldc.color);
 
884
    }
 
885
    sflag = 0;
866
886
  }
867
887
 
868
888
  ocurx = win->curx;
869
889
 
870
 
#if HISTORY
871
890
  /* If this window has a history buf, see if we want to use it. */
872
891
  if (win->histbuf && dir == S_UP &&
873
 
        win->sy2 == win->y2 && win->sy1 == win->y1) {
874
 
 
875
 
        /* Calculate screen buffer */
876
 
        e = gmap + win->y1 * COLS + win->x1;
877
 
 
878
 
        /* Calculate history buffer */
879
 
        f = win->histbuf + (win->xs * win->histline);
880
 
 
881
 
        /* Copy line from screen to history buffer */
882
 
        memcpy((char *)f, (char *)e, win->xs * sizeof(ELM));
883
 
 
884
 
        /* Postion the next line in the history buffer */
885
 
        win->histline++;
886
 
        if (win->histline >= win->histlines) win->histline = 0;
 
892
      win->sy2 == win->y2 && win->sy1 == win->y1) {
 
893
 
 
894
    /* Calculate screen buffer */
 
895
    e = gmap + win->y1 * COLS + win->x1;
 
896
 
 
897
    /* Calculate history buffer */
 
898
    f = win->histbuf + (win->xs * win->histline);
 
899
 
 
900
    /* Copy line from screen to history buffer */
 
901
    memcpy((char *)f, (char *)e, win->xs * sizeof(ELM));
 
902
 
 
903
    /* Postion the next line in the history buffer */
 
904
    win->histline++;
 
905
    if (win->histline >= win->histlines)
 
906
      win->histline = 0;
887
907
  }
888
 
#endif
889
908
 
890
909
  /* If the window is screen-wide and has no border, there
891
910
   * is a much simpler & FASTER way of scrolling the memory image !!
892
911
   */
893
912
  if (phys_scr) {
894
 
        len = (win->sy2 - win->sy1) * win->xs * sizeof(ELM);
895
 
        if (dir == S_UP)  {
896
 
                dst = (char *)&gmap[0];                         /* First line */
897
 
                src = (char *)&gmap[win->xs];                   /* Second line */
898
 
                win->cury = win->sy2 - win->y1;
899
 
        } else {
900
 
                src = (char *)&gmap[0];                         /* First line */
901
 
                dst = (char *)&gmap[win->xs];                   /* Second line */
902
 
                win->cury = win->sy1 - win->y1;
903
 
        }
904
 
        /* memmove copies len bytes from src to dst, even if the
905
 
         * objects overlap.
906
 
         */
907
 
        fflush(stdout);
 
913
    len = (win->sy2 - win->sy1) * win->xs * sizeof(ELM);
 
914
    if (dir == S_UP)  {
 
915
      dst = (char *)&gmap[0];                           /* First line */
 
916
      src = (char *)&gmap[win->xs];                     /* Second line */
 
917
      win->cury = win->sy2 - win->y1;
 
918
    } else {
 
919
      src = (char *)&gmap[0];                           /* First line */
 
920
      dst = (char *)&gmap[win->xs];                     /* Second line */
 
921
      win->cury = win->sy1 - win->y1;
 
922
    }
 
923
    /* memmove copies len bytes from src to dst, even if the
 
924
     * objects overlap.
 
925
     */
 
926
    fflush(stdout);
908
927
#ifdef _SYSV
909
 
        memcpy((char *)dst, (char *)src, len);
 
928
    memcpy((char *)dst, (char *)src, len);
910
929
#else
911
930
#  ifdef _BSD43
912
 
        bcopy((char *)src, (char *)dst, len);
 
931
    bcopy((char *)src, (char *)dst, len);
913
932
#  else
914
 
        memmove((char *)dst, (char *)src, len);
 
933
    memmove((char *)dst, (char *)src, len);
915
934
#  endif
916
935
#endif
917
936
  } else {
918
 
        /* Now scroll the memory image. */
919
 
        if (dir == S_UP) {
920
 
                for(y = win->sy1 + 1; y <= win->sy2; y++) {
921
 
                        e = gmap + y * COLS + win->x1;
922
 
                        for(x = win->x1; x <= win->x2; x++) {
923
 
                           _write(e->value, win->direct && doit,
924
 
                                        x, y - 1, e->attr, e->color);
925
 
                           e++;
926
 
                        }
927
 
                }
928
 
                win->curx = 0;
929
 
                win->cury = win->sy2 - win->y1;
930
 
                if (doit) (void) _wclreol(win);
931
 
        } else {
932
 
                for(y = win->sy2 - 1; y >= win->sy1; y--) {
933
 
                        e = gmap + y * COLS + win->x1;
934
 
                        for(x = win->x1; x <= win->x2; x++) {
935
 
                           _write(e->value, win->direct && doit,
936
 
                                        x, y + 1, e->attr, e->color);
937
 
                           e++;
938
 
                        }
939
 
                }
940
 
                win->curx = 0;
941
 
                win->cury = win->sy1 - win->y1;
942
 
                if (doit) (void) _wclreol(win);
943
 
        }
 
937
    /* Now scroll the memory image. */
 
938
    if (dir == S_UP) {
 
939
      for (y = win->sy1 + 1; y <= win->sy2; y++) {
 
940
        e = gmap + y * COLS + win->x1;
 
941
        for (x = win->x1; x <= win->x2; x++) {
 
942
          _write(e->value, win->direct && doit, x, y - 1, e->attr, e->color);
 
943
          e++;
 
944
        }
 
945
      }
 
946
      win->curx = 0;
 
947
      win->cury = win->sy2 - win->y1;
 
948
      if (doit)
 
949
        _wclreol(win);
 
950
    } else {
 
951
      for (y = win->sy2 - 1; y >= win->sy1; y--) {
 
952
        e = gmap + y * COLS + win->x1;
 
953
        for (x = win->x1; x <= win->x2; x++) {
 
954
          _write(e->value, win->direct && doit, x, y + 1, e->attr, e->color);
 
955
          e++;
 
956
        }
 
957
      }
 
958
      win->curx = 0;
 
959
      win->cury = win->sy1 - win->y1;
 
960
      if (doit)
 
961
        _wclreol(win);
 
962
    }
944
963
  }
945
964
 
946
965
  win->curx = ocurx;
947
966
 
948
 
  if (!doit) for(x = win->x1; x <= win->x2; x++)
949
 
                _write(' ', 0, x, win->y1 + win->cury, win->attr, win->color);
 
967
  if (!doit)
 
968
    for (x = win->x1; x <= win->x2; x++)
 
969
      _write(' ', 0, x, win->y1 + win->cury, win->attr, win->color);
950
970
  if (!_intern && win->direct)
951
 
        _gotoxy(win->x1 + win->curx, win->y1 + win->cury);
952
 
  if (dirflush && !_intern && win->direct) wflush();
 
971
    _gotoxy(win->x1 + win->curx, win->y1 + win->cury);
 
972
  if (dirflush && !_intern && win->direct)
 
973
    wflush();
953
974
}
954
975
 
955
976
/*
956
977
 * Locate the cursor in a window.
957
978
 */
958
 
void wlocate(win, x, y)
959
 
WIN *win;
960
 
int x, y;
 
979
void wlocate(WIN *win, int x, int y)
961
980
{
962
 
  if (x < 0) x = 0;
963
 
  if (y < 0) y = 0;
964
 
  if (x >= win->xs) x = win->xs - 1;
965
 
  if (y >= win->ys) y = win->ys - 1;
 
981
  if (x < 0)
 
982
    x = 0;
 
983
  if (y < 0)
 
984
    y = 0;
 
985
  if (x >= win->xs)
 
986
    x = win->xs - 1;
 
987
  if (y >= win->ys)
 
988
    y = win->ys - 1;
966
989
 
967
990
  win->curx = x;
968
991
  win->cury = y;
969
 
  if (win->direct) _gotoxy(win->x1 + x, win->y1 + y);
 
992
  if (win->direct)
 
993
    _gotoxy(win->x1 + x, win->y1 + y);
970
994
 
971
 
  if (dirflush) wflush();
 
995
  if (dirflush)
 
996
    wflush();
972
997
}
973
998
 
974
999
/*
975
1000
 * Print a character in a window.
976
1001
 */
977
 
void wputc(win, c)
978
 
WIN *win;
979
 
int c;
 
1002
void wputc(WIN *win, wchar_t c)
980
1003
{
981
1004
  int mv = 0;
982
1005
 
985
1008
#endif
986
1009
 
987
1010
  switch(c) {
988
 
        case '\r':
989
 
                win->curx = 0;
990
 
                mv++;
991
 
                break;
992
 
        case '\b':
993
 
                if (win->curx == 0) break;
994
 
                win->curx--;
995
 
                mv++;
996
 
                break;
997
 
        case '\007':
998
 
                wbell();
999
 
                break;
1000
 
        case '\t':
1001
 
                do {
1002
 
                        wputc(win, ' '); /* Recursion! */
1003
 
                } while(win->curx % 8);
1004
 
                break;
1005
 
        case '\n':
1006
 
                if (win->autocr) win->curx = 0;
1007
 
                /*FALLTHRU*/
1008
 
        default:
1009
 
                /* See if we need to scroll/move. (vt100 behaviour!) */
1010
 
                if (c == '\n' || (win->curx >= win->xs && win->wrap)) {
1011
 
                        if (c != '\n') win->curx = 0;
1012
 
                        win->cury++;
1013
 
                        mv++;
1014
 
                        if (win->cury == win->sy2 - win->y1 + 1) {
1015
 
                                if (win->doscroll)
1016
 
                                        wscroll(win, S_UP);
1017
 
                                else
1018
 
                                        win->cury = win->sy1 - win->y1;
1019
 
                        }
1020
 
                        if (win->cury >= win->ys) win->cury = win->ys - 1;
1021
 
                }
1022
 
                /* Now write the character. */
1023
 
                if (c != '\n') {
1024
 
                        _write(c, win->direct, win->curx + win->x1,
1025
 
                                win->cury + win->y1, win->attr, win->color);
1026
 
                        if (++win->curx >= win->xs && !win->wrap) {
1027
 
                                win->curx--;    
1028
 
                                curx = 0; /* Force to move */
1029
 
                                mv++;
1030
 
                        }
1031
 
                }
1032
 
                break;
 
1011
    case '\r':
 
1012
      win->curx = 0;
 
1013
      mv++;
 
1014
      break;
 
1015
    case '\b':
 
1016
      if (win->curx == 0)
 
1017
        break;
 
1018
      win->curx--;
 
1019
      mv++;
 
1020
      break;
 
1021
    case '\007':
 
1022
      wbell();
 
1023
      break;
 
1024
    case '\t':
 
1025
      do {
 
1026
        wputc(win, ' '); /* Recursion! */
 
1027
      } while (win->curx % 8);
 
1028
      break;
 
1029
    case '\n':
 
1030
      if (win->autocr)
 
1031
        win->curx = 0;
 
1032
      /*FALLTHRU*/
 
1033
    default:
 
1034
      /* See if we need to scroll/move. (vt100 behaviour!) */
 
1035
      if (c == '\n' || (win->curx >= win->xs && win->wrap)) {
 
1036
        if (c != '\n')
 
1037
          win->curx = 0;
 
1038
        win->cury++;
 
1039
        mv++;
 
1040
        if (win->cury == win->sy2 - win->y1 + 1) {
 
1041
          if (win->doscroll)
 
1042
            wscroll(win, S_UP);
 
1043
          else
 
1044
            win->cury = win->sy1 - win->y1;
 
1045
        }
 
1046
        if (win->cury >= win->ys)
 
1047
          win->cury = win->ys - 1;
 
1048
      }
 
1049
      /* Now write the character. */
 
1050
      if (c != '\n') {
 
1051
        if (!win->wrap && win->curx >= win->xs)
 
1052
          c = '>';
 
1053
        _write(c, win->direct, win->curx + win->x1,
 
1054
               win->cury + win->y1, win->attr, win->color);
 
1055
        if (++win->curx >= win->xs && !win->wrap) {
 
1056
          win->curx--;
 
1057
          curx = 0; /* Force to move */
 
1058
          mv++;
 
1059
        }
 
1060
      }
 
1061
      break;
1033
1062
  }
1034
1063
  if (mv && win->direct)
1035
 
        _gotoxy(win->x1 + win->curx, win->y1 + win->cury);
 
1064
    _gotoxy(win->x1 + win->curx, win->y1 + win->cury);
1036
1065
 
1037
 
  if (win->direct && dirflush && !_intern) wflush();
 
1066
  if (win->direct && dirflush && !_intern)
 
1067
    wflush();
1038
1068
}
1039
1069
 
1040
1070
/* Draw one line in a window */
1041
 
void wdrawelm(w, y, e)
1042
 
WIN *w;
1043
 
int y;
1044
 
ELM *e;
 
1071
void wdrawelm(WIN *w, int y, ELM *e)
1045
1072
{
1046
1073
  int x;
1047
1074
 
1048
1075
  /* MARK updated 02/17/94 - Fixes bug, to do all 80 cols, not 79 cols */
1049
 
  for(x = w->x1; x <= w->x2; x++)
1050
 
  {
1051
 
        _write(e->value, w->direct, x, y + w->y1, e->attr, e->color);
1052
 
                /*y + w->y1, XA_NORMAL, e->color);*/
1053
 
        e++;
 
1076
  for (x = w->x1; x <= w->x2; x++) {
 
1077
    _write(e->value, w->direct, x, y + w->y1, e->attr, e->color);
 
1078
    /*y + w->y1, XA_NORMAL, e->color);*/
 
1079
    e++;
1054
1080
  }
1055
1081
}
1056
1082
 
1057
 
#if _SEARCH_HISTORY
1058
1083
/*
1059
1084
 * fmg 8/20/97
1060
1085
 * 'accumulate' one line of ELM's into a string
1061
1086
 * WHY: need this in search function to see if line contains search pattern
1062
1087
 */
1063
 
void wdrawelm_var(w, e, buf)
1064
 
WIN *w;
1065
 
ELM *e;
1066
 
char *buf;
 
1088
void wdrawelm_var(WIN *w, ELM *e, wchar_t *buf)
1067
1089
{
1068
 
  int x,c=0;
 
1090
  int x, c = 0;
1069
1091
 
1070
1092
  /* MARK updated 02/17/94 - Fixes bug, to do all 80 cols, not 79 cols */
1071
 
  for(x = w->x1; x <= w->x2; x++)
1072
 
  {
1073
 
        buf[c++]=e->value;
1074
 
        e++;
 
1093
  for (x = w->x1; x <= w->x2; x++) {
 
1094
    buf[c++] = e->value;
 
1095
    e++;
1075
1096
  }
1076
1097
}
1077
 
#endif /*SEARCH_HISTORY*/
1078
1098
 
1079
1099
/*
1080
1100
 * fmg 8/20/97
1081
1101
 * 'draw' one line of ELM's in a window INVERTED (text-mode-wise)
1082
1102
 * WHY: need this in search function to see if line contains search pattern
1083
1103
 */
1084
 
void wdrawelm_inverse(w, y, e)
1085
 
WIN *w;
1086
 
int y;
1087
 
ELM *e;
 
1104
void wdrawelm_inverse(WIN *w, int y, ELM *e)
1088
1105
{
1089
1106
  int x;
1090
1107
 
1097
1114
  e++;
1098
1115
 
1099
1116
  /* everything in the middle will be BLINK */
1100
 
  for(x = (w->x1+1); x <= (w->x2-1); x++)
1101
 
  {
1102
 
        _write(e->value, w->direct, x, y + w->y1, XA_BOLD, WHITE);
1103
 
        e++;
 
1117
  for (x = w->x1 + 1; x <= w->x2 - 1; x++) {
 
1118
    _write(e->value, w->direct, x, y + w->y1, XA_BOLD, WHITE);
 
1119
    e++;
1104
1120
  }
1105
1121
 
1106
1122
  /* last position */
1111
1127
/*
1112
1128
 * Print a string in a window.
1113
1129
 */
1114
 
void wputs(win, s)
1115
 
WIN *win;
1116
 
char *s;
 
1130
void wputs(WIN *win, const char *s)
1117
1131
{
1118
1132
  _intern = 1;
1119
1133
 
1120
 
  while(*s) wputc(win, *s++);
1121
 
  if (dirflush && win->direct) wflush();
 
1134
  while (*s) {
 
1135
    wchar_t wc;
 
1136
 
 
1137
    s += one_mbtowc(&wc, s, MB_LEN_MAX);
 
1138
    wputc(win, wc);
 
1139
  }
 
1140
  if (dirflush && win->direct)
 
1141
    wflush();
1122
1142
  _intern = 0;
1123
1143
}
1124
1144
 
1126
1146
 * Print a formatted string in a window.
1127
1147
 * Should return stringlength - but who cares.
1128
1148
 */
1129
 
/*VARARGS1*/
1130
 
int wprintf(win, s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
1131
 
WIN *win;
1132
 
char *s, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9, *a10;
 
1149
int wprintf(WIN *win, const char *fmt, ...)
1133
1150
{
1134
1151
  char buf[160];
1135
 
  char *t;
1136
 
 
1137
 
  t = buf;
1138
 
 
1139
 
  _intern = 1;
1140
 
  snprintf(buf, sizeof(buf), s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
1141
 
  while(*t) wputc(win, *t++);
1142
 
  _intern = 0;
1143
 
  if (dirflush && win->direct) wflush();
1144
 
 
1145
 
  return(0);
 
1152
  va_list va;
 
1153
 
 
1154
  va_start(va, fmt);
 
1155
  vsnprintf(buf, sizeof(buf), fmt, va);
 
1156
  va_end(va);
 
1157
  wputs(win, buf);
 
1158
 
 
1159
  return 0;
1146
1160
}
1147
1161
 
1148
1162
/*
1149
1163
 * Sound a bell.
1150
1164
 */
1151
 
void wbell()
 
1165
void wbell(void)
1152
1166
{
1153
 
  if (BL != CNULL)
1154
 
        outstr(BL);
1155
 
  else if (VB != CNULL)
1156
 
        outstr(VB);
 
1167
  if (BL != NULL)
 
1168
    outstr(BL);
 
1169
  else if (VB != NULL)
 
1170
    outstr(VB);
1157
1171
  else
1158
 
        (void) outchar('\007');
 
1172
    outchar('\007');
1159
1173
  wflush();
1160
1174
}
1161
1175
 
1162
1176
/*
1163
1177
 * Set cursor type.
1164
1178
 */
1165
 
void wcursor(win, type)
1166
 
WIN *win;
1167
 
int type;
 
1179
void wcursor(WIN *win, int type)
1168
1180
{
1169
1181
  win->cursor = type;
1170
1182
  if (win->direct) {
1171
 
        _cursor(type);
1172
 
        if (dirflush) wflush();
 
1183
    _cursor(type);
 
1184
    if (dirflush)
 
1185
      wflush();
1173
1186
  }
1174
1187
}
1175
1188
 
1176
 
void wtitle(w, pos, s)
1177
 
WIN *w;
1178
 
int pos;
1179
 
char *s;
 
1189
void wtitle(WIN *w, int pos, const char *s)
1180
1190
{
1181
1191
  int x = 0;
1182
1192
 
1183
1193
#ifdef SMOOTH
1184
 
  curwin = NIL_WIN;
 
1194
  curwin = NULL;
1185
1195
#endif
1186
1196
 
1187
 
  if (w->border == BNONE) return;
1188
 
  
1189
 
  if (pos == TLEFT) x = w->x1;
1190
 
  if (pos == TRIGHT) x = w->x2 - strlen(s) - 1;
1191
 
  if (pos == TMID) x = w->x1 + (w->xs - strlen(s)) / 2 - 1;
1192
 
  if (x < w->x1) x = w->x1;
1193
 
 
1194
 
  if (x < w->x2) _write('[', w->direct, x++, w->y1 - 1, w->attr, w->color);
1195
 
  while(*s && x <= w->x2) _write(*s++, w->direct, x++, w->y1 - 1,
1196
 
                w->attr, w->color);
1197
 
  if (x <= w->x2) _write(']', w->direct, x++, w->y1 - 1, w->attr, w->color);
 
1197
  if (w->border == BNONE)
 
1198
    return;
 
1199
 
 
1200
  if (pos == TLEFT)
 
1201
    x = w->x1;
 
1202
  if (pos == TRIGHT)
 
1203
    x = w->x2 - mbslen(s) - 1;
 
1204
  if (pos == TMID)
 
1205
    x = w->x1 + (w->xs - mbslen(s)) / 2 - 1;
 
1206
  if (x < w->x1)
 
1207
    x = w->x1;
 
1208
 
 
1209
  if (x < w->x2)
 
1210
    _write('[', w->direct, x++, w->y1 - 1, w->attr, w->color);
 
1211
  while (*s && x <= w->x2) {
 
1212
    wchar_t wc;
 
1213
 
 
1214
    s += one_mbtowc(&wc, s, MB_LEN_MAX);
 
1215
    _write(wc, w->direct, x++, w->y1 - 1, w->attr, w->color);
 
1216
  }
 
1217
  if (x <= w->x2)
 
1218
    _write(']', w->direct, x++, w->y1 - 1, w->attr, w->color);
1198
1219
 
1199
1220
  if (w->direct) {
1200
 
        _gotoxy(w->x1 + w->curx, w->y1 + w->cury);
1201
 
        if (dirflush) wflush();
 
1221
    _gotoxy(w->x1 + w->curx, w->y1 + w->cury);
 
1222
    if (dirflush)
 
1223
      wflush();
1202
1224
  }
1203
1225
}
1204
1226
 
1208
1230
/*
1209
1231
 * Change attributes of one line of a window.
1210
1232
 */
1211
 
void wcurbar(w, y, attr)
1212
 
WIN *w;
1213
 
int y;
1214
 
int attr;
 
1233
void wcurbar(WIN *w, int y, int attr)
1215
1234
{
1216
1235
  ELM *e;
1217
1236
  int x;
1223
1242
  y += w->y1;
1224
1243
 
1225
1244
  e = gmap + y * COLS + w->x1;
1226
 
  
 
1245
 
1227
1246
  /* If we can't do reverse, just put a '>' in front of
1228
1247
   * the line. We only support XA_NORMAL & XA_REVERSE.
1229
1248
   */
1230
 
  if (!useattr || MR == CNULL) {
1231
 
        if (attr & XA_REVERSE)
1232
 
                x = '>';
1233
 
        else
1234
 
                x = ' ';
1235
 
        _write(x, w->direct, w->x1, y, attr, e->color);
 
1249
  if (!useattr || MR == NULL) {
 
1250
    if (attr & XA_REVERSE)
 
1251
      x = '>';
 
1252
    else
 
1253
      x = ' ';
 
1254
    _write(x, w->direct, w->x1, y, attr, e->color);
1236
1255
  } else {
1237
 
        for(x = w->x1; x <= w->x2; x++) {
1238
 
                _write(e->value, w->direct, x, y, attr, e->color);
1239
 
                e++;
1240
 
        }
 
1256
    for (x = w->x1; x <= w->x2; x++) {
 
1257
      _write(e->value, w->direct, x, y, attr, e->color);
 
1258
      e++;
 
1259
    }
1241
1260
  }
1242
 
  if ((VI == CNULL || _curstype == CNORMAL) && w->direct)
1243
 
        _gotoxy(w->x1, y);
1244
 
  if (w->direct) wflush();
 
1261
  if ((VI == NULL || _curstype == CNORMAL) && w->direct)
 
1262
    _gotoxy(w->x1, y);
 
1263
  if (w->direct)
 
1264
    wflush();
1245
1265
}
1246
1266
 
1247
1267
/*
1248
1268
 * wselect - select one of many choices.
1249
1269
 */
1250
 
int wselect(x, y, choices, funlist, title, attr, fg, bg)
1251
 
int x, y;
1252
 
char **choices;
1253
 
void (**funlist)();
1254
 
char *title;
1255
 
int attr, fg, bg;
 
1270
int wselect(int x, int y, const char *const *choices,
 
1271
            void (*const *funlist)(void),
 
1272
            const char *title, int attr, int fg, int bg)
1256
1273
{
1257
 
  char **a = choices;
 
1274
  const char *const *a = choices;
1258
1275
  unsigned int len = 0;
1259
1276
  int count = 0;
1260
1277
  int cur = 0;
1262
1279
  WIN *w;
1263
1280
  int high_on = XA_REVERSE | attr;
1264
1281
  int high_off = attr;
1265
 
  
 
1282
 
1266
1283
  /* first count how many, and max. width. */
1267
1284
 
1268
 
  while (*a != CNULL) {
1269
 
        count++;
1270
 
        if (strlen(_(*a)) > len)
1271
 
              len = strlen(_(*a));
1272
 
        a++;
 
1285
  while (*a != NULL) {
 
1286
    count++;
 
1287
    if (mbslen(_(*a)) > len)
 
1288
      len = mbslen(_(*a));
 
1289
    a++;
1273
1290
  }
1274
 
  if (title != CNULL && strlen(title) + 2 > len)
1275
 
        len = strlen(title) + 2;
 
1291
  if (title != NULL && mbslen(title) + 2 > len)
 
1292
    len = mbslen(title) + 2;
1276
1293
  if (attr & XA_REVERSE) {
1277
 
        high_on = attr & ~XA_REVERSE;
1278
 
        high_off = attr;
 
1294
    high_on = attr & ~XA_REVERSE;
 
1295
    high_off = attr;
1279
1296
  }
1280
1297
 
1281
 
  if ((w = wopen(x, y, x + len + 2, y + count - 1, BDOUBLE,
1282
 
        attr, fg, bg, 0, 0, 0)) == (WIN *)0) return(-1);
 
1298
  if ((w = wopen(x, y, x + len + 2, y + count - 1,
 
1299
                 BDOUBLE, attr, fg, bg, 0, 0, 0)) == NULL)
 
1300
    return -1;
1283
1301
  wcursor(w, CNONE);
1284
1302
 
1285
 
  if (title != CNULL) wtitle(w, TMID, title);
 
1303
  if (title != NULL)
 
1304
    wtitle(w, TMID, title);
1286
1305
 
1287
 
  for(c = 0; c < count; c++) {
1288
 
        wprintf(w, " %s%s", _(choices[c]), c == count - 1 ? "" : "\n");
1289
 
  }
 
1306
  for (c = 0; c < count; c++)
 
1307
    wprintf(w, " %s%s", _(choices[c]), c == count - 1 ? "" : "\n");
1290
1308
 
1291
1309
  wcurbar(w, cur, high_on);
1292
1310
  wredraw(w, 1);
1293
1311
 
1294
1312
  while (1) {
1295
 
        while((c = wxgetch()) != 27 && c != '\n' && c!= '\r' && c != ' ') {
1296
 
                if (c == K_UP || c == K_DN || c == 'j' || c == 'k' ||
1297
 
                    c == K_HOME || c == K_END)
1298
 
                        wcurbar(w, cur, high_off);
1299
 
                switch(c) {
1300
 
                        case K_UP:
1301
 
                        case 'k':
1302
 
                                cur--;
1303
 
                                if (cur < 0) cur = count - 1;
1304
 
                                break;
1305
 
                        case K_DN:
1306
 
                        case 'j':
1307
 
                                cur++;
1308
 
                                if (cur >= count) cur = 0;
1309
 
                                break;
1310
 
                        case K_HOME:
1311
 
                                cur = 0;
1312
 
                                break;
1313
 
                        case K_END:
1314
 
                                cur = count - 1;
1315
 
                                break;
1316
 
                }
1317
 
                if (c == K_UP || c == K_DN || c == 'j' || c == 'k' ||
1318
 
                    c == K_HOME || c == K_END)
1319
 
                        wcurbar(w, cur, high_on);
1320
 
        }
1321
 
        wcursor(w, CNORMAL);
1322
 
        if (c == ' ' || c == 27) {
1323
 
                wclose(w, 1);
1324
 
                return(0);
1325
 
        }
1326
 
        if (funlist == NIL_FUNLIST || funlist[cur] == NIL_FUN) {
1327
 
                wclose(w, 1);
1328
 
                return(cur + 1);
1329
 
        }
1330
 
        (*funlist[cur])();
1331
 
        wcursor(w, CNONE);
 
1313
    while ((c = wxgetch()) != 27 && c != '\n' && c!= '\r' && c != ' ') {
 
1314
      if (c == K_UP || c == K_DN || c == 'j' || c == 'k' ||
 
1315
          c == K_HOME || c == K_END)
 
1316
        wcurbar(w, cur, high_off);
 
1317
      switch (c) {
 
1318
        case K_UP:
 
1319
        case 'k':
 
1320
          cur--;
 
1321
          if (cur < 0)
 
1322
            cur = count - 1;
 
1323
          break;
 
1324
        case K_DN:
 
1325
        case 'j':
 
1326
          cur++;
 
1327
          if (cur >= count)
 
1328
            cur = 0;
 
1329
          break;
 
1330
        case K_HOME:
 
1331
          cur = 0;
 
1332
          break;
 
1333
        case K_END:
 
1334
          cur = count - 1;
 
1335
          break;
 
1336
      }
 
1337
      if (c == K_UP || c == K_DN || c == 'j' || c == 'k' ||
 
1338
          c == K_HOME || c == K_END)
 
1339
        wcurbar(w, cur, high_on);
 
1340
    }
 
1341
    wcursor(w, CNORMAL);
 
1342
    if (c == ' ' || c == 27) {
 
1343
      wclose(w, 1);
 
1344
      return 0;
 
1345
    }
 
1346
    if (funlist == NULL || funlist[cur] == NULL) {
 
1347
      wclose(w, 1);
 
1348
      return cur + 1;
 
1349
    }
 
1350
    (*funlist[cur])();
 
1351
    wcursor(w, CNONE);
1332
1352
  }
1333
1353
}
1334
1354
 
1336
1356
/* ==== Clearing functions ==== */
1337
1357
 
1338
1358
/*
 
1359
 * Clear characters.
 
1360
 */
 
1361
void wclrch(WIN *w, int n)
 
1362
{
 
1363
  int x, y, x_end;
 
1364
 
 
1365
#ifdef SMOOTH
 
1366
  curwin = w;
 
1367
#endif
 
1368
 
 
1369
  y = w->cury + w->y1;
 
1370
  x = x_end = w->curx + w->x1;
 
1371
  x_end += n - 1;
 
1372
 
 
1373
  if (x_end > w->x2)
 
1374
    x_end = w->x2;
 
1375
 
 
1376
  if (w->direct)
 
1377
    _gotoxy(w->x1, y);
 
1378
 
 
1379
  for ( ; x <= x_end; x++)
 
1380
    _write(' ', w->direct, x, y, w->attr, w->color);
 
1381
 
 
1382
  if (w->direct && dirflush)
 
1383
    wflush();
 
1384
}
 
1385
 
 
1386
/*
1339
1387
 * Clear entire line.
1340
1388
 */
1341
 
void wclrel(w)
1342
 
WIN *w;
 
1389
void wclrel(WIN *w)
1343
1390
{
1344
1391
  int ocurx = w->curx;
1345
 
  
 
1392
 
1346
1393
  w->curx = 0;
1347
 
  (void) _wclreol(w);
 
1394
  _wclreol(w);
1348
1395
  w->curx = ocurx;
1349
1396
  wlocate(w, ocurx, w->cury);
1350
1397
}
1352
1399
/*
1353
1400
 * Clear to end of line.
1354
1401
 */
1355
 
void wclreol(w)
1356
 
WIN *w;
 
1402
void wclreol(WIN *w)
1357
1403
{
1358
 
  if (_wclreol(w) && w->direct) _gotoxy(w->x1 + w->curx, w->y1 + w->cury);
1359
 
  if (dirflush) wflush();
 
1404
  if (_wclreol(w) && w->direct)
 
1405
    _gotoxy(w->x1 + w->curx, w->y1 + w->cury);
 
1406
  if (dirflush)
 
1407
    wflush();
1360
1408
}
1361
1409
 
1362
1410
/*
1363
1411
 * Clear to begin of line
1364
1412
 */
1365
 
void wclrbol(w)
1366
 
WIN *w;
 
1413
void wclrbol(WIN *w)
1367
1414
{
1368
 
   int x, y, n;
1369
 
 
 
1415
  int x, y, n;
 
1416
 
1370
1417
#ifdef SMOOTH
1371
1418
  curwin = w;
1372
1419
#endif
1373
1420
 
1374
1421
  y = w->cury + w->y1;
1375
1422
 
1376
 
  if (w->direct) _gotoxy(w->x1, y);
1377
 
  
 
1423
  if (w->direct)
 
1424
    _gotoxy(w->x1, y);
 
1425
 
1378
1426
  n = w->x1 + w->curx;
1379
 
  if( n > w->x2) n = w->x2;
1380
 
  for(x = w->x1; x <= n; x++) _write(' ', w->direct, x, y,
1381
 
                w->attr, w->color);
 
1427
  if (n > w->x2)
 
1428
    n = w->x2;
 
1429
  for (x = w->x1; x <= n; x++)
 
1430
    _write(' ', w->direct, x, y, w->attr, w->color);
1382
1431
  if (w->direct) {
1383
 
        _gotoxy(n, y);
1384
 
        if (dirflush) wflush();
 
1432
    _gotoxy(n, y);
 
1433
    if (dirflush)
 
1434
      wflush();
1385
1435
  }
1386
1436
}
1387
1437
 
1388
1438
/*
1389
1439
 * Clear to end of screen
1390
1440
 */
1391
 
void wclreos(w)
1392
 
WIN *w;
 
1441
void wclreos(WIN *w)
1393
1442
{
1394
1443
  int y;
1395
1444
  int ocurx, ocury;
1396
 
  
 
1445
 
1397
1446
  ocurx = w->curx;
1398
1447
  ocury = w->cury;
1399
 
  
 
1448
 
1400
1449
  w->curx = 0;
1401
1450
 
1402
 
  for(y = w->cury + 1; y <= w->y2 - w->y1; y++) {
1403
 
        w->cury = y;
1404
 
        (void) _wclreol(w);
 
1451
  for (y = w->cury + 1; y <= w->y2 - w->y1; y++) {
 
1452
    w->cury = y;
 
1453
    _wclreol(w);
1405
1454
  }
1406
1455
  w->curx = ocurx;
1407
1456
  w->cury = ocury;
1408
 
  if (_wclreol(w) && w->direct) _gotoxy(w->x1 + w->curx, w->y1 + w->cury);
1409
 
  if (dirflush && w->direct) wflush();
 
1457
  if (_wclreol(w) && w->direct)
 
1458
    _gotoxy(w->x1 + w->curx, w->y1 + w->cury);
 
1459
  if (dirflush && w->direct)
 
1460
    wflush();
1410
1461
}
1411
1462
 
1412
1463
/*
1413
1464
 * Clear to begin of screen.
1414
1465
 */
1415
 
void wclrbos(w)
1416
 
WIN *w;
 
1466
void wclrbos(WIN *w)
1417
1467
{
1418
1468
  int ocurx, ocury;
1419
1469
  int y;
1420
 
  
 
1470
 
1421
1471
  ocurx = w->curx;
1422
1472
  ocury = w->cury;
1423
 
  
 
1473
 
1424
1474
  w->curx = 0;
1425
 
  
1426
 
  for(y = 0; y < ocury; y++) {
1427
 
        w->cury = y;
1428
 
        (void) _wclreol(w);
 
1475
 
 
1476
  for (y = 0; y < ocury; y++) {
 
1477
    w->cury = y;
 
1478
    _wclreol(w);
1429
1479
  }
1430
1480
  w->curx = ocurx;
1431
1481
  w->cury = ocury;
1435
1485
/*
1436
1486
 * Clear a window.
1437
1487
 */
1438
 
void winclr(w)
1439
 
WIN *w;
 
1488
void winclr(WIN *w)
1440
1489
{
1441
1490
  int y;
1442
1491
  int olddir = w->direct;
1443
 
#if HISTORY
1444
1492
  ELM *e, *f;
1445
1493
  int i;
1446
1494
  int m;
1447
1495
 
1448
1496
  /* If this window has history, save the image. */
1449
1497
  if (w->histbuf) {
1450
 
 
1451
 
        /* MARK updated 02/17/95 - Scan backwards from the bottom of the */
1452
 
        /* window for the first non-empty line.  We should save all other */
1453
 
        /* blank lines inside screen, since some nice BBS ANSI menus */
1454
 
        /* contains them for cosmetic purposes or as separators. */
1455
 
        for(m = w->y2; m >= w->y1; m--) {       
1456
 
                /* Start of this line in the global map. */
1457
 
                e = gmap + m * COLS + w->x1;
1458
 
 
1459
 
                /* Quick check to see if line is empty. */
1460
 
                for(i = 0; i < w->xs; i++)
1461
 
                        if (e[i].value != ' ') break;
1462
 
                        
1463
 
                if (i != w->xs) break; /* Non empty line */
1464
 
        }
1465
 
 
1466
 
        /* Copy window into history buffer line-by-line. */
1467
 
        for(y = w->y1; y <= m; y++) {
1468
 
                /* Start of this line in the global map. */
1469
 
                e = gmap + y * COLS + w->x1;
1470
 
 
1471
 
                /* Now copy this line. */
1472
 
                f = w->histbuf + (w->xs * w->histline); /* History buffer */
1473
 
                memcpy((char *)f, (char *)e, w->xs * sizeof(ELM));
1474
 
                w->histline++;
1475
 
                if (w->histline >= w->histlines) w->histline = 0;
1476
 
        }
 
1498
    /* MARK updated 02/17/95 - Scan backwards from the bottom of the */
 
1499
    /* window for the first non-empty line.  We should save all other */
 
1500
    /* blank lines inside screen, since some nice BBS ANSI menus */
 
1501
    /* contains them for cosmetic purposes or as separators. */
 
1502
    for (m = w->y2; m >= w->y1; m--) {
 
1503
      /* Start of this line in the global map. */
 
1504
      e = gmap + m * COLS + w->x1;
 
1505
 
 
1506
      /* Quick check to see if line is empty. */
 
1507
      for (i = 0; i < w->xs; i++)
 
1508
        if (e[i].value != ' ')
 
1509
          break;
 
1510
 
 
1511
      if (i != w->xs)
 
1512
        break; /* Non empty line */
 
1513
    }
 
1514
 
 
1515
    /* Copy window into history buffer line-by-line. */
 
1516
    for (y = w->y1; y <= m; y++) {
 
1517
      /* Start of this line in the global map. */
 
1518
      e = gmap + y * COLS + w->x1;
 
1519
 
 
1520
      /* Now copy this line. */
 
1521
      f = w->histbuf + (w->xs * w->histline); /* History buffer */
 
1522
      memcpy((char *)f, (char *)e, w->xs * sizeof(ELM));
 
1523
      w->histline++;
 
1524
      if (w->histline >= w->histlines)
 
1525
        w->histline = 0;
 
1526
    }
1477
1527
  }
1478
 
#endif
1479
1528
 
1480
1529
  _setattr(w->attr, w->color);
1481
1530
  w->curx = 0;
1482
1531
 
1483
 
  if (CL && w->y1 == 0 && w->y2 == LINES-1 &&
1484
 
            w->x1 == 0 && w->x2 == COLS-1) {
1485
 
        w->direct = 0;
1486
 
        curx = 0;
1487
 
        cury = 0;
1488
 
        outstr(CL);
 
1532
  if (CL && w->y1 == 0 && w->y2 == LINES-1 && w->x1 == 0 && w->x2 == COLS-1) {
 
1533
    w->direct = 0;
 
1534
    curx = 0;
 
1535
    cury = 0;
 
1536
    outstr(CL);
1489
1537
  }
1490
 
  for(y = w->ys - 1; y >= 0; y--) {
1491
 
        w->cury = y;
1492
 
        (void) _wclreol(w);
 
1538
  for (y = w->ys - 1; y >= 0; y--) {
 
1539
    w->cury = y;
 
1540
    _wclreol(w);
1493
1541
  }
1494
1542
  w->direct = olddir;
1495
1543
  _gotoxy(w->x1, w->y1);
1496
 
  if (dirflush) wflush();
 
1544
  if (dirflush)
 
1545
    wflush();
1497
1546
}
1498
1547
 
1499
1548
/* ==== Insert / Delete functions ==== */
1500
1549
 
1501
 
void winsline(w)
1502
 
WIN *w;
 
1550
void winsline(WIN *w)
1503
1551
{
1504
1552
  int osy1, osy2;
1505
 
  
 
1553
 
1506
1554
  osy1 = w->sy1;
1507
1555
  osy2 = w->sy2;
1508
 
  
 
1556
 
1509
1557
  w->sy1 = w->y1 + w->cury;
1510
1558
  w->sy2 = w->y2;
1511
 
  if (w->sy1 < osy1) w->sy1 = osy1;
1512
 
  if (w->sy2 > osy2) w->sy2 = osy2;
 
1559
  if (w->sy1 < osy1)
 
1560
    w->sy1 = osy1;
 
1561
  if (w->sy2 > osy2)
 
1562
    w->sy2 = osy2;
1513
1563
  wscroll(w, S_DOWN);
1514
 
  
 
1564
 
1515
1565
  w->sy1 = osy1;
1516
1566
  w->sy2 = osy2;
1517
1567
}
1518
1568
 
1519
 
void wdelline(w)
1520
 
WIN *w;
 
1569
void wdelline(WIN *w)
1521
1570
{
1522
1571
  int osy1, osy2;
1523
1572
  int ocury;
1524
 
  
 
1573
 
1525
1574
  ocury = w->cury;
1526
1575
  osy1 = w->sy1;
1527
1576
  osy2 = w->sy2;
1528
 
  
 
1577
 
1529
1578
  w->sy1 = w->y1 + w->cury;
1530
1579
  w->sy2 = w->y2;
1531
 
  if (w->sy1 < osy1) w->sy1 = osy1;
1532
 
  if (w->sy2 > osy2) w->sy2 = osy2;
1533
 
  
 
1580
  if (w->sy1 < osy1)
 
1581
    w->sy1 = osy1;
 
1582
  if (w->sy2 > osy2)
 
1583
    w->sy2 = osy2;
 
1584
 
1534
1585
  _intern = 1;
1535
1586
  wscroll(w, S_UP);
1536
1587
  _intern = 0;
1543
1594
/*
1544
1595
 * Insert a space at cursor position.
1545
1596
 */
1546
 
void winschar2(w, c, move)
1547
 
WIN *w;
1548
 
int c;
1549
 
int move;
 
1597
void winschar2(WIN *w, wchar_t c, int move)
1550
1598
{
1551
1599
  int y;
1552
1600
  int x;
1553
1601
  int doit = 1;
1554
 
  ELM buf[160];
1555
 
  ELM *e;
 
1602
  ELM *buf, *e;
1556
1603
  int len, odir;
1557
1604
  int oldx;
1558
1605
 
1561
1608
#endif
1562
1609
 
1563
1610
  /* See if we need to insert. */
1564
 
  if (c == 0 || strchr("\r\n\t\b\007", c) || w->curx >= w->xs - 1) {
1565
 
        wputc(w, c);
1566
 
        return;
 
1611
  if (c == 0 || wcschr(L"\r\n\t\b\007", c) || w->curx >= w->xs - 1) {
 
1612
    wputc(w, c);
 
1613
    return;
1567
1614
  }
1568
1615
 
1569
1616
  odir = w->direct;
1570
 
  if (w->xs == COLS && IC != CNULL) {
1571
 
        /* We can use the insert character capability. */
1572
 
        if (w->direct) outstr(IC);
1573
 
 
1574
 
        /* No need to draw the character if it's a space. */
1575
 
        if (c == ' ') w->direct = 0;
1576
 
 
1577
 
        /* We don't need to draw the new line at all. */
1578
 
        doit = 0;
 
1617
  if (w->xs == COLS && IC != NULL) {
 
1618
    /* We can use the insert character capability. */
 
1619
    if (w->direct)
 
1620
      outstr(IC);
 
1621
 
 
1622
    /* No need to draw the character if it's a space. */
 
1623
    if (c == ' ')
 
1624
      w->direct = 0;
 
1625
 
 
1626
    /* We don't need to draw the new line at all. */
 
1627
    doit = 0;
1579
1628
  }
1580
 
  
 
1629
 
1581
1630
  /* Get the rest of line into buffer */
1582
1631
  y = w->y1 + w->cury;
1583
1632
  x = w->x1 + w->curx;
1584
1633
  oldx = w->curx;
1585
1634
  len = w->xs - w->curx;
 
1635
 
 
1636
  buf = malloc(sizeof(ELM) * len);
 
1637
  if (!buf)
 
1638
    return; /* Umm... */
1586
1639
  memcpy(buf, gmap + COLS * y + x, sizeof(ELM) * len);
1587
1640
 
1588
1641
  /* Now, put the new character on screen. */
1589
1642
  wputc(w, c);
1590
 
  if (!move) w->curx = oldx;
 
1643
  if (!move)
 
1644
    w->curx = oldx;
1591
1645
 
1592
1646
  /* Write buffer to screen */
1593
1647
  e = buf;
1594
 
  for(++x; x <= w->x2; x++) {
1595
 
        _write(e->value, doit && w->direct, x, y, e->attr, e->color);
1596
 
        e++;
 
1648
  for (++x; x <= w->x2; x++) {
 
1649
    _write(e->value, doit && w->direct, x, y, e->attr, e->color);
 
1650
    e++;
1597
1651
  }
 
1652
  free(buf);
 
1653
 
1598
1654
  w->direct = odir;
1599
1655
  wlocate(w, w->curx, w->cury);
1600
1656
}
1601
1657
 
1602
 
void winschar(w)
1603
 
WIN *w;
 
1658
void winschar(WIN *w)
1604
1659
{
1605
1660
  winschar2(w, ' ', 0);
1606
1661
}
1608
1663
/*
1609
1664
 * Delete character under the cursor.
1610
1665
 */
1611
 
void wdelchar(w)
1612
 
WIN *w;
 
1666
void wdelchar(WIN *w)
1613
1667
{
1614
1668
  int x, y;
1615
1669
  int doit = 1;
1621
1675
 
1622
1676
  x = w->x1 + w->curx;
1623
1677
  y = w->y1 + w->cury;
1624
 
  
1625
 
  if (w->direct && w->xs == COLS && DC != CNULL) {
1626
 
        /*_gotoxy(x - 1, y);*/
1627
 
        _gotoxy(x, y);
1628
 
        outstr(DC);
1629
 
        doit = 0;
 
1678
 
 
1679
  if (w->direct && w->xs == COLS && DC != NULL) {
 
1680
    /*_gotoxy(x - 1, y);*/
 
1681
    _gotoxy(x, y);
 
1682
    outstr(DC);
 
1683
    doit = 0;
1630
1684
  }
1631
 
  
 
1685
 
1632
1686
  e = gmap + y * COLS + x + 1;
1633
 
  
1634
 
  for(; x < w->x2; x++) {
1635
 
        _write(e->value, doit && w->direct, x, y, e->attr, e->color);
1636
 
        e++;
 
1687
 
 
1688
  for (; x < w->x2; x++) {
 
1689
    _write(e->value, doit && w->direct, x, y, e->attr, e->color);
 
1690
    e++;
1637
1691
  }
1638
1692
  _write(' ', doit && w->direct, x, y, w->attr, w->color);
1639
1693
  wlocate(w, w->curx, w->cury);
1642
1696
/* ============= Support: edit a line on the screen. ============ */
1643
1697
 
1644
1698
/* Redraw the line we are editting. */
1645
 
static void lredraw(w, x, y, s, len)
1646
 
WIN *w;
1647
 
int x;
1648
 
int y;
1649
 
char *s;
1650
 
int len;
 
1699
static void lredraw(WIN *w, int x, int y, wchar_t *s, int len)
1651
1700
{
1652
1701
  int i, f;
1653
1702
 
1654
1703
  i = 0;
1655
1704
  wlocate(w, x, y);
1656
 
  for(f = 0; f < len; f++) {
1657
 
        if (s[f] == 0) i++;
1658
 
        wputc(w, i ? ' ' : s[f]);
 
1705
  for (f = 0; f < len; f++) {
 
1706
    if (s[f] == 0)
 
1707
      i++;
 
1708
    wputc(w, i ? ' ' : s[f]);
1659
1709
  }
1660
1710
}
1661
1711
 
1665
1715
#  define BUFLEN 256
1666
1716
#endif
1667
1717
 
1668
 
/* wgets - edit one line in a window. */
1669
 
int wgets(w, s, linelen, maxlen)
1670
 
WIN *w;
1671
 
char *s;
1672
 
int linelen;
1673
 
int maxlen;
 
1718
/* wgetwcs - edit one line in a window. */
 
1719
int wgetwcs(WIN *w, wchar_t *s, int linelen, int maxlen)
1674
1720
{
1675
1721
  int c;
1676
1722
  int idx;
1677
1723
  int offs = 0;
1678
1724
  int f, st = 0, i;
1679
 
  char buf[BUFLEN];
 
1725
  wchar_t buf[BUFLEN];
1680
1726
  int quit = 0;
1681
1727
  int once = 1;
1682
1728
  int x, y, r;
1687
1733
  y = w->cury;
1688
1734
 
1689
1735
  i = w->xs - x;
1690
 
  if (linelen >= i - 1) linelen = i - 1;
 
1736
  if (linelen >= i - 1)
 
1737
    linelen = i - 1;
1691
1738
 
1692
1739
  /* We assume the line has already been drawn on the screen. */
1693
 
  if ((idx = strlen(s)) > linelen)
1694
 
        idx = linelen;
1695
 
  strncpy(buf, s, sizeof(buf));
 
1740
  if ((idx = wcslen(s)) > linelen)
 
1741
    idx = linelen;
 
1742
  wcsncpy(buf, s, sizeof(buf) / sizeof(*buf));
1696
1743
  wlocate(w, x + idx, y);
1697
1744
  dirflush = 0;
1698
1745
  wflush();
1699
1746
 
1700
 
  while(!quit) {
1701
 
        if (once) {
1702
 
                c = K_END;
1703
 
                once--;
1704
 
        } else {
1705
 
                c = wxgetch();
1706
 
                if (c > 255 || c == K_BS || c == K_DEL) delete = 0;
1707
 
        }
1708
 
        switch(c) {
1709
 
                case '\r':
1710
 
                case '\n':
1711
 
                        st = 0;
1712
 
                        quit = 1;
1713
 
                        break;
1714
 
                case K_ESC: /* Exit without changing. */
1715
 
                        wlocate(w, x, y);
1716
 
                        lredraw(w, x, y, s, linelen);
1717
 
                        wflush();
1718
 
                        st = -1;
1719
 
                        quit = 1;
1720
 
                        break;
1721
 
                case K_HOME: /* Home */
1722
 
                        r = (offs > 0);
1723
 
                        offs = 0;
1724
 
                        idx = 0;
1725
 
                        if (r) lredraw(w, x, y, buf, linelen);
1726
 
                        wlocate(w, x, y);
1727
 
                        wflush();
1728
 
                        break;
1729
 
                case K_END: /* End of line. */
1730
 
                        idx = strlen(buf);
1731
 
                        r = 0;
1732
 
                        while(idx - offs > linelen) {
1733
 
                                r = 1;
1734
 
                                offs += 4;
1735
 
                        }
1736
 
                        if (r) lredraw(w, x, y, buf + offs, linelen);
1737
 
                        wlocate(w, x + idx - offs, y);
1738
 
                        wflush();
1739
 
                        break;
1740
 
                case K_LT: /* Cursor left. */
1741
 
                case K_BS: /* Backspace is first left, then DEL. */
1742
 
                        if (idx == 0) break;
1743
 
                        idx--;
1744
 
                        if (idx < offs) {
1745
 
                                offs -= 4;
1746
 
                                /*if (c == K_LT) FIXME? */
1747
 
                                        lredraw(w, x, y, buf + offs, linelen);
1748
 
                        }
1749
 
                        if(c == K_LT) {
1750
 
                                wlocate(w, x + idx - offs, y);
1751
 
                                wflush();
1752
 
                                break;
1753
 
                        }
1754
 
                        /*FALLTHRU*/
1755
 
                case K_DEL: /* Delete character under cursor. */
1756
 
                        if (buf[idx] == 0) break;
1757
 
                        for(f = idx; buf[f]; f++)
1758
 
                                buf[f] = buf[f+1];
1759
 
                        lredraw(w, x + idx - offs, y, buf + idx,
1760
 
                                linelen - (idx - offs));
1761
 
                        wlocate(w, x + idx - offs, y);
1762
 
                        wflush();
1763
 
                        break;
1764
 
                case K_RT:
1765
 
                        if (buf[idx] == 0) break;
1766
 
                        idx++;
1767
 
                        if (idx - offs > linelen) {
1768
 
                                offs += 4;
1769
 
                                lredraw(w, x, y, buf + offs, linelen);
1770
 
                        }
1771
 
                        wlocate(w, x + idx - offs, y);
1772
 
                        wflush();
1773
 
                        break;
1774
 
                default:
1775
 
                        /* If delete == 1, delete the buffer. */
1776
 
                        if (delete) {
1777
 
                                if ((i = strlen(buf)) > linelen)
1778
 
                                        i = linelen;
1779
 
                                buf[0] = 0;
1780
 
                                idx = 0;
1781
 
                                offs = 0;
1782
 
                                wlocate(w, x, y);
1783
 
                                for(f = 0; f < i; f++) wputc(w, ' ');
1784
 
                                delete = 0;
1785
 
                        }
 
1747
  while (!quit) {
 
1748
    if (once) {
 
1749
      c = K_END;
 
1750
      once--;
 
1751
    } else {
 
1752
      c = wxgetch();
 
1753
      if (c > 255 || c == K_BS || c == K_DEL)
 
1754
        delete = 0;
 
1755
    }
 
1756
    switch(c) {
 
1757
      case '\r':
 
1758
      case '\n':
 
1759
        st = 0;
 
1760
        quit = 1;
 
1761
        break;
 
1762
      case K_ESC: /* Exit without changing. */
 
1763
        wlocate(w, x, y);
 
1764
        lredraw(w, x, y, s, linelen);
 
1765
        wflush();
 
1766
        st = -1;
 
1767
        quit = 1;
 
1768
        break;
 
1769
      case K_HOME: /* Home */
 
1770
        r = offs > 0;
 
1771
        offs = 0;
 
1772
        idx = 0;
 
1773
        if (r)
 
1774
          lredraw(w, x, y, buf, linelen);
 
1775
        wlocate(w, x, y);
 
1776
        wflush();
 
1777
        break;
 
1778
      case K_END: /* End of line. */
 
1779
        idx = wcslen(buf);
 
1780
        r = 0;
 
1781
        while (idx - offs > linelen) {
 
1782
          r = 1;
 
1783
          offs += 4;
 
1784
        }
 
1785
        if (r)
 
1786
          lredraw(w, x, y, buf + offs, linelen);
 
1787
        wlocate(w, x + idx - offs, y);
 
1788
        wflush();
 
1789
        break;
 
1790
      case K_LT: /* Cursor left. */
 
1791
      case K_BS: /* Backspace is first left, then DEL. */
 
1792
        if (idx == 0)
 
1793
          break;
 
1794
        idx--;
 
1795
        if (idx < offs) {
 
1796
          offs -= 4;
 
1797
          /*if (c == K_LT) FIXME? */
 
1798
          lredraw(w, x, y, buf + offs, linelen);
 
1799
        }
 
1800
        if (c == K_LT) {
 
1801
          wlocate(w, x + idx - offs, y);
 
1802
          wflush();
 
1803
          break;
 
1804
        }
 
1805
        /*FALLTHRU*/
 
1806
      case K_DEL: /* Delete character under cursor. */
 
1807
        if (buf[idx] == 0)
 
1808
          break;
 
1809
        for (f = idx; buf[f]; f++)
 
1810
          buf[f] = buf[f+1];
 
1811
        lredraw(w, x + idx - offs, y, buf + idx, linelen - (idx - offs));
 
1812
        wlocate(w, x + idx - offs, y);
 
1813
        wflush();
 
1814
        break;
 
1815
      case K_RT:
 
1816
        if (buf[idx] == 0)
 
1817
          break;
 
1818
        idx++;
 
1819
        if (idx - offs > linelen) {
 
1820
          offs += 4;
 
1821
          lredraw(w, x, y, buf + offs, linelen);
 
1822
        }
 
1823
        wlocate(w, x + idx - offs, y);
 
1824
        wflush();
 
1825
        break;
 
1826
      default:
 
1827
        /* If delete == 1, delete the buffer. */
 
1828
        if (delete) {
 
1829
          if ((i = wcslen(buf)) > linelen)
 
1830
            i = linelen;
 
1831
          buf[0] = 0;
 
1832
          idx = 0;
 
1833
          offs = 0;
 
1834
          wlocate(w, x, y);
 
1835
          for (f = 0; f < i; f++)
 
1836
            wputc(w, ' ');
 
1837
          delete = 0;
 
1838
        }
1786
1839
 
1787
 
                        /* Insert character at cursor position. */
1788
 
                        if (c < 32 || c > 255) break;
1789
 
                        if (idx + 1 >= maxlen) break;
1790
 
                        for(f = strlen(buf) + 1; f > idx; f--)
1791
 
                                buf[f] = buf[f-1];
1792
 
                        i = buf[idx];
1793
 
                        buf[idx] = c;
1794
 
                        if (i == 0) buf[idx+1] = i;
1795
 
                        if (idx - offs >= linelen) {
1796
 
                                offs += 4;
1797
 
                                lredraw(w, x, y, buf + offs, linelen);
1798
 
                        } else
1799
 
                                lredraw(w, x + idx - offs, y, buf + idx,
1800
 
                                        linelen - (idx - offs));
1801
 
                        idx++;
1802
 
                        wlocate(w, x + idx - offs, y);
1803
 
                        wflush();
1804
 
                        break;
 
1840
        /* Insert character at cursor position. */
 
1841
        if (c < 32 || c > 255)
 
1842
          break;
 
1843
        f = wcslen(buf) + 2;
 
1844
        if (f >= maxlen)
 
1845
          break;
 
1846
        while (f > idx) {
 
1847
          buf[f] = buf[f-1];
 
1848
          f--;
1805
1849
        }
 
1850
        buf[idx] = c;
 
1851
        if (idx - offs >= linelen) {
 
1852
          offs += 4;
 
1853
          lredraw(w, x, y, buf + offs, linelen);
 
1854
        } else
 
1855
          lredraw(w, x + idx - offs, y, buf + idx, linelen - (idx - offs));
 
1856
        idx++;
 
1857
        wlocate(w, x + idx - offs, y);
 
1858
        wflush();
 
1859
        break;
 
1860
    }
1806
1861
  }
1807
 
  if (st == 0) strcpy(s, buf);
 
1862
  if (st == 0)
 
1863
    wcscpy(s, buf);
1808
1864
  dirflush = direct;
1809
 
  return(st);
 
1865
  return st;
 
1866
}
 
1867
 
 
1868
/* wgets - edit one line in a window. */
 
1869
int wgets(WIN *w, char *s, int linelen, int maxlen)
 
1870
{
 
1871
  int st;
 
1872
  wchar_t buf[BUFLEN];
 
1873
  size_t i;
 
1874
  char *sptr;
 
1875
 
 
1876
  sptr = s;
 
1877
  for (i = 0; *sptr != 0 && i < sizeof (buf) - 1; i++)
 
1878
    sptr += one_mbtowc(buf + i, sptr, MB_LEN_MAX);
 
1879
  buf[i] = 0;
 
1880
  st = wgetwcs(w, buf, linelen, maxlen);
 
1881
  if (st == 0) {
 
1882
    sptr = s;
 
1883
    for (i = 0; buf[i] != 0; i++)
 
1884
      {
 
1885
       char tmp[MB_LEN_MAX];
 
1886
       size_t l;
 
1887
 
 
1888
       /* This truncates data; too bad */
 
1889
       l = one_wctomb(tmp, buf[i]);
 
1890
       if (sptr + l >= s + maxlen)
 
1891
         break;
 
1892
       memcpy(sptr, tmp, l);
 
1893
       sptr += l;
 
1894
      }
 
1895
    *sptr = 0;
 
1896
  }
 
1897
  return st;
1810
1898
}
1811
1899
 
1812
1900
/* ==== Initialization code ==== */
1815
1903
static char cbuf[2048];
1816
1904
 
1817
1905
/* Map AC characters. */
1818
 
static int acmap(c)
1819
 
int c;
 
1906
static int acmap(int c)
1820
1907
{
1821
 
  char *p;
 
1908
  const char *p;
1822
1909
 
1823
 
  for(p = AC; *p; p += 2)
1824
 
        if (*p == c) return(*++p);
1825
 
  return('.');
 
1910
  for (p = AC; *p; p += 2)
 
1911
    if (*p == c)
 
1912
      return *++p;
 
1913
  return '.';
1826
1914
}
1827
1915
 
1828
1916
/*
1830
1918
 */
1831
1919
#ifdef BBS
1832
1920
/* Code for the BBS system.. */
1833
 
int win_init(term, lines)
1834
 
char *term;
1835
 
int lines;
 
1921
int win_init(char *term, int lines)
1836
1922
{
1837
1923
  int fg = WHITE;
1838
1924
  int bg = BLACK;
1839
1925
  int attr = XA_NORMAL;
1840
1926
#else
1841
1927
/* Code for other applications (minicom!) */
1842
 
int win_init(fg, bg, attr)
1843
 
int fg;
1844
 
int bg;
1845
 
int attr;
 
1928
int win_init(int fg, int bg, int attr)
1846
1929
{
1847
1930
  char *term;
1848
1931
#endif
1849
1932
  static WIN _stdwin;
1850
1933
  int f, olduseattr;
1851
1934
 
1852
 
  if (w_init) return(0);
 
1935
  if (w_init)
 
1936
    return 0;
1853
1937
 
1854
1938
#ifndef BBS
1855
 
  if ((term = getenv("TERM")) == CNULL) {
1856
 
        fprintf(stderr, _("Environment variable TERM not set\n"));
1857
 
        return(-1);
 
1939
  if ((term = getenv("TERM")) == NULL) {
 
1940
    fprintf(stderr, _("Environment variable TERM not set\n"));
 
1941
    return -1;
1858
1942
  }
1859
1943
#endif
1860
 
  switch((f = tgetent(cbuf, term))) {
1861
 
        case 0:
1862
 
                fprintf(stderr, _("No termcap entry for %s\n"), term);
1863
 
                return(-1);
1864
 
        case -1:
1865
 
                fprintf(stderr, _("No termcap database present!\n"));
1866
 
                return(-1);
1867
 
        default:
1868
 
                break;
 
1944
  switch ((f = tgetent(cbuf, term))) {
 
1945
    case 0:
 
1946
      fprintf(stderr, _("No termcap entry for %s\n"), term);
 
1947
      return -1 ;
 
1948
    case -1:
 
1949
      fprintf(stderr, _("No termcap database present!\n"));
 
1950
      return -1 ;
 
1951
    default:
 
1952
      break;
1869
1953
  }
1870
1954
  _tptr = tbuf;
1871
1955
 
1872
 
  if ((CM = tgetstr("cm", &_tptr)) == CNULL) {
1873
 
        fprintf(stderr, _("No cursor motion capability (cm)\n"));
1874
 
        return(-1);
 
1956
  if ((CM = tgetstr("cm", &_tptr)) == NULL) {
 
1957
    fprintf(stderr, _("No cursor motion capability (cm)\n"));
 
1958
    return -1;
1875
1959
  }
1876
1960
  LINES = COLS = 0;
1877
1961
  getrowcols(&LINES, &COLS);
1879
1963
  LINES = lines;
1880
1964
#endif
1881
1965
  if (LINES == 0 && (LINES = tgetnum("li")) <= 0) {
1882
 
        fprintf(stderr, _("Number of terminal lines unknown\n"));
1883
 
        return(-1);
 
1966
    fprintf(stderr, _("Number of terminal lines unknown\n"));
 
1967
    return -1;
1884
1968
  }
1885
1969
  if (COLS == 0 && (COLS = tgetnum("co")) <= 0) {
1886
 
        fprintf(stderr, _("Number of terminal columns unknown\n"));
1887
 
        return(-1);
 
1970
    fprintf(stderr, _("Number of terminal columns unknown\n"));
 
1971
    return -1;
1888
1972
  }
1889
1973
 
1890
1974
  /* Terminal Capabilities */
1923
2007
  NL = tgetstr("nl", &_tptr);
1924
2008
  AC = tgetstr("ac", &_tptr);
1925
2009
  EA = tgetstr("eA", &_tptr);
1926
 
#if ST_LINE
 
2010
#ifdef ST_LINE
1927
2011
  TS = tgetstr("ts", &_tptr);
1928
2012
  FS = tgetstr("fs", &_tptr);
1929
2013
  DS = tgetstr("ds", &_tptr);
1930
2014
#endif
1931
2015
 
1932
 
  if (MR == CNULL) MR = SO;  /* Try standout */
1933
 
  if (MR == CNULL) MR = US;  /* Try underline */
1934
 
  if (MR == CNULL) MR = MD;  /* Try bold */
1935
 
  if (SF == CNULL) SF = "\n";
1936
 
  if (AC == NULL || *AC == 0) AC = def_ac; /* Standard vt100 mappings. */
 
2016
  if (MR == NULL)
 
2017
    MR = SO;         /* Try standout */
 
2018
  if (MR == NULL)
 
2019
    MR = US;         /* Try underline */
 
2020
  if (MR == NULL)
 
2021
    MR = MD;         /* Try bold */
 
2022
  if (SF == NULL)
 
2023
    SF = "\n";
 
2024
  if (AC == NULL || *AC == 0)
 
2025
    AC = def_ac;     /* Standard vt100 mappings. */
1937
2026
 
1938
2027
  /* cr and nl are often not defined but result in great optimization.
1939
2028
   * I only hope that minicom does not break on terminals where this
1940
2029
   * really does not work..
1941
2030
   */
1942
 
  if (CR == CNULL) CR = "\r";
1943
 
  if (NL == CNULL) NL = "\n";
 
2031
  if (CR == NULL)
 
2032
    CR = "\r";
 
2033
  if (NL == NULL)
 
2034
    NL = "\n";
1944
2035
 
1945
 
#if ST_LINE
 
2036
#ifdef ST_LINE
1946
2037
  /* See if we can use the status line. */
1947
2038
  if (!tgetflag("hs") || !tgetflag("es") || !TS || !FS)
1948
 
        use_status = 0;
 
2039
    use_status = 0;
1949
2040
#else
1950
2041
  use_status = 0;
1951
2042
#endif
1952
2043
 
1953
 
  if (IS != CNULL) outstr(IS); /* Initialization string */
 
2044
  if (IS != NULL)
 
2045
    outstr(IS); /* Initialization string */
1954
2046
 
1955
2047
  /* Reset attributes */
1956
2048
  olduseattr = useattr;
1959
2051
  useattr = olduseattr;
1960
2052
 
1961
2053
  /* No reverse? don't use attributes at all. */
1962
 
  if (MR == CNULL) useattr = 0;
 
2054
  if (MR == NULL)
 
2055
    useattr = 0;
1963
2056
 
1964
2057
  /* If we have the "ug" flag, don't allow attributes to be displayed. */
1965
 
  if (tgetnum("ug") > 0) useattr = 0;
1966
 
  
 
2058
  if (tgetnum("ug") > 0)
 
2059
    useattr = 0;
 
2060
 
1967
2061
  _has_am = tgetflag("am");
1968
2062
  _mv_standout = tgetflag("ms");
1969
2063
  if (tgetflag("bs")) {
1970
 
    if (BC == CNULL) BC = "\b";
1971
 
  } 
 
2064
    if (BC == NULL)
 
2065
      BC = "\b";
 
2066
  }
1972
2067
  else
1973
 
    BC = CNULL; 
 
2068
    BC = NULL;
1974
2069
 
1975
2070
  /* Special IBM box-drawing characters */
1976
2071
  D_UL  = 201;
1979
2074
  D_LL  = 200;
1980
2075
  D_VER = 186;
1981
2076
  D_LR  = 188;
1982
 
  
 
2077
 
1983
2078
  S_UL  = 218;
1984
2079
  S_HOR = 240;
1985
2080
  S_UR  = 191;
1988
2083
  S_LR  = 217;
1989
2084
 
1990
2085
  if (AS != NULL && !screen_ibmpc) {
1991
 
        /* Try to find AC mappings. */
1992
 
        D_UL  = S_UL  = acmap('l');
1993
 
        D_HOR = S_HOR = acmap('q');
1994
 
        D_UR  = S_UR  = acmap('k');
1995
 
        D_LL  = S_LL  = acmap('m');
1996
 
        D_VER = S_VER = acmap('x');
1997
 
        D_LR  = S_LR  = acmap('j');
 
2086
    /* Try to find AC mappings. */
 
2087
    D_UL  = S_UL  = acmap('l');
 
2088
    D_HOR = S_HOR = acmap('q');
 
2089
    D_UR  = S_UR  = acmap('k');
 
2090
    D_LL  = S_LL  = acmap('m');
 
2091
    D_VER = S_VER = acmap('x');
 
2092
    D_LR  = S_LR  = acmap('j');
1998
2093
  }
1999
2094
 
2000
2095
  if (screen_iso) {
2001
 
        /* Try to find AC mappings. */
2002
 
        D_UL  = S_UL  = '+';
2003
 
        D_HOR = S_HOR = '-';
2004
 
        D_UR  = S_UR  = '+';
2005
 
        D_LL  = S_LL  = '+';
2006
 
        D_VER = S_VER = '|';
2007
 
        D_LR  = S_LR  = '+';
 
2096
    /* Try to find AC mappings. */
 
2097
    D_UL  = S_UL  = '+';
 
2098
    D_HOR = S_HOR = '-';
 
2099
    D_UR  = S_UR  = '+';
 
2100
    D_LL  = S_LL  = '+';
 
2101
    D_VER = S_VER = '|';
 
2102
    D_LR  = S_LR  = '+';
2008
2103
  }
2009
2104
 
2010
2105
 
2011
 
#if VERY_OLD
2012
 
  if ((p = tgetstr("gA", &_tptr)) != CNULL) wcharmap[201] = *p;
2013
 
  if ((p = tgetstr("gB", &_tptr)) != CNULL) wcharmap[205] = *p;
2014
 
  if ((p = tgetstr("gC", &_tptr)) != CNULL) wcharmap[187] = *p;
2015
 
  if ((p = tgetstr("gD", &_tptr)) != CNULL) wcharmap[200] = *p;
2016
 
  if ((p = tgetstr("gE", &_tptr)) != CNULL) wcharmap[186] = *p;
2017
 
  if ((p = tgetstr("gF", &_tptr)) != CNULL) wcharmap[188] = *p;
2018
 
  if ((p = tgetstr("gG", &_tptr)) != CNULL) wcharmap[218] = *p;
2019
 
  if ((p = tgetstr("gH", &_tptr)) != CNULL) wcharmap[240] = *p;
2020
 
  if ((p = tgetstr("gI", &_tptr)) != CNULL) wcharmap[191] = *p;
2021
 
  if ((p = tgetstr("gJ", &_tptr)) != CNULL) wcharmap[192] = *p;
2022
 
  if ((p = tgetstr("gK", &_tptr)) != CNULL) wcharmap[179] = *p;
2023
 
  if ((p = tgetstr("gL", &_tptr)) != CNULL) wcharmap[217] = *p;
2024
 
#endif
2025
 
 
2026
2106
  /* Memory for global map */
2027
 
  if ((gmap = (ELM *)malloc(sizeof(ELM) * (LINES + 1) * COLS)) == (ELM *)0) {
2028
 
        fprintf(stderr, "Not enough memory\n");
2029
 
        return(-1);
 
2107
  if ((gmap = malloc(sizeof(ELM) * (LINES + 1) * COLS)) == NULL) {
 
2108
    fprintf(stderr, "Not enough memory\n");
 
2109
    return -1;
2030
2110
  };
2031
2111
  _buffend = _bufstart + BUFFERSIZE;
2032
2112
 
2033
2113
  /* Initialize stdwin */
2034
2114
  stdwin = &_stdwin;
2035
2115
 
2036
 
  stdwin->wrap = 1;
2037
 
  stdwin->cursor = CNORMAL;
2038
 
  stdwin->autocr = 1;
 
2116
  stdwin->wrap     = 1;
 
2117
  stdwin->cursor   = CNORMAL;
 
2118
  stdwin->autocr   = 1;
2039
2119
  stdwin->doscroll = 1;
2040
 
  stdwin->x1 = 0;
2041
 
  stdwin->sy1 = stdwin->y1 = 0;
2042
 
  stdwin->x2 = COLS - 1;
2043
 
  stdwin->sy2 = stdwin->y2 = LINES - 1;
2044
 
  stdwin->xs = COLS;
2045
 
  stdwin->ys = LINES;
2046
 
  stdwin->attr = attr;
2047
 
  stdwin->color = COLATTR(fg, bg);
2048
 
  stdwin->direct = 1;
2049
 
#if HISTORY
2050
 
  stdwin->histbuf = (ELM *)0;
2051
 
#endif
2052
 
 
2053
 
  if (EA != CNULL) outstr(EA); /* Graphics init. */
2054
 
  if (KS != CNULL) outstr(KS); /* Keypad mode */
2055
 
  
2056
 
  (void) setcbreak(1); /* Cbreak, no echo */
 
2120
  stdwin->x1       = 0;
 
2121
  stdwin->sy1      = stdwin->y1 = 0;
 
2122
  stdwin->x2       = COLS - 1;
 
2123
  stdwin->sy2      = stdwin->y2 = LINES - 1;
 
2124
  stdwin->xs       = COLS;
 
2125
  stdwin->ys       = LINES;
 
2126
  stdwin->attr     = attr;
 
2127
  stdwin->color    = COLATTR(fg, bg);
 
2128
  stdwin->direct   = 1;
 
2129
  stdwin->histbuf  = NULL;
 
2130
 
 
2131
  if (EA != NULL)
 
2132
    outstr(EA);          /* Graphics init. */
 
2133
  if (KS != NULL)
 
2134
    outstr(KS);          /* Keypad mode */
 
2135
 
 
2136
  setcbreak(1);          /* Cbreak, no echo */
2057
2137
 
2058
2138
  winclr(stdwin);
2059
2139
  w_init = 1;
2060
 
  return(0);
 
2140
  return 0;
2061
2141
}
2062
2142
 
2063
 
void win_end()
 
2143
void win_end(void)
2064
2144
{
2065
 
  if (gmap == (ELM *)0 || w_init == 0) return;
2066
 
  (void) setcbreak(0); /* Reset */
 
2145
  if (gmap == NULL || w_init == 0)
 
2146
    return;
 
2147
  setcbreak(0); /* Reset */
2067
2148
  stdwin->attr = XA_NORMAL;
2068
2149
  stdwin->color = COLATTR(WHITE, BLACK);
2069
2150
  _setattr(stdwin->attr, stdwin->color);
2070
2151
  winclr(stdwin);
2071
 
#if ST_LINE
2072
 
  if (DS) outstr(DS);
 
2152
#ifdef ST_LINE
 
2153
  if (DS)
 
2154
    outstr(DS);
2073
2155
#endif
2074
2156
  wcursor(stdwin, CNORMAL);
2075
 
  if (KE != CNULL) outstr(KE);
2076
 
  if (RS != CNULL) outstr(RS);
2077
 
  else if (IS != CNULL) outstr(IS);
 
2157
  if (KE != NULL)
 
2158
    outstr(KE);
 
2159
  if (RS != NULL)
 
2160
    outstr(RS);
 
2161
  else if (IS != NULL)
 
2162
    outstr(IS);
2078
2163
 
2079
2164
  wflush();
2080
2165
  free(gmap);
2081
 
  gmap = (ELM *)0;
2082
 
  stdwin = NIL_WIN;
 
2166
  gmap = NULL;
 
2167
  stdwin = NULL;
2083
2168
  w_init = 0;
2084
2169
}