~dannf/ubuntu/saucy/screen/lp1213278-from-debian

« back to all changes in this revision

Viewing changes to input.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathaniel McCallum
  • Date: 2004-09-03 15:15:33 UTC
  • Revision ID: james.westby@ubuntu.com-20040903151533-px02yqlrchs4fv2t
Tags: upstream-4.0.2
ImportĀ upstreamĀ versionĀ 4.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 1993-2002
 
2
 *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
 
3
 *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
 
4
 * Copyright (c) 1987 Oliver Laumann
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2, or (at your option)
 
9
 * any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program (see the file COPYING); if not, write to the
 
18
 * Free Software Foundation, Inc.,
 
19
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 
20
 *
 
21
 ****************************************************************
 
22
 */
 
23
 
 
24
#include <sys/types.h>
 
25
#include "config.h"
 
26
#include "screen.h"
 
27
#include "extern.h"
 
28
 
 
29
#define INPUTLINE (flayer->l_height - 1)
 
30
 
 
31
static void InpProcess __P((char **, int *));
 
32
static void InpAbort __P((void));
 
33
static void InpRedisplayLine __P((int, int, int, int));
 
34
 
 
35
extern struct layer *flayer;
 
36
extern struct display *display;
 
37
extern struct mchar mchar_blank, mchar_so;
 
38
 
 
39
struct inpline
 
40
{
 
41
  char  buf[101];       /* text buffer */
 
42
  int  len;             /* length of the editible string */
 
43
  int  pos;             /* cursor position in editable string */
 
44
};
 
45
 
 
46
static struct inpline inphist; /* XXX: should be a dynamic list */
 
47
 
 
48
 
 
49
struct inpdata
 
50
{
 
51
  struct inpline inp;
 
52
  int  inpmaxlen;       /* 100, or less, if caller has shorter buffer */
 
53
  char *inpstring;      /* the prompt */
 
54
  int  inpstringlen;    /* length of the prompt */
 
55
  int  inpmode;         /* INP_NOECHO, INP_RAW, INP_EVERY */
 
56
  void (*inpfinfunc) __P((char *buf, int len, char *priv));
 
57
  char  *priv;          /* private data for finfunc */
 
58
};
 
59
 
 
60
static struct LayFuncs InpLf =
 
61
{
 
62
  InpProcess,
 
63
  InpAbort,
 
64
  InpRedisplayLine,
 
65
  DefClearLine,
 
66
  DefRewrite,
 
67
  DefResize,
 
68
  DefRestore
 
69
};
 
70
 
 
71
/*
 
72
**   Here is the input routine
 
73
*/
 
74
 
 
75
/* called once, after InitOverlayPage in Input() or Isearch() */
 
76
void
 
77
inp_setprompt(p, s)
 
78
char *p, *s;
 
79
{
 
80
  struct inpdata *inpdata;
 
81
  
 
82
  inpdata = (struct inpdata *)flayer->l_data;
 
83
  if (p)
 
84
    {
 
85
      inpdata->inpstringlen = strlen(p);
 
86
      inpdata->inpstring = p;
 
87
    }
 
88
  if (s)
 
89
    {
 
90
      if (s != inpdata->inp.buf)
 
91
        strncpy(inpdata->inp.buf, s, sizeof(inpdata->inp.buf) - 1);
 
92
      inpdata->inp.buf[sizeof(inpdata->inp.buf) - 1] = 0;
 
93
      inpdata->inp.pos = inpdata->inp.len = strlen(inpdata->inp.buf);
 
94
    }
 
95
  InpRedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0);
 
96
}
 
97
 
 
98
/*
 
99
 * We dont use HS status line with Input().
 
100
 * If we would use it, then we should check e_tgetflag("es") if
 
101
 * we are allowed to use esc sequences there.
 
102
 *
 
103
 * mode is an OR of
 
104
 * INP_NOECHO == suppress echoing of characters.
 
105
 * INP_RAW    == raw mode. call finfunc after each character typed.
 
106
 * INP_EVERY  == digraph mode.
 
107
 */
 
108
void
 
109
Input(istr, len, mode, finfunc, data)
 
110
char *istr;
 
111
int len;
 
112
int mode;
 
113
void (*finfunc) __P((char *buf, int len, char *data));
 
114
char *data;
 
115
{
 
116
  int maxlen;
 
117
  struct inpdata *inpdata;
 
118
  
 
119
  if (len > 100)
 
120
    len = 100;
 
121
  if (!(mode & INP_NOECHO))
 
122
    {
 
123
      maxlen = flayer->l_width - 1 - strlen(istr);
 
124
      if (len > maxlen)
 
125
        len = maxlen;
 
126
    }
 
127
  if (len < 0)
 
128
    {
 
129
      LMsg(0, "Width %d chars too small", -len);
 
130
      return;
 
131
    }
 
132
  if (InitOverlayPage(sizeof(*inpdata), &InpLf, 1))
 
133
    return;
 
134
  inpdata = (struct inpdata *)flayer->l_data;
 
135
  inpdata->inpmaxlen = len;
 
136
  inpdata->inpfinfunc = finfunc;
 
137
  inpdata->inp.pos = inpdata->inp.len = 0;
 
138
  inpdata->inpmode = mode;
 
139
  inpdata->priv = data;
 
140
  inp_setprompt(istr, (char *)NULL);
 
141
  flayer->l_x = inpdata->inpstringlen;
 
142
  flayer->l_y = INPUTLINE;
 
143
}
 
144
 
 
145
static void
 
146
InpProcess(ppbuf, plen)
 
147
char **ppbuf;
 
148
int *plen;
 
149
{
 
150
  int len, x;
 
151
  char *pbuf;
 
152
  char ch;
 
153
  struct inpdata *inpdata;
 
154
  struct display *inpdisplay;
 
155
 
 
156
  inpdata = (struct inpdata *)flayer->l_data;
 
157
  inpdisplay = display;
 
158
 
 
159
  LGotoPos(flayer, inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos), INPUTLINE);
 
160
  if (ppbuf == 0)
 
161
    {
 
162
      InpAbort();
 
163
      return;
 
164
    }
 
165
  x = inpdata->inpstringlen + inpdata->inp.pos;
 
166
  len = *plen;
 
167
  pbuf = *ppbuf;
 
168
  while (len)
 
169
    {
 
170
      char *p = inpdata->inp.buf + inpdata->inp.pos;
 
171
 
 
172
      ch = *pbuf++;
 
173
      len--;
 
174
      if (inpdata->inpmode & INP_EVERY)
 
175
        {
 
176
          inpdata->inp.buf[inpdata->inp.len] = ch;
 
177
          inpdata->inp.buf[inpdata->inp.len + 1] = ch;  /* gross */
 
178
          display = inpdisplay;
 
179
          (*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv);
 
180
          ch = inpdata->inp.buf[inpdata->inp.len];
 
181
        }
 
182
      else if (inpdata->inpmode & INP_RAW)
 
183
        {
 
184
          display = inpdisplay;
 
185
          (*inpdata->inpfinfunc)(&ch, 1, inpdata->priv);        /* raw */
 
186
          if (ch)
 
187
            continue;
 
188
        }
 
189
      if (((unsigned char)ch & 0177) >= ' ' && ch != 0177 && inpdata->inp.len < inpdata->inpmaxlen)
 
190
        {
 
191
          if (inpdata->inp.len > inpdata->inp.pos)
 
192
            bcopy(p, p+1, inpdata->inp.len - inpdata->inp.pos);
 
193
          inpdata->inp.buf[inpdata->inp.pos++] = ch;
 
194
          inpdata->inp.len++;
 
195
 
 
196
          if (!(inpdata->inpmode & INP_NOECHO))
 
197
            {
 
198
              struct mchar mc;
 
199
              mc = mchar_so;
 
200
              mc.image = *p++;
 
201
              LPutChar(flayer, &mc, x, INPUTLINE);
 
202
              x++;
 
203
              if (p < inpdata->inp.buf+inpdata->inp.len)
 
204
                {
 
205
                  while (p < inpdata->inp.buf+inpdata->inp.len)
 
206
                    {
 
207
                      mc.image = *p++;
 
208
                      LPutChar(flayer, &mc, x++, INPUTLINE);
 
209
                    }
 
210
                  x = inpdata->inpstringlen + inpdata->inp.pos;
 
211
                  LGotoPos(flayer, x, INPUTLINE);
 
212
                }
 
213
            }
 
214
        }
 
215
      else if ((ch == '\b' || ch == 0177) && inpdata->inp.pos > 0)
 
216
        {
 
217
          if (inpdata->inp.len > inpdata->inp.pos)
 
218
            bcopy(p, p-1, inpdata->inp.len - inpdata->inp.pos);
 
219
          inpdata->inp.len--;
 
220
          inpdata->inp.pos--;
 
221
          p--;
 
222
 
 
223
          if (!(inpdata->inpmode & INP_NOECHO))
 
224
            {
 
225
              struct mchar mc;
 
226
              mc = mchar_so;
 
227
              x--;
 
228
              while (p < inpdata->inp.buf+inpdata->inp.len)
 
229
                {
 
230
                  mc.image = *p++;
 
231
                  LPutChar(flayer, &mc, x++, INPUTLINE);
 
232
                }
 
233
              LPutChar(flayer, &mchar_blank, x, INPUTLINE);
 
234
              x = inpdata->inpstringlen + inpdata->inp.pos;
 
235
              LGotoPos(flayer, x, INPUTLINE);
 
236
            }
 
237
        }
 
238
      else if (ch == '\025')                    /* CTRL-U */
 
239
        {
 
240
          x = inpdata->inpstringlen;
 
241
          if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO))
 
242
            {
 
243
              LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - 1, INPUTLINE, 0, 0);
 
244
              LGotoPos(flayer, x, INPUTLINE);
 
245
            }
 
246
          inpdata->inp.len = inpdata->inp.pos = 0;
 
247
        }
 
248
      else if (ch == '\013')                    /* CTRL-K */
 
249
        {
 
250
          x = inpdata->inpstringlen + inpdata->inp.pos;
 
251
          if (inpdata->inp.len > inpdata->inp.pos && !(inpdata->inpmode & INP_NOECHO))
 
252
            {
 
253
              LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - inpdata->inp.pos - 1, INPUTLINE, 0, 0);
 
254
              LGotoPos(flayer, x, INPUTLINE);
 
255
            }
 
256
          inpdata->inp.len = inpdata->inp.pos;
 
257
        }
 
258
      else if (ch == '\001' || (unsigned char)ch == 0201)       /* CTRL-A */
 
259
        {
 
260
          LGotoPos(flayer, x -= inpdata->inp.pos, INPUTLINE);
 
261
          inpdata->inp.pos = 0;
 
262
        }
 
263
      else if ((ch == '\002' || (unsigned char)ch == 0202) && inpdata->inp.pos > 0)     /* CTRL-B */
 
264
        {
 
265
          LGotoPos(flayer, --x, INPUTLINE);
 
266
          inpdata->inp.pos--;
 
267
        }
 
268
      else if (ch == '\005' || (unsigned char)ch == 0205)       /* CTRL-E */
 
269
        {
 
270
          LGotoPos(flayer, x += inpdata->inp.len - inpdata->inp.pos, INPUTLINE);
 
271
          inpdata->inp.pos = inpdata->inp.len;
 
272
        }
 
273
      else if ((ch == '\006' || (unsigned char)ch == 0206) && inpdata->inp.pos < inpdata->inp.len)      /* CTRL-F */
 
274
        {
 
275
          LGotoPos(flayer, ++x, INPUTLINE);
 
276
          inpdata->inp.pos++;
 
277
        }
 
278
      else if (ch == '\020' || (unsigned char)ch == 0220)       /* CTRL-P */
 
279
        {
 
280
          struct mchar mc;
 
281
          mc = mchar_so;
 
282
          if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO))
 
283
            LClearArea(flayer, inpdata->inpstringlen, INPUTLINE, inpdata->inpstringlen + inpdata->inp.len - 1, INPUTLINE, 0, 0);
 
284
 
 
285
          inpdata->inp = inphist;       /* structure copy */
 
286
          if (inpdata->inp.len > inpdata->inpmaxlen)
 
287
            inpdata->inp.len = inpdata->inpmaxlen;
 
288
          if (inpdata->inp.pos > inpdata->inp.len)
 
289
            inpdata->inp.pos = inpdata->inp.len;
 
290
 
 
291
          x = inpdata->inpstringlen;
 
292
          p = inpdata->inp.buf;
 
293
          
 
294
          if (!(inpdata->inpmode & INP_NOECHO))
 
295
            {
 
296
              while (p < inpdata->inp.buf+inpdata->inp.len)
 
297
                {
 
298
                  mc.image = *p++;
 
299
                  LPutChar(flayer, &mc, x++, INPUTLINE);
 
300
                }
 
301
            }
 
302
          x = inpdata->inpstringlen + inpdata->inp.pos;
 
303
          LGotoPos(flayer, x, INPUTLINE);
 
304
        }
 
305
 
 
306
      else if (ch == '\004' || ch == '\003' || ch == '\007' || ch == '\033' ||
 
307
               ch == '\000' || ch == '\n' || ch == '\r')
 
308
        {
 
309
          if (ch != '\004' && ch != '\n' && ch != '\r')
 
310
            inpdata->inp.len = 0;
 
311
          inpdata->inp.buf[inpdata->inp.len] = 0;
 
312
 
 
313
          if (inpdata->inp.len && inpdata->inpmode == 0)
 
314
            inphist = inpdata->inp;     /* structure copy */
 
315
          
 
316
          flayer->l_data = 0;
 
317
          InpAbort();           /* redisplays... */
 
318
          *ppbuf = pbuf;
 
319
          *plen = len;
 
320
          display = inpdisplay;
 
321
          if ((inpdata->inpmode & INP_RAW) == 0)
 
322
            (*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv);
 
323
          else
 
324
            (*inpdata->inpfinfunc)(pbuf - 1, 0, inpdata->priv);
 
325
          free((char *)inpdata);
 
326
          return;
 
327
        }
 
328
    }
 
329
  if (!(inpdata->inpmode & INP_RAW))
 
330
    {
 
331
      flayer->l_x = inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos);
 
332
      flayer->l_y = INPUTLINE;
 
333
    }
 
334
  *ppbuf = pbuf;
 
335
  *plen = len;
 
336
}
 
337
 
 
338
static void
 
339
InpAbort()
 
340
{
 
341
  LAY_CALL_UP(LayRedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0));
 
342
  ExitOverlayPage();
 
343
}
 
344
 
 
345
static void
 
346
InpRedisplayLine(y, xs, xe, isblank)
 
347
int y, xs, xe, isblank;
 
348
{
 
349
  int q, r, s, l, v;
 
350
  struct inpdata *inpdata;
 
351
  
 
352
  inpdata = (struct inpdata *)flayer->l_data;
 
353
  if (y != INPUTLINE)
 
354
    {
 
355
      LAY_CALL_UP(LayRedisplayLine(y, xs, xe, isblank));
 
356
      return;
 
357
    }
 
358
  inpdata->inp.buf[inpdata->inp.len] = 0;
 
359
  q = xs;
 
360
  v = xe - xs + 1;
 
361
  s = 0;
 
362
  r = inpdata->inpstringlen;
 
363
  if (v > 0 && q < r)
 
364
    {
 
365
      l = v;
 
366
      if (l > r - q)
 
367
        l = r - q;
 
368
      LPutStr(flayer, inpdata->inpstring + q - s, l, &mchar_so, q, y);
 
369
      q += l;
 
370
      v -= l;
 
371
    }
 
372
  s = r;
 
373
  r += inpdata->inp.len;
 
374
  if (!(inpdata->inpmode & INP_NOECHO) && v > 0 && q < r)
 
375
    {
 
376
      l = v;
 
377
      if (l > r - q)
 
378
        l = r - q;
 
379
      LPutStr(flayer, inpdata->inp.buf + q - s, l, &mchar_so, q, y);
 
380
      q += l;
 
381
      v -= l;
 
382
    }
 
383
  s = r;
 
384
  r = flayer->l_width;
 
385
  if (!isblank && v > 0 && q < r)
 
386
    {
 
387
      l = v;
 
388
      if (l > r - q)
 
389
        l = r - q;
 
390
      LClearArea(flayer, q, y, q + l - 1, y, 0, 0);
 
391
      q += l;
 
392
    }
 
393
}
 
394
 
 
395
int
 
396
InInput()
 
397
{
 
398
  if (flayer && flayer->l_layfn == &InpLf)
 
399
    return 1;
 
400
  return 0;
 
401
}
 
402