libDtSearch: Coverity 86579
[oweals/cde.git] / cde / lib / DtTerm / Term / TermAction.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 #ifndef lint
24 #ifdef  VERBOSE_REV_INFO
25 static char rcs_id[] = "$XConsortium: TermAction.c /main/1 1996/04/21 19:15:17 drk $";
26 #endif  /* VERBOSE_REV_INFO */
27 #endif  /* lint */
28
29 /*                                                                      *
30  * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company               *
31  * (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
32  * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.                *
33  * (c) Copyright 1993, 1994, 1996 Novell, Inc.                          *
34  * (c) Copyright 1996 Digital Equipment Corporation.                    *
35  * (c) Copyright 1996 FUJITSU LIMITED.                                  *
36  * (c) Copyright 1996 Hitachi.                                          *
37  */
38
39 #include "TermHeader.h"
40 #include "TermPrimDebug.h"
41 #include "TermPrimI.h"
42 #include "TermP.h"
43 #include "TermPrimData.h"
44 /* #include "TermData.h" */
45 #include "TermPrimAction.h"
46 #include "TermAction.h"
47 #include "TermFunction.h"
48 #include "TermPrimSetPty.h"
49 #include "TermSendEsc.h"
50 #ifdef _AIX
51 #include <X11/keysym.h>
52 #endif /* _AIX */
53
54 static char  *KeypadKey[] = { DT_KP_Space, DT_KP_Tab, DT_KP_Enter, DT_KP_F1, 
55                               DT_KP_F2, DT_KP_F3, DT_KP_F4, DT_KP_Equal, 
56                               DT_KP_Multiply, DT_KP_Add, DT_KP_Separator, 
57                               DT_KP_Subtract, DT_KP_Decimal, DT_KP_Divide, 
58                               DT_KP_0, DT_KP_1, DT_KP_2, DT_KP_3, DT_KP_4, 
59                               DT_KP_5, DT_KP_6, DT_KP_7, DT_KP_8, DT_KP_9};
60 static char  *AppKeypadKey[] ={KP_APP_Space, KP_APP_Tab, KP_APP_Enter,KP_APP_F1,
61                               KP_APP_F2, KP_APP_F3, KP_APP_F4, KP_APP_Equal, 
62                               KP_APP_Multiply, KP_APP_Add, KP_APP_Separator,
63                               KP_APP_Subtract, KP_APP_Decimal, KP_APP_Divide,
64                               KP_APP_0, KP_APP_1, KP_APP_2, KP_APP_3, KP_APP_4,
65                               KP_APP_5, KP_APP_6, KP_APP_7, KP_APP_8, KP_APP_9};
66 #ifdef  OBSOLETE
67 static char  *EditKey[] = {ESC_FIND, ESC_INSERT_HERE, ESC_DELETE,
68                            ESC_SELECT, ESC_PREV_SCREEN, ESC_NEXT_SCREEN};
69 static char  *SunEditKey[] = {ESC_FIND_SUN, ESC_INSERT_HERE_SUN, 
70                             ESC_DELETE_SUN, ESC_SELECT_SUN, ESC_PREV_SCREEN_SUN,
71                             ESC_NEXT_SCREEN_SUN};
72 #endif  /* OBSOLETE */
73 void
74 _DtTermWriteEscSeq(Widget w, char *transmitString)
75 {
76     DtTermWidget    tw  = (DtTermWidget)w;
77     DtTermData      td = tw->vt.td;
78
79     if (KEYBOARD_LOCKED(td->tpd->keyboardLocked)) {
80         /* keyboard locked -- ring the bell...
81          */
82         (void) _DtTermPrimBell(w);
83     } else 
84         if ( td->S8C1TMode ) {
85            char *cbuf =malloc(strlen(transmitString)+1);
86            strcpy(cbuf,transmitString) ;
87            cbuf[1] = 0x9B ;
88            (void) _DtTermPrimSendInput(w, (unsigned char *) (cbuf+1),
89                 strlen(cbuf+1));
90            free(cbuf) ;
91          }
92         else {
93            (void) _DtTermPrimSendInput(w, (unsigned char *) transmitString,
94                 strlen(transmitString));
95         }
96     return;
97 }
98
99 typedef struct {
100     const char *string;
101     char value;
102 } EnumType;
103
104 static int
105 stringToEnum(char *c, EnumType *enumTypes, int numEnumTypes)
106 {
107     int i;
108
109     for (i = 0; i < numEnumTypes; i++) {
110         if (!strcmp(enumTypes[i].string, c))
111             return(i);
112     }
113
114     return(-1);
115 }
116
117 \f
118 /*** BREAK ********************************************************************
119  * 
120  *  #####   #####   ######    ##    #    #
121  *  #    #  #    #  #        #  #   #   #
122  *  #####   #    #  #####   #    #  ####
123  *  #    #  #####   #       ######  #  #
124  *  #    #  #   #   #       #    #  #   #
125  *  #####   #    #  ######  #    #  #    #
126  */
127
128 void
129 _DtTermActionBreak(Widget w, XEvent *event, String *params, Cardinal *num_params)
130 {
131     DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
132     struct termData *tpd = tw->term.tpd;
133     int msec = 0;
134
135     /* check for keyboardLock... */
136     if (KEYBOARD_LOCKED(tpd->keyboardLocked)) {
137         (void) _DtTermPrimBell(w);
138         return;
139     }
140
141     /* tcsendbreak() , which eventually gets called, has the msec
142        parameter but it never actually gets used, so for now, its a dont care
143      */
144
145     if (tw->term.pty >= 0)
146         (void) _DtTermPrimPtySendBreak(tw->term.pty, msec);
147     return;
148 }
149
150 \f
151 /*** SCROLL *******************************************************************
152  * 
153  *   ####    ####   #####    ####   #       #
154  *  #       #    #  #    #  #    #  #       #
155  *   ####   #       #    #  #    #  #       #
156  *       #  #       #####   #    #  #       #
157  *  #    #  #    #  #   #   #    #  #       #
158  *   ####    ####   #    #   ####   ######  ######
159  */
160
161
162 typedef enum {
163     scrollPage,
164     scrollHalfPage,
165     scrollLine,
166     scrollPixel
167 } ScrollAmount;
168
169 static EnumType scrollUnits[] = {
170   { "page",     (char) scrollPage, },
171   { "halfpage", (char) scrollHalfPage, },
172   { "line",     (char) scrollLine },
173 };
174
175 void
176 _DtTermActionScroll(Widget w, XEvent *event,
177         String *params, Cardinal *num_params)
178 {
179     DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
180     struct termData *tpd = tw->term.tpd;
181     int unitsIndex;
182     ScrollAmount units;
183     int count = 1;
184
185     if (*num_params >= 1) {
186         count = strtol(params[0], (char **) 0, 0);
187     }
188
189     if (*num_params >= 2) {
190         unitsIndex = stringToEnum(params[1], scrollUnits,
191                 XtNumber(scrollUnits));
192         if (unitsIndex < 0) {
193             /* no match... */
194             return;
195         }
196         units = (ScrollAmount) scrollUnits[unitsIndex].value;
197     } else {
198         units = scrollLine;
199     }
200
201     /* perform the cursor motion...
202      */
203     switch(units) {
204     case scrollPage:
205             _DtTermFuncScroll(w, count*(tw->term.rows-1), fromAction);
206         break;
207
208     case scrollHalfPage:
209         if (count > 0) {
210             _DtTermFuncScroll(w, count * 
211                   (tw->term.rows - tpd->memoryLockRow) / 2, fromAction);
212         } else {
213             _DtTermFuncScroll(w, 
214                     count * (tw->term.rows - tpd->memoryLockRow) / 2,
215                     fromAction);
216         }
217         break;
218
219     case scrollLine:
220             _DtTermFuncScroll(w, count, fromAction);
221         break;
222     }
223     return;
224 }
225
226 void
227 _DtTermActionBeginningOfBuffer(Widget w, XEvent *event,
228         String *params, Cardinal *num_params)
229 {
230     _DtTermFuncBeginningOfBuffer(w,0,1) ;
231     (void) _DtTermPrimCursorOn(w);
232     return;
233 }
234
235 void
236 _DtTermActionEndOfBuffer(Widget w, XEvent *event,
237         String *params, Cardinal *num_params)
238 {
239     _DtTermFuncEndOfBuffer(w,0,1) ;
240     (void) _DtTermPrimCursorOn(w);
241     return;
242 }
243
244
245 \f
246 /** HARD/SOFT RESET ***********************************************************
247  *                                       #
248  *  #    #    ##    #####   #####       #    ####    ####   ######   #####
249  *  #    #   #  #   #    #  #    #     #    #       #    #  #          #
250  *  ######  #    #  #    #  #    #    #      ####   #    #  #####      #
251  *  #    #  ######  #####   #    #   #           #  #    #  #          #
252  *  #    #  #    #  #   #   #    #  #       #    #  #    #  #          #
253  *  #    #  #    #  #    #  #####  #         ####    ####   #          #
254  * 
255  * 
256  *  #####   ######   ####   ######   #####
257  *  #    #  #       #       #          #
258  *  #    #  #####    ####   #####      #
259  *  #####   #            #  #          #
260  *  #   #   #       #    #  #          #
261  *  #    #  ######   ####   ######     #
262  */
263 void
264 _DtTermActionHardReset(Widget w, XEvent *event,
265         String *params, Cardinal *num_params)
266 {
267     (void) _DtTermFuncHardReset(w, 0, fromAction);
268 }
269
270 void
271 _DtTermActionSoftReset(Widget w, XEvent *event,
272         String *params, Cardinal *num_params)
273 {
274     (void) _DtTermFuncSoftReset(w, 0, fromAction);
275 }
276
277 \f
278 /*** INSERT CHAR/LINE *********************************************************
279  * 
280  *     #    #    #   ####   ######  #####    #####
281  *     #    ##   #  #       #       #    #     #
282  *     #    # #  #   ####   #####   #    #     #
283  *     #    #  # #       #  #       #####      #
284  *     #    #   ##  #    #  #       #   #      #
285  *     #    #    #   ####   ######  #    #     #
286  * 
287  *                                       #
288  *   ####   #    #    ##    #####       #   #          #    #    #  ######
289  *  #    #  #    #   #  #   #    #     #    #          #    ##   #  #
290  *  #       ######  #    #  #    #    #     #          #    # #  #  #####
291  *  #       #    #  ######  #####    #      #          #    #  # #  #
292  *  #    #  #    #  #    #  #   #   #       #          #    #   ##  #
293  *   ####   #    #  #    #  #    # #        ######     #    #    #  ######
294  */
295
296
297 void
298 _DtTermActionInsertLine(Widget w, XEvent *event,
299         String *params, Cardinal *num_params)
300 {
301     _DtTermFuncInsertLine(w,1,1) ;
302     (void) _DtTermPrimCursorOn(w);
303 }
304
305
306 \f
307 /*** CURSOR MOTION ************************************************************
308  * 
309  *   ####   #    #  #####    ####    ####   #####
310  *  #    #  #    #  #    #  #       #    #  #    #
311  *  #       #    #  #    #   ####   #    #  #    #
312  *  #       #    #  #####        #  #    #  #####
313  *  #    #  #    #  #   #   #    #  #    #  #   #
314  *   ####    ####   #    #   ####    ####   #    #
315  * 
316  * 
317  *  #    #   ####    #####     #     ####   #    #
318  *  ##  ##  #    #     #       #    #    #  ##   #
319  *  # ## #  #    #     #       #    #    #  # #  #
320  *  #    #  #    #     #       #    #    #  #  # #
321  *  #    #  #    #     #       #    #    #  #   ##
322  *  #    #   ####      #       #     ####   #    #
323  */
324
325 typedef enum {
326     cursorForward,
327     cursorBackward,
328     cursorUp,
329     cursorDown
330 } CursorDirection;
331
332 static EnumType cursorDirections[] = {
333   { "forward",  (char) cursorForward, },
334   { "backward", (char) cursorBackward, },
335   { "up",       (char) cursorUp, },
336   { "down",     (char) cursorDown },
337 };
338
339 void
340 _DtTermActionMoveCursor(Widget w, XEvent *event,
341         String *params, Cardinal *num_params)
342 {
343     int i;
344
345     if (*num_params < 1) {
346         return;
347     }
348
349     /* figure out the direction... */
350     i = stringToEnum(params[0], cursorDirections, XtNumber(cursorDirections));
351     if (i < 0) {
352         /* no match... */
353         return;
354     }
355
356     switch((CursorDirection) cursorDirections[i].value) {
357     case cursorUp:
358         if (((DtTermWidget)w)->vt.td->applicationMode)  
359             (void) _DtTermWriteEscSeq(w, ESC_CURSOR_UP_APP);
360         else
361             (void) _DtTermWriteEscSeq(w, ESC_CURSOR_UP);
362         break;
363
364     case cursorDown:
365         if (((DtTermWidget)w)->vt.td->applicationMode)
366            (void) _DtTermWriteEscSeq(w, ESC_CURSOR_DOWN_APP);
367         else
368            (void) _DtTermWriteEscSeq(w, ESC_CURSOR_DOWN);
369         break;
370
371     case cursorForward:
372         if (((DtTermWidget)w)->vt.td->applicationMode)
373          (void) _DtTermWriteEscSeq(w, ESC_CURSOR_RIGHT_APP);
374         else
375          (void) _DtTermWriteEscSeq(w, ESC_CURSOR_RIGHT);
376         break;
377
378     case cursorBackward:
379         if (((DtTermWidget)w)->vt.td->applicationMode)
380          (void) _DtTermWriteEscSeq(w, ESC_CURSOR_LEFT_APP);
381         else
382          (void) _DtTermWriteEscSeq(w, ESC_CURSOR_LEFT);
383         break;
384     }
385     return;
386 }
387
388
389 void
390 _DtTermActionTab(Widget w, XEvent *event,
391         String *params, Cardinal *num_params)
392 {
393     (void) _DtTermPrimSendInput(w, (unsigned char *) "\t", 1);
394     return;
395 }
396
397 \f
398 /*** FUNCTION KEYS ************************************************************
399  * 
400  *  ######  #    #  #    #   ####    #####     #     ####   #    #
401  *  #       #    #  ##   #  #    #     #       #    #    #  ##   #
402  *  #####   #    #  # #  #  #          #       #    #    #  # #  #
403  *  #       #    #  #  # #  #          #       #    #    #  #  # #
404  *  #       #    #  #   ##  #    #     #       #    #    #  #   ##
405  *  #        ####   #    #   ####      #       #     ####   #    #
406  * 
407  * 
408  *  #    #  ######   #   #   ####
409  *  #   #   #         # #   #
410  *  ####    #####      #     ####
411  *  #  #    #          #         #
412  *  #   #   #          #    #    #
413  *  #    #  ######     #     ####
414  */
415 void
416 _DtTermActionFunctionKeyExecute(Widget w, XEvent *event, String *params,
417         Cardinal *num_params)
418 {
419     Boolean shift = False;
420     long keyNumber;
421     char *ret;
422     int i;
423
424     /* must have a key number, may have a shift/unshift as well... */
425     if (*num_params < 1) {
426         return;
427     }
428
429     /* get a key number... */
430     keyNumber = strtol(params[0], &ret, 0);
431
432
433     /* if we had anything left in the string, the number is bogus... */
434     if (*ret) {
435         return;
436     }
437
438     if (*num_params >= 2) {
439         if (!strcmp(params[1], "UDK")) {
440             shift = True;
441         } else if (!strcmp(params[1], "function")) {
442             shift = False;
443         } else {
444             return;
445         }
446     }
447
448     /* execute the key... */
449     (void) _DtTermFunctionKeyExecute(w, (short) keyNumber, shift);
450     return;
451 }
452
453
454 /**************************************************************************
455  *
456  *  KEYPAD 
457  *
458  */
459
460 static char *kpTypes[] = { "space", "tab",  "enter", "f1",  "f2", "f3", "f4",
461    "equal",   "multiply", "add",  "separator", "subtract", "decimal", "divide",
462    "0",  "1",  "2", "3", "4", "5", "6",  "7", "8", "9"  
463 };
464 static int no_kptypes=sizeof(kpTypes)/sizeof(char *) ;
465
466 void
467 _DtTermActionKeypadKeyExecute(Widget w, XEvent *event, String *params,
468         Cardinal *num_params)
469 {
470     DtTermWidget    tw  = (DtTermWidget)w;
471     Boolean shift = False;
472     long keyNumber;
473     char *ret;
474     int type;
475     DtTermData  td = tw->vt.td;
476
477     if (KEYBOARD_LOCKED(td->tpd->keyboardLocked)) {
478         /* keyboard locked -- ring the bell...
479          */
480         (void) _DtTermPrimBell(w);
481                return ;
482      }
483     /* must have an edit key type... */
484     if (*num_params < 1) {
485         return;
486     }
487 #ifdef _AIX
488     /*
489      * IBM JP kbd specific code. IBM JP kbd requires IM functionality
490      * to recoginze NumLock state + (*,/) key
491      *
492      * The following code is derived from TermPrim/TermPrim.c's
493      * _DtTermPrimActionKeyInput()
494      *
495      */
496     {
497         XKeyEvent     *keyEvent = (XKeyEvent *)event;
498         KeySym        keysym;
499         Status        status;
500         unsigned char string[BUFSIZ];
501         int           nbytes;
502
503         nbytes = XmImMbLookupString(w, keyEvent, (char *) string,
504                         sizeof(string), &keysym, &status);
505
506         /*
507          * Usually we have to take care of the status. Yet, this function is
508          * called only when KP_XX is pressed. So in this case, ignore any
509          * error case..... Please keep your fingers crossed !
510          */
511
512         /*
513          * Hack code........
514          */
515         if ( ( keysym == XK_KP_Add ) || ( keysym == XK_KP_Multiply ) ) {
516             if ( string[0] == '*' )
517                 params[0] = "multiply";
518             else if ( string[0] == '+' )
519                 params[0] = "add";
520         }
521     }
522 #endif /* _AIX */
523
524     type=0;
525     while( strcmp(params[0],kpTypes[type]) && type<= no_kptypes )  type++;
526
527     if (type > no_kptypes) return ;
528
529     if ( tw->vt.td->applicationKPMode ) {
530        _DtTermWriteEscSeq(w,AppKeypadKey[type]);
531      }
532     else {
533        _DtTermPrimSendInput(w,(unsigned char *)KeypadKey[type],
534                           strlen(KeypadKey[type]));
535        if ( type == 2 && tw->term.tpd->autoLineFeed )
536                  _DtTermPrimSendInput(w,(unsigned char *)"\012",1);/* newline */
537      }
538 }
539
540 /***********************************************************************
541  * 
542  *  Edit Keys (Find, Insert Here, Remove, Select, Prev Screen, Next Screen)
543  *
544  */
545
546 typedef enum {
547     findType,   
548     insertType,     
549     selectType,
550     priorType,
551     nextType,
552     deleteType,
553     removeType,
554     helpType,
555     menuType,
556     doType
557 } EditType;
558
559 static EnumType editTypes[] = {
560   { "find",     (char) findType, },
561   { "insert", (char) insertType,      },
562   { "select",   (char) selectType,  },
563   { "next",    (char) nextType,     },
564   { "prior",   (char) priorType,   },
565   { "delete",  (char) deleteType, },
566   { "remove",  (char) removeType, },
567   { "help",    (char) helpType, },
568   { "menu",    (char) menuType, },
569   { "do",      (char) doType },
570 };
571
572 void
573 _DtTermActionEditKeyExecute(Widget w, XEvent *event, String *params,
574         Cardinal *num_params)
575 {
576     DtTermWidget    tw  = (DtTermWidget)w;
577     Boolean shift = False;
578     long keyNumber;
579     char *ret;
580     int i;
581     DtTermData      td = tw->vt.td;
582
583     if (*num_params < 1) {
584         return;
585     }
586
587     /* figure out the direction... */
588     i = stringToEnum(params[0], editTypes, XtNumber(editTypes));
589     if (i < 0) {
590         /* no match... */
591         return;
592     }
593
594     switch( editTypes[i].value) {
595             case findType:  
596                     if ( tw->vt.sunFunctionKeys == False) {
597                       (void) _DtTermWriteEscSeq(w, ESC_FIND) ;
598                      }
599                     else {
600                       (void) _DtTermWriteEscSeq(w,ESC_FIND_SUN);
601                      }
602                     break;
603             case insertType:
604                     if ( tw->vt.sunFunctionKeys == False) {
605                       (void) _DtTermWriteEscSeq(w, ESC_INSERT_HERE) ;
606                      }
607                     else {
608                       (void) _DtTermWriteEscSeq(w,ESC_INSERT_HERE_SUN);
609                      }
610                     break;
611             case selectType:
612                     if ( tw->vt.sunFunctionKeys == False) {
613                       (void) _DtTermWriteEscSeq(w, ESC_SELECT) ;
614                      }
615                     else {
616                       (void) _DtTermWriteEscSeq(w,ESC_SELECT_SUN);
617                      }
618                     break;
619             case priorType:
620                     if ( tw->vt.sunFunctionKeys == False) {
621                       (void) _DtTermWriteEscSeq(w, ESC_PREV_SCREEN) ;
622                      }
623                     else {
624                       (void) _DtTermWriteEscSeq(w,ESC_PREV_SCREEN_SUN);
625                      }
626                     break;
627             case nextType:
628                     if ( tw->vt.sunFunctionKeys == False) {
629                       (void) _DtTermWriteEscSeq(w, ESC_NEXT_SCREEN) ;
630                      }
631                     else {
632                       (void) _DtTermWriteEscSeq(w,ESC_NEXT_SCREEN_SUN);
633                      }
634                     break;
635             case deleteType:
636             case removeType:
637                     if ( tw->vt.sunFunctionKeys == False) {
638                       (void) _DtTermWriteEscSeq(w, ESC_DELETE) ;
639                      }
640                     else {
641                       (void) _DtTermWriteEscSeq(w,ESC_DELETE_SUN);
642                      }
643                     break;
644
645             case helpType:
646                     if (tw->vt.sunFunctionKeys == False) {
647                         (void) _DtTermWriteEscSeq(w, ESC_HELP);
648                     } else {
649                         (void) _DtTermWriteEscSeq(w, ESC_HELP_SUN);
650                     }
651                     break;
652
653             case menuType:
654                     if (tw->vt.sunFunctionKeys == False) {
655                         (void) _DtTermWriteEscSeq(w, ESC_MENU);
656                     } else {
657                         (void) _DtTermWriteEscSeq(w, ESC_MENU_SUN);
658                     }
659                     break;
660
661             case doType:
662                     if (tw->vt.sunFunctionKeys == False) {
663                         (void) _DtTermWriteEscSeq(w, ESC_DO);
664                     } else {
665                         (void) _DtTermWriteEscSeq(w, ESC_DO_SUN);
666                     }
667                     break;
668        
669        }
670 }