~ubuntu-branches/debian/jessie/eso-midas/jessie

« back to all changes in this revision

Viewing changes to prim/tw3/libsrc/twget.c

  • Committer: Package Import Robot
  • Author(s): Ole Streicher
  • Date: 2014-04-22 14:44:58 UTC
  • Revision ID: package-import@ubuntu.com-20140422144458-okiwi1assxkkiz39
Tags: upstream-13.09pl1.2+dfsg
ImportĀ upstreamĀ versionĀ 13.09pl1.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
  Copyright (C) 1986-2009 European Southern Observatory (ESO)
 
3
 
 
4
  This program is free software; you can redistribute it and/or 
 
5
  modify it under the terms of the GNU General Public License as 
 
6
  published by the Free Software Foundation; either version 2 of 
 
7
  the License, or (at your option) any later version.
 
8
 
 
9
  This program is distributed in the hope that it will be useful,
 
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
  GNU General Public License for more details.
 
13
 
 
14
  You should have received a copy of the GNU General Public 
 
15
  License along with this program; if not, write to the Free 
 
16
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
 
17
  MA 02139, USA.
 
18
 
 
19
  Corresponding concerning ESO-MIDAS should be addressed as follows:
 
20
        Internet e-mail: midas@eso.org
 
21
        Postal address: European Southern Observatory
 
22
                        Data Management Division 
 
23
                        Karl-Schwarzschild-Strasse 2
 
24
                        D 85748 Garching bei Muenchen 
 
25
                        GERMANY
 
26
===========================================================================*/
 
27
 
 
28
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
29
.TYPE           Module
 
30
.IDENTIFICATION twget.c
 
31
.AUTHOR         Francois Ochsenbein [ESO-IPG]
 
32
.LANGUAGE       C
 
33
.KEYWORDS       Window Management
 
34
.ENVIRONMENT    TermWindows
 
35
.COMMENTS       This module contains routines to perform command input,
 
36
                and to manage the associated command stack.
 
37
\begin{TeX}
 
38
\\
 
39
The commands are stacked in a buffer (named {\tt text} in the
 
40
{\tt COMMAND} structure). Each command is preceded and followed
 
41
by the text length, in order to facilitate forward and backward
 
42
movements in the stack.\\[0.5ex]
 
43
{\bf Editing possibilities} when a command is typed at the terminal 
 
44
are available, like cursor mouvements, moving in the stack,
 
45
refreshing the Screen. 
 
46
 
 
47
The default actions of control characters are defined as TW\_cc\_default
 
48
in {\tt twparam.h}, with choices UNIX-like, VMS-like or a third
 
49
set. The action of each control character may be modified with the
 
50
tv\_setcc(control\_character, action) (DefineControl) function.
 
51
 
 
52
\end{TeX}
 
53
 
 
54
.VERSION  1.0   01-Sep-1986:    Creation
 
55
.VERSION  2.0   03-Dec-1986     New terminal-independant graphic characters
 
56
                        with output buffering version.
 
57
.VERSION 3.0    20-May-1988: Version '3'
 
58
                        Functions tw_get1 and tw_getf added.
 
59
.VERSION 3.1    17-Feb-1989: Add ^ option in SetStopping, which specifies
 
60
                        that the arrow should stop if borders encountered.
 
61
                        Changed tw_getf to tw_modf.
 
62
.VERSION 3.2    31-Mar-1989: Removed bug in mv1...
 
63
.VERSION 3.3    05-Apr-1989: Possibility of NULL_WINDOW as input.
 
64
.VERSION 3.4    17-May-1989: No redisplay with ModsWithCheck if window 
 
65
                not active.
 
66
.VERSION 3.5    09-Jun-1989: Use negative string size for Stretchable Window.
 
67
                Added tw_ms2. Added tw_gc2.
 
68
.VERSION 3.6    19-Jun-1989: tw_mods puts the cursor at the BEGINNING of
 
69
                the line to edit.
 
70
.VERSION 3.7    24-Jul-1989: Catched INTERRUPT
 
71
.VERSION 3.8    24-Aug-1989: Clear line if INTERRUPT
 
72
.VERSION 3.9    05-Dec-1990: Modified tw_get1: Return 0 if First Char found.
 
73
                                Added tw_gc1 (use a stopping list)
 
74
 
 
75
 090901         last modif
 
76
----------------------------------------------------------------------------*/
 
77
 
 
78
#define         DEBUG           0       /* For debugging only           */
 
79
 
 
80
#define PM_LEVEL        LEVEL_TW
 
81
 
 
82
#include <midas_def.h>
 
83
 
 
84
 
 
85
#define  TW_import      0       /* Do not use macro window definitions  */
 
86
#include <twset.h>
 
87
 
 
88
 
 
89
extern int tv_wa(), tv_agoto(), tv_getc();
 
90
extern int tv_bell(), tv_setsc(), tv_push();
 
91
 
 
92
extern int tw_write(), tw_uc(), tw_box(), tw_r(), tw_agoto(), tw_st();
 
93
extern int tw_wa(), tw_clear(), tw_tra(), tw_dc(), tw_mods();
 
94
extern int tw_helps(), tw_amark(), tw_occluded(), tw_nl(), tw_line();
 
95
 
 
96
extern int pm_enter(), pm_iexit(), pm_ed_tr2(), pm_trace();
 
97
 
 
98
extern int eh_ed_str2();
 
99
 
 
100
 
 
101
MID_EXTERN      WINDOW *Screen;
 
102
MID_EXTERN  TERM   *terms;
 
103
typedef void (*FUNCTION)();
 
104
extern FUNCTION ostint();
 
105
 
 
106
 
 
107
#if     DEBUG
 
108
#define TW_cc_level     3
 
109
#define ENTER_DEBUG(x)  ENTER(x)
 
110
#define EXIT_DEBUG(x)   EXIT(x)
 
111
#define DISPLAY(opt)    zed(opt)
 
112
#else
 
113
#define DISPLAY(opt)
 
114
#define ENTER_DEBUG(x)  
 
115
#define EXIT_DEBUG(x)   return(x)
 
116
#endif
 
117
 
 
118
MID_STATIC WINDOW       *W = NULL_PTR(WINDOW);
 
119
MID_STATIC COMMAND      *c = NULL_PTR(COMMAND);
 
120
static short int command_number;
 
121
MID_STATIC unsigned int f = 0;          /* Flags to communicate */
 
122
MID_STATIC char                 *stop_list = (char *)0;
 
123
MID_STATIC int          stop_len = 0;
 
124
MID_STATIC int          (*f_ed)() = NULL_FCT(int);
 
125
                                        /* Control function for modf */
 
126
static int      old_pos;
 
127
static ACHAR    *saved_screen = NULL_PTR(ACHAR);
 
128
static int      saved_screen_size = 0;
 
129
static int      saved_screen_len  = 0;
 
130
 
 
131
static char     *input_start, *input_end, *input_valid; /* Input string */
 
132
 
 
133
#define Stop            0x0100
 
134
#define Special         0x0200
 
135
#define Stop1           0x0400
 
136
#define NoMore          0x1000
 
137
#define Raw             0x2000
 
138
#define Occluded        0x4000
 
139
#define Interrupted     0x8000
 
140
 
 
141
#define BYTE_MAX        0xff
 
142
#define ULONG_MAX       0xffffffff
 
143
 
 
144
        MONITOR(TWGET);
 
145
 
 
146
 
 
147
/*==========================================================================*/
 
148
static int InInt(s)
 
149
/*+++
 
150
.PURPOSE Catch Interrupt
 
151
.RETURNS 0
 
152
.REMARKS 
 
153
---*/
 
154
        int     s;      /* IN: Signal */
 
155
{
 
156
  f |= (Stop | Interrupted);
 
157
  return(0);
 
158
}
 
159
  
 
160
/*==========================================================================*/
 
161
static int OpenStretchableWindow(len)
 
162
/*+++
 
163
.PURPOSE Special Window, saving what's presently on the Screen.
 
164
.RETURNS OK / NOK (It's a _DISPLAY_ window)
 
165
.REMARKS 
 
166
---*/
 
167
        int     len;    /* IN: Length of Stretchable Window */
 
168
{
 
169
 
 
170
  if (saved_screen_size < len)  
 
171
        saved_screen_size = len,
 
172
        saved_screen = MEM_EXP(ACHAR,(char *) saved_screen, saved_screen_size);
 
173
  
 
174
  saved_screen_len = len;
 
175
  tw_tra(W, saved_screen, saved_screen_len);
 
176
  
 
177
  return(saved_screen_len);
 
178
}
 
179
  
 
180
/*==========================================================================
 
181
 *                      check
 
182
 *==========================================================================*/
 
183
static int check(w)
 
184
/*+++
 
185
.PURPOSE Check if window is Display Only
 
186
.RETURNS OK / NOK
 
187
--------*/
 
188
        WINDOW *w;      /* IN: The concerned Window     */
 
189
{
 
190
        int     status;
 
191
        
 
192
  status = OK;
 
193
 
 
194
  W = (w ? w : Screen);
 
195
 
 
196
  if_not(c = Command(W))        status = NOK, 
 
197
        ERR_ED_STR2("Window is Display-Only: ", W->id, 8);
 
198
 
 
199
  return(status);
 
200
}
 
201
 
 
202
/*==========================================================================
 
203
 *                      o1
 
204
 *==========================================================================*/
 
205
static int o1(ch)
 
206
/*+++
 
207
.PURPOSE Optimized output of 1 character, if Echo is on.
 
208
.RETURNS 0 / 1 (number of chars output on Screen)
 
209
.REMARKS Optimization only for an active window, not in Insert Mode.
 
210
---*/
 
211
        char *ch;               /* IN: Character to output      */
 
212
{
 
213
        ACHAR   achar;
 
214
        int     i, j, J, saved_marker;
 
215
 
 
216
  ENTER_DEBUG("+o1");
 
217
 
 
218
  status = 0;
 
219
  saved_marker = W->marker[1];
 
220
  if_not(f&Echo)        FINISH;         /* Nothing if no echo   */
 
221
  
 
222
  J = W->Nj, i = W->pos/J, j = W->pos%J;
 
223
 
 
224
  if ( f & (Imode | Occluded) )
 
225
  {
 
226
        if (saved_screen_len)   
 
227
                W->marker[1] = W->marker[0] + input_valid - input_start;
 
228
        status = tw_write(W, (char *)ch, 1, 0);  /* Not optimized...    */
 
229
        FINISH;
 
230
  }
 
231
 
 
232
        /* Convert char to ACHAR, and update Cursor Position on Screen  */
 
233
 
 
234
  achar = (W->attr & ~HIGH) | ( iscntrl(*ch) ? RubbishAchar() : *ch);
 
235
  tw_uc(W);
 
236
 
 
237
        /* Update Window's Cursor Position      */
 
238
 
 
239
  W->pos += 1;
 
240
 
 
241
        /* First, copy char to window           */
 
242
 
 
243
  *Aij(W,i,j) = achar;
 
244
 
 
245
        /* ... and copy char to Screen          */
 
246
 
 
247
  if (W != Screen)
 
248
  {
 
249
        J = Screen->Nj, i = Screen->pos/J, j = Screen->pos%J;
 
250
        *Aij(Screen, i, j) = achar;
 
251
        SetPosition(Screen->pos);
 
252
  }
 
253
 
 
254
        /* ... physically output char to Screen */
 
255
 
 
256
  WriteAchars(&achar, 1);
 
257
 
 
258
        /* ... And finally update Screen Cursor */
 
259
 
 
260
  tw_uc(W);
 
261
 
 
262
  status = 1;
 
263
 
 
264
  FIN:
 
265
  W->marker[1] = saved_marker;
 
266
  EXIT_DEBUG(status);
 
267
}
 
268
 
 
269
/*======================================================================
 
270
 *                      mv1
 
271
 *======================================================================*/
 
272
static int mv1(direction, bytes)
 
273
/*+++++
 
274
.PURPOSE Optimized cursor mouvement of 1 place in the specified
 
275
        direction: up, down, right, left or home.
 
276
.RETURNS OK / NOK (attempt to move outside window, cursor does not move).
 
277
.REMARKS Move is limited within markers.
 
278
------*/
 
279
        int direction;  /* IN: The direction of the displacement        */
 
280
        int bytes;      /* IN: The maximal displacement                 */
 
281
{
 
282
        int displacement, saved_marker, status;
 
283
 
 
284
  ENTER_DEBUG("mv1");
 
285
 
 
286
  status = NOK;
 
287
  if_not(f&Echo)        FINISH;         /* Nothing if no echo   */
 
288
  
 
289
  status = OK;
 
290
  saved_marker = W->marker[1],  W->marker[1] = W->pos + bytes;
 
291
 
 
292
  switch(direction)
 
293
  { case _LEFT_:        displacement = -1;      break;
 
294
    case _RIGHT_:       displacement =  1;      break;
 
295
    case _UP_:          displacement = -W->Nj;  break;
 
296
    case _DOWN_:        displacement =  W->Nj;  break;
 
297
    default:            displacement =  W->marker[0] - W->pos;
 
298
        if (displacement == 0) displacement = -1;       /* No mouvement, 
 
299
                                                        forces NOK status */
 
300
  }
 
301
 
 
302
  displacement += W->pos;               /* New position */
 
303
  if ( (displacement >= W->marker[0]) && (displacement <= W->marker[1]))
 
304
        tw_agoto(W, displacement);
 
305
  else  status = NOK;
 
306
  W->marker[1] = saved_marker;
 
307
 
 
308
  FIN:
 
309
  EXIT_DEBUG(status);
 
310
}
 
311
 
 
312
/*======================================================================
 
313
 *                      move
 
314
 *======================================================================*/
 
315
static int move(out, in, len)
 
316
/*+++++
 
317
.PURPOSE Copy string to another.
 
318
.RETURNS Length of string
 
319
.REMARKS Move is limited within markers. 
 
320
------*/
 
321
        char    *out;   /* OUT: copied string           */
 
322
        char    *in;    /* IN: string to display        */
 
323
        int     len;    /* IN: Length of in             */
 
324
{
 
325
        int     l;
 
326
 
 
327
  l = MIN (len, W->marker[1] - W->marker[0]);
 
328
  oscopy  (out, in, l);
 
329
 
 
330
  return(l);
 
331
}
 
332
 
 
333
/*======================================================================
 
334
 *                      show
 
335
 *======================================================================*/
 
336
static int show(str, len)
 
337
/*+++++
 
338
.PURPOSE Redisplay the string (in, len) on the W window.
 
339
.RETURNS Length of string
 
340
.REMARKS Move is limited within markers. Cursor positioned AFTER marker.
 
341
------*/
 
342
        char    *str;   /* IN: string to display        */
 
343
        int     len;    /* IN: Length of in             */
 
344
{
 
345
        int     l;
 
346
 
 
347
  l = MIN (len, W->marker[1] - W->marker[0]);
 
348
  if_not(f&Echo)        FINISH;         /* Nothing if no echo   */
 
349
 
 
350
  tw_st(W, Imode|Echo, 0); 
 
351
  tw_agoto(W, old_pos);
 
352
  if (saved_screen_len) tw_wa(W, saved_screen, saved_screen_len);
 
353
  else                  tw_clear(W, _DOWN_);
 
354
  tw_write(W, str, l, 0);
 
355
  if (f&Echo)   tw_st(W, Echo, 1), tw_r(W,0, NULL_WINDOW);
 
356
 
 
357
  FIN:
 
358
  return(l);
 
359
}
 
360
 
 
361
/*======================================================================
 
362
 *                      here_Delete
 
363
 *======================================================================*/
 
364
static int here_Delete(ndel)
 
365
/*+++++
 
366
.PURPOSE Delete char interface
 
367
.RETURNS Length of string
 
368
.REMARKS Move is limited within markers. Cursor positioned AFTER marker.
 
369
------*/
 
370
        int     ndel;   /* IN: Number of bytes to delete */
 
371
{
 
372
        int     len;    /* IN: Length of input          */
 
373
        int     status;
 
374
 
 
375
  len = input_valid - input_start;
 
376
 
 
377
  if (saved_screen_len) 
 
378
  {
 
379
        status = W->pos;
 
380
        W->flags &= ~Imode;
 
381
        tw_st(W, Imode|Echo, 0); 
 
382
        {
 
383
                tw_agoto(W, old_pos + len);
 
384
                tw_wa(W, saved_screen + len, saved_screen_len - len);
 
385
        }
 
386
        tw_agoto(W, old_pos);
 
387
        tw_write(W, input_start, len, 0);
 
388
 
 
389
        if (ndel < 0)   status += ndel;
 
390
        tw_agoto(W, status);
 
391
        if (f&Imode)    W->flags |= Imode;
 
392
        if (f&Echo)     tw_st(W, Echo, 1), tw_r(W,0, NULL_WINDOW);
 
393
        status = OK;
 
394
  }
 
395
  else          status = tw_dc(W, ndel);
 
396
 
 
397
  return(status);
 
398
}
 
399
 
 
400
/*==========================================================================
 
401
 *                      zm
 
402
 *==========================================================================*/
 
403
static int zm(direction)
 
404
/*+++
 
405
.PURPOSE Move in the command stack according to the specified direction.
 
406
.RETURNS OK / NOK (at the top or bottom of the stack)
 
407
.REMARKS 
 
408
---*/
 
409
        int     direction;      /* IN: _UP_, _DOWN_ or _HOME_ (last command) */
 
410
{
 
411
#if TWFAC_Stacking
 
412
 
 
413
  status = NOK;
 
414
 
 
415
  if (c->size == 0)             FINISH;
 
416
 
 
417
  DISPLAY(0);
 
418
 
 
419
  switch(direction)
 
420
  { case _UP_:          /* Towards the beginning of the stack   */
 
421
        if (c->pointed_no <= c->first_no)       
 
422
        {       c->pointed_no   = c->first_no - 1;
 
423
                c->pointed      = 0;
 
424
                FINISH;
 
425
        }
 
426
        (c->pointed_no)--;
 
427
        (c->pointed)--;         /* Index of suffix length       */
 
428
        (c->pointed) -= (1 + *(c->text + c->pointed));
 
429
        break;
 
430
    case _DOWN_:        /* Towards the bottom of the stack      */
 
431
        if (c->pointed_no >= c->last_no)        
 
432
        {       c->pointed_no   = c->last_no + 1;
 
433
                c->pointed      = c->used;
 
434
                FINISH;
 
435
        }
 
436
        (c->pointed_no)++;
 
437
        (c->pointed) += (2 + *(c->text + c->pointed));
 
438
        break;
 
439
    default:            /* The last issued command              */
 
440
        if (c->last_no < c->first_no)   
 
441
        {       c->pointed_no   = 0;
 
442
                c->pointed      = 0;
 
443
                FINISH;
 
444
        }
 
445
        c->pointed_no   = c->last_no;
 
446
        c->pointed      = (c->used) - 1;
 
447
        (c->pointed) -= (1 + *(c->text + c->pointed));
 
448
        break;
 
449
  }
 
450
 
 
451
  DISPLAY(0);
 
452
 
 
453
  status = OK;
 
454
  FIN:
 
455
  return(status);
 
456
#else
 
457
  return(NOK);
 
458
#endif
 
459
}
 
460
 
 
461
/*==========================================================================
 
462
 *                      zadd
 
463
 *==========================================================================*/
 
464
static int zadd(str, nbytes, opt)
 
465
/*+++
 
466
.PURPOSE Insert into the command stack the string str.
 
467
.RETURNS OK / NOK (not enough space)
 
468
.REMARKS 
 
469
---*/
 
470
        char    *str;   /* IN: The string to insert */
 
471
        int     nbytes;         /* IN: Length of the str string */
 
472
        int     opt;            /* IN: Option 1 to add effectively / 2 only if\
 
473
                                        differs from previous   */
 
474
{
 
475
#if TWFAC_Stacking
 
476
        char    *p;
 
477
        int     i,u, l;
 
478
 
 
479
  TRACE_ED_STR2("Command = ",str,nbytes);
 
480
 
 
481
  status = NOK;
 
482
 
 
483
  if (nbytes < 0)               FINISH;
 
484
  if (c->size == 0)             FINISH;
 
485
 
 
486
  DISPLAY(1);
 
487
 
 
488
        /* Check it it's the same command as previous one       */
 
489
        
 
490
  if ((opt == 2) && zm(_HOME_))         /* Get last command     */
 
491
  {     p = (char *)(c->text + c->pointed);
 
492
        if ((*(p++) == nbytes) && (oscomp(p, str, nbytes) == 0))
 
493
        {       status = OK;
 
494
                FINISH;
 
495
        }
 
496
  }
 
497
 
 
498
  u = c->used + nbytes + 2;     /* Used bytes after addition    */
 
499
  i = 2;
 
500
  
 
501
  while (u > c->size)           /* Look if stack must be compressed     */
 
502
  {     l = *(c->text + i) + 2; /* Length of command    */
 
503
        (c->first_no)++;
 
504
        u -= l, i += l;
 
505
  }
 
506
 
 
507
  if (u < 2)                            /* Not enough space ... */
 
508
  {     c->used = 2;
 
509
        FINISH;
 
510
  }
 
511
 
 
512
  if (i>2) 
 
513
  {     l = c->used - i;                /* Length to copy       */
 
514
#if DEBUG
 
515
        TRACE("Compress Stack:");
 
516
        DISPLAY(1);
 
517
#endif
 
518
        c->used = 2 + oscopy((char *)(c->text+2), (char *)(c->text + i), l);
 
519
#if DEBUG
 
520
        TRACE("Compressed Stack:");
 
521
        DISPLAY(1);
 
522
#endif
 
523
  }
 
524
 
 
525
  c->pointed = c->used;
 
526
 
 
527
  p          = (char *)(c->text + c->used);
 
528
  *(p++) = nbytes;                      /* Prefix length        */
 
529
  p += oscopy((char *)p, (char *)str, nbytes);
 
530
                                        /* Copy text            */
 
531
  *(p++) = nbytes;                      /* Suffix length        */
 
532
 
 
533
  if (opt)                              /* Modify only if required */
 
534
  {     c->used = (unsigned char *)p - (c->text);
 
535
        (c->last_no)++;
 
536
        (c->pointed_no) = c->last_no;
 
537
  }
 
538
 
 
539
  DISPLAY(1);
 
540
  status = OK;
 
541
 
 
542
  FIN:
 
543
  return(status);
 
544
#else
 
545
  return(NOK);
 
546
#endif
 
547
}
 
548
 
 
549
/*==========================================================================
 
550
 *                      tw_stopin
 
551
 *==========================================================================*/
 
552
int     tw_stopin(w, type, list)
 
553
/*+++
 
554
.PURPOSE Define the list of Characters that stop the Input:
 
555
        Control Characters, Arrows, Keypad, Function Keys.
 
556
.RETURNS OK / NOK (It's a _DISPLAY_ window)
 
557
.REMARKS A void string ("") removes all stopping characters; 
 
558
        a string starting with + means "add to existing list",
 
559
        with - "delete from existing list".
 
560
        The * acts as the wild character, e.g. "-*" means "delete all".
 
561
        By default, only the \r (Carriage-Return) stops the input.
 
562
\begin{TeX}
 
563
 
 
564
        For type \_STANDARD\_, {\em list} contains the ASCII equivalence,
 
565
        e.g. A for Control A.
 
566
 
 
567
        For type \_ARROW\_, individual keys are specified in {\em list} 
 
568
        by {\bf u}p, {\bf d}owm, {\bf l}eft, {\bf r}ight and {\bf h}ome.
 
569
        The {\bf \^{ }} (carret) means {\em return if a border encountered}
 
570
 
 
571
        Other keys cannot be individually specified.
 
572
 
 
573
\end{TeX}
 
574
---*/
 
575
        WINDOW  *w;     /* MOD: Window concerned        */
 
576
        int     type;   /* IN: _NORMAL_ , _ARROW_, _KEYPAD_, _PF_ or _FK_ */
 
577
        char    *list;  /* IN: The characters that may be used to terminate; \
 
578
                                the * is used as a wild character \
 
579
                                (enable all)    */
 
580
{
 
581
        int     wild;
 
582
        unsigned int i;
 
583
        char    *p;
 
584
 
 
585
  ENTER("tw_stopin");
 
586
 
 
587
  i = 0;
 
588
 
 
589
  if_not(check(w))      EXIT(NOK);
 
590
  if_not(list)          EXIT(NOK);
 
591
  p = list;
 
592
  wild = (*p == '+' ? 1 : (*p == '-' ? -1 : 0));
 
593
  
 
594
  switch(type)
 
595
  { case _ARROW_:
 
596
        if_not(wild)    c->exit_ar = 0;
 
597
        for ( ; *p; p++)
 
598
        {       switch(tolower(*p))
 
599
                { case 'u': i = MASK(_UP_);     break;
 
600
                  case 'd': i = MASK(_DOWN_);   break;
 
601
                  case 'l': i = MASK(_LEFT_);   break;
 
602
                  case 'r': i = MASK(_RIGHT_);  break;
 
603
                  case 'h': i = MASK(_HOME_);   break;
 
604
                  case '*': i = 0x1f;           break;
 
605
                  case '^': i = MASK(_TEE_);    break;
 
606
                  case '+': wild = 1;           continue;
 
607
                  case '-': wild = -1;          continue;
 
608
                }
 
609
                if (wild<0)     c->exit_ar &= ~i;
 
610
                else            c->exit_ar |=  i;
 
611
        }
 
612
        break;
 
613
 
 
614
    case _KEYPAD_: case _PF_: case _FK_:
 
615
        i = MASK(type);
 
616
        if (*p == '*')  wild = 1;
 
617
        if (wild)       c->exit_pf &= ~i;
 
618
        if (wild > 0)   c->exit_pf |= i;
 
619
        break;
 
620
 
 
621
    default:            /* Control Characters */
 
622
        if_not(wild)    c->exit_cc = MASK('\r');
 
623
        for ( ; *p; p++)
 
624
        {       switch(*p)      
 
625
                { case '+':     wild = 1;       continue;
 
626
                  case '-':     wild = -1;      continue;
 
627
                  case '*':     i = ULONG_MAX;          break;
 
628
                  default:      i = MASK(Control_(*p)); break;
 
629
                }
 
630
                if (wild<0)     c->exit_cc &= ~i;
 
631
                else            c->exit_cc |=  i;
 
632
        }
 
633
        break;
 
634
  }
 
635
 
 
636
  EXIT(OK);
 
637
}
 
638
 
 
639
/*==========================================================================
 
640
 *                      tw_getc
 
641
 *==========================================================================*/
 
642
int     tw_getc(w, ch)
 
643
/*+++
 
644
.PURPOSE Get a single character on the window.
 
645
.RETURNS _STANDARD_, NOK (unknown escape sequence) _INTERRUPT_ _EOF_, _PF_, _FK_ , _KEYPAD_
 
646
.REMARKS Help Window Removed if _EOF_ or \r.
 
647
---*/
 
648
        WINDOW  *w;     /* MOD: Window concerned                */
 
649
        char    *ch;    /* OUT: The character typed             */
 
650
{
 
651
        char    buffer[2];
 
652
        int     type;
 
653
 
 
654
  ENTER("tw_getc");
 
655
  
 
656
  f = Stop1;    /* Stop after first byte */
 
657
  type = tw_mods(w, buffer, sizeof(buffer), 0);
 
658
  *ch = buffer[0];
 
659
  f = 0;
 
660
 
 
661
  if( (type < 0) || ((type == _STANDARD_) && (buffer[0] == '\r')))
 
662
        tw_helps(W,0);          /* Remove Help Window   */
 
663
 
 
664
  EXIT(type);
 
665
}
 
666
 
 
667
 
 
668
int tw_gc1(w, ch, stop1)
 
669
/*+++
 
670
.PURPOSE Similar to gc, but uses a list of characters that are NOT
 
671
        interpreted
 
672
.RETURNS _EOF_ / _INTERRUPT_ / 0(stopped after first input) / 
 
673
        _STANDARD_ / _ARROW_ / _KEYPAD_ / _FK_ / _PF_
 
674
        (see tw_mods)
 
675
---*/
 
676
        WINDOW  *w;     /* MOD: Window to echo the input        */
 
677
        char    *ch;    /* OUT: The character typed             */
 
678
        char    *stop1; /* IN: List of characters to stop       */
 
679
{
 
680
        int     status;
 
681
 
 
682
  ENTER("tw_gc1");
 
683
 
 
684
  stop_list = stop1;
 
685
  stop_len  = strlen(stop1);
 
686
  status    = tw_getc(w, ch);
 
687
  if (stop_len < 0)     status = 0;     /* Stopped due to 1st char */
 
688
  stop_len  = 0;
 
689
 
 
690
  EXIT(status);
 
691
}
 
692
  
 
693
/*==========================================================================
 
694
 *                      tw_get1
 
695
 *==========================================================================*/
 
696
int tw_get1(w, str, nbytes, stop1)
 
697
/*+++
 
698
.PURPOSE Get a command string from terminal, made of up to (nbytes-1)
 
699
        characters, but stop if one of the characters
 
700
        in stop1 was hit as the {\em first} input.
 
701
.RETURNS _EOF_ / _INTERRUPT_ / 0(stopped after first input) / 
 
702
        _STANDARD_ / _ARROW_ / _KEYPAD_ / _FK_ / _PF_
 
703
        (see tw_mods)
 
704
---*/
 
705
        WINDOW  *w;             /* MOD: Window to echo the input        */
 
706
        char    *str;           /* MOD: The buffer to get the input     */
 
707
        int     nbytes;         /* IN: Length of the input buffer       */
 
708
        char    *stop1;         /* IN: List of characters to stop       */
 
709
{
 
710
        int     status;
 
711
 
 
712
  ENTER("tw_get1");
 
713
 
 
714
  stop_list = stop1;
 
715
  stop_len  = strlen(stop1);
 
716
  status    = tw_mods(w, str, nbytes, 0);
 
717
  if (stop_len < 0)     status = 0;     /* Stopped due to 1st char */
 
718
  stop_len  = 0;
 
719
 
 
720
  EXIT(status);
 
721
}
 
722
  
 
723
/*==========================================================================
 
724
 *                      tw_ms2
 
725
 *==========================================================================*/
 
726
int tw_ms2(w, str, nbytes, linput, fct)
 
727
/*+++
 
728
.PURPOSE Similar to tw_modf, but returns a composite status.
 
729
.RETURNS A composite code including the kind of key and the actual key
 
730
        typed at the terminal. Codes are:
 
731
\begin{TeX}
 
732
        \begin{itemize}
 
733
        \item 0:  the \b r terminated the input.
 
734
        \item \_INTERRUPT\_:  the {\em Interrupt} key was hit.
 
735
        \item \_EOF\_:  the {\em EOF} key was hit.
 
736
        \item a control char:  the returned character terminated the input.
 
737
        \item \_ARROW({\em key}):  one of the Arrows was hit, e.g. 
 
738
                {\tt \_ARROW(\_UP\_)}
 
739
        \item \_KEYPAD({\em key}):  one of the Kitpad Keys was hit,
 
740
                e.g. {\tt \_KEYPAD('6')}
 
741
        \item \_PF({\em key}):  one of the PF Keys was hit, 
 
742
                e.g. {\tt \_PF(1)}
 
743
        \item \_FK({\em key}):  one of the FK Keys was hit, 
 
744
                e.g. {\tt \_FK(12)}
 
745
        \end{itemize}
 
746
\end{TeX}
 
747
---*/
 
748
        WINDOW  *w;             /* MOD: Window to echo the input        */
 
749
        char    *str;           /* MOD: The buffer to get the input     */
 
750
        int     nbytes;         /* IN: Length of the input buffer (<0 stretchable)      */
 
751
        int     linput;         /* IN: Length of the string to modify   */
 
752
        int     (*fct)();       /* IN: The check function       */
 
753
{
 
754
        int     status;
 
755
        char    thechar;
 
756
 
 
757
  ENTER("tw_ms2");
 
758
 
 
759
  f_ed = fct;
 
760
 
 
761
  status = tw_mods(w, str, nbytes, linput);
 
762
  if (status < 0)       *str = EOS;
 
763
  else switch(status)
 
764
  {
 
765
        case _STANDARD_:        /* Normal \r terminated string  */
 
766
                status = 0;     
 
767
                break;
 
768
 
 
769
        case 0:         /* Special Character stopped the Input  */
 
770
                status = GetChar(&thechar);     /* Get it...    */
 
771
                switch(status)
 
772
                {
 
773
                  case _EOF_:                   break;
 
774
                  case _STANDARD_:
 
775
                        status = thechar;       break;
 
776
                  default:
 
777
                        status = (status << 8) | thechar;
 
778
                                                break;
 
779
                }
 
780
                break;
 
781
 
 
782
        default:        
 
783
                status = (status << 8) | *str;
 
784
                *str = EOS;     
 
785
                break;
 
786
  }
 
787
  f_ed = NULL_FCT(int);
 
788
 
 
789
  EXIT(status);
 
790
}
 
791
  
 
792
/*==========================================================================
 
793
 *                      tw_gc2
 
794
 *==========================================================================*/
 
795
int tw_gc2(w)
 
796
/*+++
 
797
.PURPOSE Similar to tw_getc, but returns a composite status.
 
798
.RETURNS A composite code including the kind of key and the actual key
 
799
        typed at the terminal (see tw_ms2).
 
800
---*/
 
801
        WINDOW  *w;             /* MOD: Window to echo the input        */
 
802
{
 
803
        char    buffer[2];
 
804
        int     type;
 
805
 
 
806
  ENTER("tw_gc2");
 
807
  
 
808
  f = Stop1;    /* Stop after first byte */
 
809
 
 
810
  type = tw_mods(w, buffer, sizeof(buffer), 0);
 
811
  if (type < 0) buffer[0] = EOS;
 
812
  else switch(type)
 
813
  {
 
814
        case _STANDARD_:        /* Normal \r terminated string  */
 
815
                type = (buffer[0] == '\r' ? 0 : buffer[0]);     
 
816
                break;
 
817
 
 
818
        default:        
 
819
                type = (type << 8) | buffer[0];
 
820
                break;
 
821
  }
 
822
  f = 0;
 
823
 
 
824
  if (type <= 0)        tw_helps(W,0);          /* Remove Help Window   */
 
825
 
 
826
  EXIT(type);
 
827
}
 
828
  
 
829
/*==========================================================================
 
830
 *                      tw_modf
 
831
 *==========================================================================*/
 
832
int tw_modf(w, str, nbytes, linput, fct)
 
833
/*+++
 
834
.PURPOSE Get a command string from terminal, made of up to (nbytes-1)
 
835
        characters, but with check using the user--supplied
 
836
        function fct. 
 
837
\begin{TeX}
 
838
The supplied {\em fct} function is called before returning from
 
839
        the general input function, \ie just after the \meta{Carriage Return}
 
840
        or any other character that stops the input.
 
841
        The fct function has three arguments:
 
842
        \begin{enumerate}
 
843
        \item The window used
 
844
        \item   the input string
 
845
        \item   the size of this string (for modifications)
 
846
        \end{enumerate}
 
847
ans should return OK (the input is good) or NOK (the input is bad).
 
848
\end{TeX}
 
849
.RETURNS _EOF_ / _INTERRUPT_ / 0 / _STANDARD_ / _ARROW_ / _KEYPAD_ / _FK_ / _PF_
 
850
        (see tw_mods)
 
851
---*/
 
852
        WINDOW  *w;             /* MOD: Window to echo the input        */
 
853
        char    *str;           /* MOD: The buffer to get the input     */
 
854
        int     nbytes;         /* IN: Length of the input buffer (<0 stretchable)      */
 
855
        int     linput;         /* IN: Length of the string to modify   */
 
856
        int     (*fct)();       /* IN: The check function       */
 
857
{
 
858
        int     status;
 
859
 
 
860
  ENTER("tw_modf");
 
861
 
 
862
  f_ed = fct;
 
863
  status    = tw_mods(w, str, nbytes, linput);
 
864
  f_ed = NULL_FCT(int);
 
865
 
 
866
  EXIT(status);
 
867
}
 
868
  
 
869
/*==========================================================================
 
870
 *                      tw_mods
 
871
 *==========================================================================*/
 
872
int     tw_mods(w, str, nbytes, linput)
 
873
/*+++
 
874
.PURPOSE Display a template command, and get a command string 
 
875
        from terminal, made of up to (nbytes-1)
 
876
        characters, and echo on specified window.
 
877
        The input stops when the one of the characters
 
878
        specified by tw_stopin is hit (the Carriage Return only by default).
 
879
\begin{TeX}
 
880
        {\em Note that keypad characters are considered as normal chars,
 
881
        unless {\tt tw\_stopin(w, \_KEYPAD\_,"*")}  was called.}
 
882
\end{TeX}
 
883
.RETURNS OK or _STANDARD_, EOF, NOK, _KEYPAD_, _PF_, _FK_ with the 
 
884
following meanings:
 
885
\begin{TeX}
 
886
\begin{itemize}
 
887
\item   OK or \_STANDARD\_: a $<$Carriage\_Return$>$ or $<$Enter$>$
 
888
        terminates the input;
 
889
        this last character is not reported to the string,
 
890
        but {\em is replaced by the EOS character.}
 
891
\item   NOK: either
 
892
        \begin{itemize}
 
893
        \item the window is Display Only (no input available)
 
894
        \item the size of the input string is 1 character or less
 
895
                (nbytes $<2$)
 
896
        \item a control / arrow / keypad / PK / Function character was typed 
 
897
                at the terminal, which is {\em not the 
 
898
                first} input char;
 
899
                the returned string contains the previous characters
 
900
                (\ie before the stopping char), and a next call to 
 
901
                the function will return the control character.
 
902
        \end{itemize}
 
903
\item   \_INTERRUPT\_: the {\em Interrupt}(Control\_C) 
 
904
        char was typed. Output string is blanked.
 
905
\item   \_EOF\_: the EOF (Control\_Z or Control\_D, depending on InitWindow) 
 
906
        char was typed as the
 
907
        {\em first} input character; the output string contains only
 
908
        a zero (EOS).
 
909
        {\em Note that the EOF character not typed as the first char
 
910
        returns NOK.}
 
911
\item   \_KEYPAD\_: a keypad key is the 
 
912
        {\em first} input character and the Keypad is enabled
 
913
        via a previous call to {\tt tw\_stopin(w, \_KEYPAD\_, "*")}; 
 
914
        the output string contains the equivalence keypad.
 
915
        If the Keypad is enabled via {\em tw\_stopin}, and a Keypad
 
916
        was hit after normal ASCII characters, the function returns NOK.
 
917
        Note that keypad keys are translated if the keypad is not enabled.
 
918
\item   \_PF\_: a PF key is the 
 
919
        {\em first} input character if PF keys were previously enabled
 
920
        via {\tt tw\_stopin(w, \_PF\_, "*")}.
 
921
\item   \_FK\_: a Function is the 
 
922
        {\em first} input character if Function  keys were previously enabled
 
923
        via {\tt tw\_stopin(w, \_FK\_, "*")}.
 
924
\end{itemize}
 
925
\end{TeX}
 
926
.REMARKS 
 
927
---*/
 
928
        WINDOW  *w;             /* MOD: Window to echo the input        */
 
929
        char    *str;           /* MOD: The buffer to get the input     */
 
930
        int     nbytes; /* IN: Length of the input buffer (<0 stretchable) */
 
931
        int     linput;         /* IN: Length of template string        */
 
932
{
 
933
        char    *p;             /* Current position in str      */
 
934
        int     type;
 
935
        int     i, l, k, old_stoplen;
 
936
        int     old_marker[2];
 
937
        char    ch;
 
938
        unsigned char old_flags, old_control;
 
939
        FUNCTION old_int;
 
940
        
 
941
  ENTER("tw_mods");
 
942
 
 
943
  type = 0;
 
944
  old_control = ' ';
 
945
  i = ABSOLUTE(nbytes);
 
946
  if (i < 2)            EXIT(NOK);              /* Buffer too small     */
 
947
 
 
948
  saved_screen_len = 0;
 
949
  input_start = str;
 
950
 
 
951
  if_not(check(w))      
 
952
  {     *input_start = EOS;
 
953
        EXIT(NOK);
 
954
  }
 
955
 
 
956
  if (nbytes < 0)                       /* Use Stretchable Window       */
 
957
        nbytes = -nbytes, 
 
958
        OpenStretchableWindow(nbytes-1);
 
959
 
 
960
 
 
961
  old_pos = W->pos;     /* Keep first initial data */
 
962
  old_marker[0] = W->marker[0], old_marker[1] = W->marker[1];
 
963
  old_flags = W->flags;
 
964
  old_stoplen = stop_len;
 
965
 
 
966
  if (old_pos >= W->marker[1])  EXIT(NOK);
 
967
  
 
968
  p = input_start, input_valid = p;
 
969
  f |= W->flags & (Imode|Echo|Stacking);
 
970
  if ( (f&Echo) == 0)   f &= ~Stacking;         /* No stacking if no echo ... */
 
971
 
 
972
 
 
973
        /* To be sure that wrapping allowed, install a Range on the
 
974
         * Window. Anything will then be limited to the Range
 
975
         */
 
976
 
 
977
  l = tw_amark(W, W->pos, nbytes-1);
 
978
  input_end = p + l;
 
979
 
 
980
  if(f&Echo)    if (tw_occluded(W,0))   f |= Occluded;
 
981
                                /* Can't optimize output...             */
 
982
 
 
983
  if (f&Stacking)               /* Set stack to (last+1) command        */
 
984
  {     c->pointed = c->used;
 
985
        c->pointed_no = c->last_no + 1;
 
986
        command_number = c->pointed_no;
 
987
  }
 
988
  else  command_number = -1;
 
989
 
 
990
        /* Echo template string, and position cursor to End of Template */
 
991
        /**** Note: If No Echo, DON'T DISPLAY INPUT ....................*/
 
992
 
 
993
  if ((linput > 0) && (f&Echo))
 
994
  {     i = MIN(linput, input_end - input_start);
 
995
        tw_write(W, input_start, i, 0);
 
996
        /* p += i, input_valid = p;     If Cursor at END of text */
 
997
        input_valid = input_start + i; tw_agoto(W, old_pos); 
 
998
                                        /* Cursor at BEGINNING of text */
 
999
  }
 
1000
  tw_agoto(W, old_pos); 
 
1001
 
 
1002
  old_int = OnInterrupt((void *)InInt);         /* Install Interrupt Function   */
 
1003
  
 
1004
        /* Loop on the input char       */
 
1005
 
 
1006
  while (1)
 
1007
  {     
 
1008
        if (f&Stop)     /* Check with the Function      */
 
1009
        {
 
1010
                if (f&Interrupted)      /* Delete the Whole Line */
 
1011
                {       tw_agoto(W, old_pos);
 
1012
                        i = input_valid - input_start;  /* Number of chars to delete */
 
1013
                        p = input_start, input_valid = p;
 
1014
                        here_Delete(i);
 
1015
                        break;
 
1016
                }
 
1017
 
 
1018
                if (f_ed)
 
1019
                {       *input_valid = EOS;
 
1020
                        /* tw_agoto(W, old_pos + (input_valid - input_start));*/
 
1021
                        k = (*f_ed)(W, input_start, nbytes);    /* Call... */
 
1022
                        l = strlen(input_start);/* Don't redisplay if stretch */
 
1023
                        if (saved_screen_len == 0) 
 
1024
                                l = show(input_start, l);
 
1025
                        input_valid = input_start + l;
 
1026
                        if (p > input_valid)    p = input_valid;
 
1027
                        tw_agoto(W, old_pos + (p - input_start));
 
1028
                        if (k)  break;                  /* Anything OK  */
 
1029
                        f &= ~Stop;                     /* Bad input... */
 
1030
                        continue;
 
1031
                }
 
1032
                break;
 
1033
        }
 
1034
 
 
1035
        if ((f & Stop1) && (p == input_end)     )       break;
 
1036
 
 
1037
        if (f & NoMore)         /* Too long string...   */
 
1038
        {       Bell();         
 
1039
                f &= ~NoMore;
 
1040
        }
 
1041
 
 
1042
                /* When there is a stopping list, install the terminal
 
1043
                   as NOMAP. This is done via SetControls
 
1044
                */
 
1045
        if (stop_len > 0)       old_control = SetControls(0);
 
1046
        type = GetChar(&ch);
 
1047
        if (stop_len > 0)       SetControls(old_control);
 
1048
        if(f&Interrupted)       continue;
 
1049
 
 
1050
#if DEBUG
 
1051
        TRACE_ED_STR2("Total   string is: ",input_start,input_valid-input_start);
 
1052
        TRACE_ED_STR2("Present string is: ",input_start,p-input_start);
 
1053
        TRACE_ED_STR2("Just read        : ",&ch, 1);
 
1054
        TRACE_ED_I   (" ... of type: ",type);
 
1055
#endif
 
1056
 
 
1057
        if ( type == NOK)       /* Bad Escape Sequence...       */
 
1058
        {       if (f & Stop1)  f |= (Stop|Special);
 
1059
                if (input_valid == input_start) /* Was First Input Character */
 
1060
                                f |= (Stop|Special);
 
1061
                else            Bell();
 
1062
                continue;
 
1063
        }
 
1064
 
 
1065
        if (f & Raw)            type = _STANDARD_;
 
1066
 
 
1067
        if (f&Imode)    W->flags |= Imode;
 
1068
                else    W->flags &= ~Imode;
 
1069
 
 
1070
        switch(type)
 
1071
        { case EOF:     f |= (Stop|Special);
 
1072
                continue;
 
1073
 
 
1074
          case _PF_: case _FK_:
 
1075
                if (c->exit_pf & MASK(type))
 
1076
                        f |= (Stop|Special);
 
1077
                else            Bell();
 
1078
                continue;
 
1079
 
 
1080
          case _ARROW_: 
 
1081
                i = MASK(ch);
 
1082
                if (c->exit_ar & i)                     /* Possible Stop */
 
1083
                {       if(c->exit_ar & MASK(_TEE_));   /* not Immediate */
 
1084
                        else    { f |= (Stop|Special); continue; }
 
1085
                }
 
1086
                if ((f&Stacking) && (i&(MASK(_UP_)|MASK(_DOWN_))))
 
1087
                {               /* Copy retrieved command, and edit it  */
 
1088
                        if (c->pointed_no == command_number)
 
1089
                                /* Save what has been typed */
 
1090
                                zadd(input_start, input_valid-input_start, 0);
 
1091
#       if TWFAC_Stacking
 
1092
                        zm(ch);         /* Move in Stack */
 
1093
                        i = c->pointed;
 
1094
                        l = *(c->text + i);
 
1095
                        l = move(input_start, (char *)(c->text + i + 1), l);
 
1096
                        show(input_start, l);
 
1097
                        p = input_start + l, input_valid = p;
 
1098
#       endif
 
1099
                        continue;
 
1100
                }
 
1101
                                        /* Reflect Cursor Displacement  */
 
1102
                if_not (mv1(ch, input_valid-p))         /* No possible move     */
 
1103
                        if (c->exit_ar & i)             /* Must Stop    */
 
1104
                                f |= (Stop|Special);
 
1105
                p = input_start + (W->pos - W->marker[0]);      /* Pos in buf   */
 
1106
                continue;
 
1107
                
 
1108
          case _KEYPAD_:
 
1109
                if (c->exit_pf & MASK(_KEYPAD_))
 
1110
                {       f |= (Stop|Special);
 
1111
                        continue;
 
1112
                }
 
1113
                type = _STANDARD_;  /* Keypad chars are considered as normal */
 
1114
                break;
 
1115
        }               
 
1116
 
 
1117
        if (stop_len > 0)  {            /* Check first byte     */
 
1118
                if (oscloc(stop_list, stop_len, ch) < stop_len) {
 
1119
                        stop_len = -1;          /* Found*/
 
1120
                        f |= (Stop|Special);
 
1121
                        continue;
 
1122
                }
 
1123
                stop_len = 0; 
 
1124
        }
 
1125
 
 
1126
        /* --- Here Only if it's an ASCII character ---- */
 
1127
 
 
1128
        if ((isprint(ch)) || (f&Raw) || (terms->flags & TERM_NOMAP)) {
 
1129
                f &= ~Raw;
 
1130
                if (f & Imode)
 
1131
                {       if ( (input_valid) >= input_end)        f |= NoMore;
 
1132
                        else oscopy ( p+1, p, input_valid++ - p);
 
1133
                }
 
1134
                else            /* Replace Mode */
 
1135
                {       if (input_valid <= p)           input_valid = p+1;
 
1136
                        if (input_valid > input_end)    input_valid--, f |= NoMore;
 
1137
                }
 
1138
                if (f & NoMore)         /* Too long string...   */
 
1139
                        continue;
 
1140
                *(p++) = ch;
 
1141
                o1(&ch);                /* Echo the character...*/
 
1142
                if (stop_len <= 0)      continue;
 
1143
        }
 
1144
 
 
1145
                /*==============================================*/
 
1146
                /* ---     Here only if it's a Control Char     */
 
1147
                /*==============================================*/
 
1148
        
 
1149
        if (ch == '\r')                         /* Normal End   */
 
1150
        {       f |= Stop;
 
1151
                if (f&Stop1)    f |= Special;
 
1152
                continue;
 
1153
        }
 
1154
 
 
1155
        i = *(unsigned char *)(&ch);
 
1156
        if (i > 32)             /* Delete char  */
 
1157
        {       i = 32;
 
1158
                if (f&Stop1)    { f |= Stop|Special; continue; }
 
1159
        }
 
1160
 
 
1161
        if (c->exit_cc & MASK(i))               /* Exit on Control      */
 
1162
        {       f |= (Stop|Special);
 
1163
                continue;
 
1164
        }
 
1165
 
 
1166
        switch(terms->tc[i])
 
1167
        { default:              Bell();         /* Just ignore...       */
 
1168
                continue;
 
1169
 
 
1170
          case TW_cc_EOF:       f |= (Stop|Special);
 
1171
                type = EOF;
 
1172
                continue;
 
1173
 
 
1174
          case TW_cc_RAW:       f |= Raw;
 
1175
                continue;
 
1176
 
 
1177
          case TW_cc_REFR:                      /* Refresh Screen       */
 
1178
                tw_r(NULL_WINDOW,1,NULL_WINDOW);
 
1179
                continue;
 
1180
 
 
1181
          case TW_cc_HELP:      tw_helps(W,1);  /* Switch the Help Wind */
 
1182
                f &= ~Occluded;
 
1183
                if(f&Echo)      if (tw_occluded(W,0))   f |= Occluded;
 
1184
                continue;
 
1185
 
 
1186
          case TW_cc_MODE:      f ^= Imode;     /* Change mode  */
 
1187
                continue;       /* Window Imode flag done at loop top   */
 
1188
 
 
1189
          case TW_cc_NW:                        /* Move to next word    */
 
1190
                p += oscscan((unsigned char *)p, input_valid-p, _SPACE_, main_ascii);
 
1191
                p += oscspan((unsigned char *)p, input_valid-p, _SPACE_, main_ascii);
 
1192
                tw_agoto(W, old_pos + (p-input_start));
 
1193
                continue;
 
1194
 
 
1195
          case TW_cc_EOL:                       /* Move cursor to end   */
 
1196
                tw_agoto(W, old_pos + (input_valid - input_start));
 
1197
                p = input_valid;
 
1198
                continue;
 
1199
 
 
1200
          case TW_cc_DELC:                      /* Delete Char  */
 
1201
                if (p > input_start) 
 
1202
                {       p--, input_valid--;
 
1203
                        oscopy(p, p+1, input_valid-p);
 
1204
                        here_Delete(-1);
 
1205
                }
 
1206
                continue;
 
1207
 
 
1208
          case TW_cc_DELL:                      /* Clear Line = delete all */
 
1209
                tw_agoto(W, old_pos);
 
1210
                i = input_valid - input_start;  /* Number of chars to delete */
 
1211
                p = input_start, input_valid = p;
 
1212
                here_Delete(i);
 
1213
                stop_len = old_stoplen;
 
1214
                continue;
 
1215
 
 
1216
          case TW_cc_DELE:                      /* Delete to the right  */
 
1217
                i = input_valid - p;
 
1218
                input_valid = p;
 
1219
                here_Delete(i);
 
1220
                continue;
 
1221
 
 
1222
          case TW_cc_DELW:                      /* Delete Previous Word */
 
1223
                i = oscbspan((unsigned char *)input_start, p-input_start, _SPACE_, main_ascii);
 
1224
                i = oscbscan((unsigned char *)input_start, i+1, _SPACE_, main_ascii);
 
1225
                i = (p-input_start) - (i+1);    /* Number of chars to delete */
 
1226
                oscopy(p-i, p, input_valid-p);
 
1227
                p -= i, input_valid -= i;
 
1228
                here_Delete(-i);
 
1229
                continue;
 
1230
        }
 
1231
  }
 
1232
 
 
1233
  if (f&Interrupted)    type = _INTERRUPT_, input_valid = input_start;
 
1234
  p = input_valid, l = p - input_start;         /* Final Length of String */
 
1235
 
 
1236
 
 
1237
        /* Add the string to command stack      */
 
1238
 
 
1239
  if ( (f&Stacking) && (type <= _STANDARD_)  && (l > 0))
 
1240
        zadd(input_start, l, 2);
 
1241
 
 
1242
  if (f & Special)
 
1243
  {     if (input_valid == input_start)         /* Was First Input Character */
 
1244
                *(p++) = ch;
 
1245
        else    tv_push(type, ch), type = NOK;
 
1246
  }
 
1247
  *p = EOS;
 
1248
 
 
1249
 
 
1250
 
 
1251
  if_not(f&Stop1)       tw_helps(W,0);          /* Remove Help Window   */
 
1252
  W->marker[0] = old_marker[0], W->marker[1] = old_marker[1];
 
1253
  W->flags = old_flags;
 
1254
 
 
1255
  if(saved_screen_len)                  /* Restore The Text     */
 
1256
  {
 
1257
        tw_st(W, Echo, 0);
 
1258
        k = W->pos;
 
1259
        tw_agoto(W, old_pos);
 
1260
        tw_wa(W, saved_screen, saved_screen_len);
 
1261
        tw_agoto(W, k);
 
1262
        if (f&Echo)     tw_st(W, Echo, 1), tw_r(W,0,NULL_WINDOW);
 
1263
  }
 
1264
  f = 0;
 
1265
  OnInterrupt(old_int);
 
1266
 
 
1267
  TRACE(str);
 
1268
 
 
1269
  EXIT(type);
 
1270
}
 
1271
 
 
1272
#if DEBUG
 
1273
/*==========================================================================
 
1274
 *                      zed
 
1275
 *==========================================================================*/
 
1276
static int zed(opt)
 
1277
/*+++
 
1278
.PURPOSE Edit a stack (for debugging purposes)
 
1279
.RETURNS OK 
 
1280
.REMARKS Option 1 to display the whole stack
 
1281
---*/
 
1282
        int     opt;            /* IN: Edition option   */
 
1283
{
 
1284
        char    msg[80];
 
1285
        char    *p;
 
1286
        int     i,u,l;
 
1287
 
 
1288
  sprintf(msg,"!size=%d, used=%d, pointed=%d, no=%d, first=%d, last=%d",
 
1289
        c->size, c->used, c->pointed, c->pointed_no, c->first_no,
 
1290
        c->last_no);
 
1291
  LOG(msg);
 
1292
 
 
1293
  if(opt)
 
1294
  {     TRACE_ED_HEXA("Stack is:",c->text,c->used);
 
1295
        for (p = (char *)(c->text)+2, i=c->first_no; i<= c->last_no; i++)
 
1296
        {       sprintf(msg,"!No %4d=>",i);
 
1297
                TRACE_ED_STR2(msg,p+1,*p);
 
1298
                p += *p;        p += 2;
 
1299
        }
 
1300
  }
 
1301
 
 
1302
  return(OK);
 
1303
}
 
1304
#endif
 
1305
 
 
1306
/*==========================================================================
 
1307
 *                      tw_zadd
 
1308
 *==========================================================================*/
 
1309
int     tw_zadd(w, str, nbytes)
 
1310
/*+++
 
1311
.PURPOSE Insert into the command stack the string str.
 
1312
.RETURNS OK / NOK (not enough space)
 
1313
.REMARKS The command IS NOT inserted if it's the same as the previoue one.
 
1314
---*/
 
1315
        WINDOW *w;              /* IN: The concerned Window     */
 
1316
        char    *str;           /* IN: The string to insert */
 
1317
        int     nbytes;         /* IN: Length of the str string */
 
1318
{
 
1319
  ENTER("tw_zadd");
 
1320
  status = check(w);    
 
1321
  if(status)            status = zadd(str, nbytes, 2);
 
1322
  EXIT(status)  ;
 
1323
}
 
1324
 
 
1325
/*==========================================================================*/
 
1326
static int zclear()
 
1327
/*+++
 
1328
.PURPOSE Clear the command stack.
 
1329
.RETURNS OK 
 
1330
.REMARKS 
 
1331
---*/
 
1332
{       
 
1333
#if TWFAC_Stacking
 
1334
        unsigned char *p;
 
1335
 
 
1336
  if (c->size < 2)              FINISH;
 
1337
 
 
1338
  DISPLAY(0);
 
1339
 
 
1340
  c->used = 2;
 
1341
  c->pointed = 0;
 
1342
  c->pointed_no = 0;
 
1343
  c->first_no = 1;
 
1344
  c->last_no  = 0;
 
1345
  p = c->text;
 
1346
 
 
1347
  *(p++) = 0;
 
1348
  *(p++) = 0;
 
1349
 
 
1350
  DISPLAY(0);
 
1351
 
 
1352
  FIN:
 
1353
  return(OK);
 
1354
#else
 
1355
  return(NOK);
 
1356
#endif
 
1357
}
 
1358
 
 
1359
/*==========================================================================
 
1360
 *                      tw_zclear
 
1361
 *==========================================================================*/
 
1362
int     tw_zclear(w)
 
1363
/*+++
 
1364
.PURPOSE Clear the command stack.
 
1365
.RETURNS OK 
 
1366
.REMARKS 
 
1367
---*/
 
1368
        WINDOW *w;      /* IN: The concerned Window     */
 
1369
{
 
1370
  ENTER("tw_zclear");
 
1371
  status = check(w);
 
1372
  if(status)            status = zclear();
 
1373
  EXIT(status)  ;
 
1374
}
 
1375
 
 
1376
/*==========================================================================
 
1377
 *                      tw_zm
 
1378
 *==========================================================================*/
 
1379
int     tw_zm(w, direction)
 
1380
/*+++
 
1381
.PURPOSE Move in the command stack according to the specified direction.
 
1382
.RETURNS OK / NOK (at the top or bottom of the stack)
 
1383
.REMARKS 
 
1384
---*/
 
1385
        WINDOW *w;              /* IN: The concerned Window     */
 
1386
        int     direction;      /* IN: _UP_, _DOWN_ or _HOME_ (last command) */
 
1387
{
 
1388
  ENTER("tw_zm");
 
1389
  status = check(w);
 
1390
  if(status)            status = zm(direction);
 
1391
  EXIT(status)  ;
 
1392
}
 
1393
 
 
1394
/*==========================================================================
 
1395
 *                      tw_zn
 
1396
 *==========================================================================*/
 
1397
static int zn(number)
 
1398
/*+++
 
1399
.PURPOSE Move in the stack to a specified numbered command
 
1400
.RETURNS OK / NOK (numbered command not in stack)
 
1401
.REMARKS 
 
1402
---*/
 
1403
        int     number;         /* IN: Command number   */
 
1404
{
 
1405
#if TWFAC_Stacking
 
1406
        int n;
 
1407
 
 
1408
#if DEBUG
 
1409
        TRACE_ED_I("Getting command #",number);
 
1410
#endif
 
1411
 
 
1412
  status = NOK;
 
1413
 
 
1414
  if (c->size == 0)             FINISH;
 
1415
 
 
1416
  DISPLAY(0);
 
1417
 
 
1418
  n = number;
 
1419
  if (n < c->first_no)          FINISH;
 
1420
  if (n > c->last_no)           FINISH;
 
1421
 
 
1422
  if ( (n - c->first_no) < 3)
 
1423
  {     c->pointed = 2;
 
1424
        c->pointed_no = c->first_no;
 
1425
  }
 
1426
 
 
1427
  while (c->pointed_no > n)     zm(_UP_);
 
1428
  while (c->pointed_no < n)     zm(_DOWN_);
 
1429
 
 
1430
  DISPLAY(0);
 
1431
 
 
1432
  status = OK;
 
1433
  FIN:
 
1434
  return(status);
 
1435
#else
 
1436
  return(NOK);
 
1437
#endif
 
1438
}
 
1439
 
 
1440
/*==========================================================================*/
 
1441
int     tw_zn(w, number)
 
1442
/*+++
 
1443
.PURPOSE Move in the stack to a specified numbered command
 
1444
.RETURNS OK / NOK (numbered command not in stack)
 
1445
.REMARKS 
 
1446
---*/
 
1447
        WINDOW *w;              /* IN: The concerned Window     */
 
1448
        int     number;         /* IN: Command number   */
 
1449
{
 
1450
  ENTER("tw_zn");
 
1451
  status = check(w);
 
1452
  if(status)            status = zn(number);
 
1453
  EXIT(status)  ;
 
1454
}
 
1455
 
 
1456
/*==========================================================================
 
1457
 *                      tw_zo1
 
1458
 *==========================================================================*/
 
1459
static int zo1(w, option)
 
1460
/*+++
 
1461
.PURPOSE Edit on a specified window the current stacked command
 
1462
.RETURNS OK / NOK (no stacked command)
 
1463
.REMARKS The edition starts on a new line
 
1464
---*/
 
1465
        WINDOW  *w;             /* MOD: Window for output       */
 
1466
        int     option;         /* IN: 1 to edit with number */
 
1467
{
 
1468
#if TWFAC_Stacking
 
1469
        unsigned char   *p;
 
1470
        int             n, i;
 
1471
        MID_STATIC char c_no[6] = {' ', ' ', ' ', ' ', ':', ' '};
 
1472
 
 
1473
  status = NOK;
 
1474
 
 
1475
  if (c->size == 0)                     FINISH;
 
1476
  if (c->pointed_no < c->first_no)      FINISH;
 
1477
  if (c->pointed_no > c->last_no)       FINISH;
 
1478
 
 
1479
  DISPLAY(0);
 
1480
 
 
1481
  f = w->flags & Echo;
 
1482
  w->flags &= ~Echo;  
 
1483
 
 
1484
  if (w->pos % w->Nj)           tw_nl(w);
 
1485
 
 
1486
  if (option)   
 
1487
  {     i = sizeof(c_no) - 2;
 
1488
        for (n = c->pointed_no; --i >= 0; n /= 10)
 
1489
                c_no[i] = (n ? n%10+'0' : ' ');
 
1490
        tw_write(w, c_no, sizeof(c_no), 0);
 
1491
  }
 
1492
 
 
1493
  p = c->text + c->pointed;
 
1494
  tw_line(w, p+1, *p, 0);
 
1495
 
 
1496
  if (f)
 
1497
  {     w->flags |= Echo, f = 0;
 
1498
        tw_rw(w, 0,NULL_WINDOW);
 
1499
  }
 
1500
  status = OK;
 
1501
 
 
1502
  FIN:
 
1503
  return(OK);
 
1504
#else
 
1505
  return(NOK);
 
1506
#endif
 
1507
}
 
1508
 
 
1509
/*==========================================================================*/
 
1510
int     tw_zo1(w, win, option)
 
1511
/*+++
 
1512
.PURPOSE Edit on a specified window the current stacked command
 
1513
.RETURNS OK / NOK (no stacked command)
 
1514
.REMARKS The edition starts on a new line
 
1515
---*/
 
1516
        WINDOW  *w;             /* MOD: Window for output       */
 
1517
        WINDOW *win;            /* IN: The concerned Window     */
 
1518
        int     option;         /* IN: 1 to edit with number */
 
1519
{
 
1520
  ENTER("tw_zo1");
 
1521
  status = check(win);
 
1522
  if(status)    status = zo1(w, option);
 
1523
  EXIT(status)  ;
 
1524
}
 
1525
 
 
1526
/*==========================================================================
 
1527
 *                      tw_zo
 
1528
 *==========================================================================*/
 
1529
static int zo(w, option)
 
1530
/*+++
 
1531
.PURPOSE Edit on a specified window the stack contents
 
1532
.RETURNS OK / NOK (no stacked command)
 
1533
.REMARKS The edition starts on a new line. The window is cleared before
 
1534
        the edition. If the window is active with scrolling, 
 
1535
        ALL commands are listed.
 
1536
---*/
 
1537
        WINDOW  *w;             /* MOD: Window for output       */
 
1538
        int     option;         /* IN: 1 to edit with number */
 
1539
{
 
1540
#if TWFAC_Stacking
 
1541
        int n;
 
1542
 
 
1543
  status = NOK;
 
1544
 
 
1545
  if (c->size == 0)             FINISH;
 
1546
  if (c->pointed_no == 0)       FINISH;
 
1547
 
 
1548
  DISPLAY(1);
 
1549
 
 
1550
        /* Computation of the number of commands that can be issued     */
 
1551
  n = c->last_no - c->first_no + 1;
 
1552
  if ( n > w->Ni )      n = c->last_no - w->Ni + 1;
 
1553
        else            n = c->first_no;
 
1554
  /* if ( (w->active) && (w->scroll) )  n = c->first_no; */
 
1555
 
 
1556
  zn(n);
 
1557
  tw_clear(w,_WHOLE_);
 
1558
 
 
1559
  while (1)
 
1560
  {     zo1(w,option);
 
1561
        if_not(zm(_DOWN_))      break;
 
1562
  }
 
1563
 
 
1564
  status = OK;
 
1565
  FIN:
 
1566
  return(status);
 
1567
#else
 
1568
  return(NOK);
 
1569
#endif
 
1570
}
 
1571
 
 
1572
/*==========================================================================*/
 
1573
int     tw_zo(w, win, option)
 
1574
/*+++
 
1575
.PURPOSE Edit on a specified window the stack contents
 
1576
.RETURNS OK / NOK (no stacked command)
 
1577
.REMARKS The edition starts on a new line. The window is cleared before
 
1578
        the edition. If the window is active with scrolling, 
 
1579
        ALL commands are listed.
 
1580
---*/
 
1581
        WINDOW  *w;             /* MOD: Window for output       */
 
1582
        WINDOW *win;            /* IN: The concerned Window     */
 
1583
        int     option;         /* IN: 1 to edit with number */
 
1584
{
 
1585
  ENTER("tw_zo");
 
1586
  status = check(win);
 
1587
  if(status)    status = zo(w, option);
 
1588
  EXIT(status)  ;
 
1589
}
 
1590