2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
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 */
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. *
39 #include "TermHeader.h"
40 #include "TermPrimDebug.h"
41 #include "TermPrimI.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"
51 #include <X11/keysym.h>
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};
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,
74 _DtTermWriteEscSeq(Widget w, char *transmitString)
76 DtTermWidget tw = (DtTermWidget)w;
77 DtTermData td = tw->vt.td;
79 if (KEYBOARD_LOCKED(td->tpd->keyboardLocked)) {
80 /* keyboard locked -- ring the bell...
82 (void) _DtTermPrimBell(w);
84 if ( td->S8C1TMode ) {
85 char *cbuf =malloc(strlen(transmitString)+1);
86 strcpy(cbuf,transmitString) ;
88 (void) _DtTermPrimSendInput(w, (unsigned char *) (cbuf+1),
93 (void) _DtTermPrimSendInput(w, (unsigned char *) transmitString,
94 strlen(transmitString));
105 stringToEnum(char *c, EnumType *enumTypes, int numEnumTypes)
109 for (i = 0; i < numEnumTypes; i++) {
110 if (!strcmp(enumTypes[i].string, c))
118 /*** BREAK ********************************************************************
120 * ##### ##### ###### ## # #
122 * ##### # # ##### # # ####
123 * # # ##### # ###### # #
125 * ##### # # ###### # # # #
129 _DtTermActionBreak(Widget w, XEvent *event, String *params, Cardinal *num_params)
131 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
132 struct termData *tpd = tw->term.tpd;
135 /* check for keyboardLock... */
136 if (KEYBOARD_LOCKED(tpd->keyboardLocked)) {
137 (void) _DtTermPrimBell(w);
141 /* tcsendbreak() , which eventually gets called, has the msec
142 parameter but it never actually gets used, so for now, its a dont care
145 if (tw->term.pty >= 0)
146 (void) _DtTermPrimPtySendBreak(tw->term.pty, msec);
151 /*** SCROLL *******************************************************************
153 * #### #### ##### #### # #
157 * # # # # # # # # # #
158 * #### #### # # #### ###### ######
169 static EnumType scrollUnits[] = {
170 { "page", (char) scrollPage, },
171 { "halfpage", (char) scrollHalfPage, },
172 { "line", (char) scrollLine },
176 _DtTermActionScroll(Widget w, XEvent *event,
177 String *params, Cardinal *num_params)
179 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
180 struct termData *tpd = tw->term.tpd;
185 if (*num_params >= 1) {
186 count = strtol(params[0], (char **) 0, 0);
189 if (*num_params >= 2) {
190 unitsIndex = stringToEnum(params[1], scrollUnits,
191 XtNumber(scrollUnits));
192 if (unitsIndex < 0) {
196 units = (ScrollAmount) scrollUnits[unitsIndex].value;
201 /* perform the cursor motion...
205 _DtTermFuncScroll(w, count*(tw->term.rows-1), fromAction);
210 _DtTermFuncScroll(w, count *
211 (tw->term.rows - tpd->memoryLockRow) / 2, fromAction);
214 count * (tw->term.rows - tpd->memoryLockRow) / 2,
220 _DtTermFuncScroll(w, count, fromAction);
227 _DtTermActionBeginningOfBuffer(Widget w, XEvent *event,
228 String *params, Cardinal *num_params)
230 _DtTermFuncBeginningOfBuffer(w,0,1) ;
231 (void) _DtTermPrimCursorOn(w);
236 _DtTermActionEndOfBuffer(Widget w, XEvent *event,
237 String *params, Cardinal *num_params)
239 _DtTermFuncEndOfBuffer(w,0,1) ;
240 (void) _DtTermPrimCursorOn(w);
246 /** HARD/SOFT RESET ***********************************************************
248 * # # ## ##### ##### # #### #### ###### #####
249 * # # # # # # # # # # # # # #
250 * ###### # # # # # # # #### # # ##### #
251 * # # ###### ##### # # # # # # # #
252 * # # # # # # # # # # # # # # #
253 * # # # # # # ##### # #### #### # #
256 * ##### ###### #### ###### #####
258 * # # ##### #### ##### #
261 * # # ###### #### ###### #
264 _DtTermActionHardReset(Widget w, XEvent *event,
265 String *params, Cardinal *num_params)
267 (void) _DtTermFuncHardReset(w, 0, fromAction);
271 _DtTermActionSoftReset(Widget w, XEvent *event,
272 String *params, Cardinal *num_params)
274 (void) _DtTermFuncSoftReset(w, 0, fromAction);
278 /*** INSERT CHAR/LINE *********************************************************
280 * # # # #### ###### ##### #####
282 * # # # # #### ##### # # #
283 * # # # # # # ##### #
285 * # # # #### ###### # # #
288 * #### # # ## ##### # # # # # ######
289 * # # # # # # # # # # # ## # #
290 * # ###### # # # # # # # # # # #####
291 * # # # ###### ##### # # # # # # #
292 * # # # # # # # # # # # # ## #
293 * #### # # # # # # # ###### # # # ######
298 _DtTermActionInsertLine(Widget w, XEvent *event,
299 String *params, Cardinal *num_params)
301 _DtTermFuncInsertLine(w,1,1) ;
302 (void) _DtTermPrimCursorOn(w);
307 /*** CURSOR MOTION ************************************************************
309 * #### # # ##### #### #### #####
310 * # # # # # # # # # # #
311 * # # # # # #### # # # #
312 * # # # ##### # # # #####
313 * # # # # # # # # # # # #
314 * #### #### # # #### #### # #
317 * # # #### ##### # #### # #
318 * ## ## # # # # # # ## #
319 * # ## # # # # # # # # # #
320 * # # # # # # # # # # #
321 * # # # # # # # # # ##
322 * # # #### # # #### # #
332 static EnumType cursorDirections[] = {
333 { "forward", (char) cursorForward, },
334 { "backward", (char) cursorBackward, },
335 { "up", (char) cursorUp, },
336 { "down", (char) cursorDown },
340 _DtTermActionMoveCursor(Widget w, XEvent *event,
341 String *params, Cardinal *num_params)
345 if (*num_params < 1) {
349 /* figure out the direction... */
350 i = stringToEnum(params[0], cursorDirections, XtNumber(cursorDirections));
356 switch((CursorDirection) cursorDirections[i].value) {
358 if (((DtTermWidget)w)->vt.td->applicationMode)
359 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_UP_APP);
361 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_UP);
365 if (((DtTermWidget)w)->vt.td->applicationMode)
366 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_DOWN_APP);
368 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_DOWN);
372 if (((DtTermWidget)w)->vt.td->applicationMode)
373 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_RIGHT_APP);
375 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_RIGHT);
379 if (((DtTermWidget)w)->vt.td->applicationMode)
380 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_LEFT_APP);
382 (void) _DtTermWriteEscSeq(w, ESC_CURSOR_LEFT);
390 _DtTermActionTab(Widget w, XEvent *event,
391 String *params, Cardinal *num_params)
393 (void) _DtTermPrimSendInput(w, (unsigned char *) "\t", 1);
398 /*** FUNCTION KEYS ************************************************************
400 * ###### # # # # #### ##### # #### # #
401 * # # # ## # # # # # # # ## #
402 * ##### # # # # # # # # # # # # #
403 * # # # # # # # # # # # # # #
404 * # # # # ## # # # # # # # ##
405 * # #### # # #### # # #### # #
408 * # # ###### # # ####
416 _DtTermActionFunctionKeyExecute(Widget w, XEvent *event, String *params,
417 Cardinal *num_params)
419 Boolean shift = False;
424 /* must have a key number, may have a shift/unshift as well... */
425 if (*num_params < 1) {
429 /* get a key number... */
430 keyNumber = strtol(params[0], &ret, 0);
433 /* if we had anything left in the string, the number is bogus... */
438 if (*num_params >= 2) {
439 if (!strcmp(params[1], "UDK")) {
441 } else if (!strcmp(params[1], "function")) {
448 /* execute the key... */
449 (void) _DtTermFunctionKeyExecute(w, (short) keyNumber, shift);
454 /**************************************************************************
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"
464 static int no_kptypes=sizeof(kpTypes)/sizeof(char *) ;
467 _DtTermActionKeypadKeyExecute(Widget w, XEvent *event, String *params,
468 Cardinal *num_params)
470 DtTermWidget tw = (DtTermWidget)w;
471 Boolean shift = False;
475 DtTermData td = tw->vt.td;
477 if (KEYBOARD_LOCKED(td->tpd->keyboardLocked)) {
478 /* keyboard locked -- ring the bell...
480 (void) _DtTermPrimBell(w);
483 /* must have an edit key type... */
484 if (*num_params < 1) {
489 * IBM JP kbd specific code. IBM JP kbd requires IM functionality
490 * to recoginze NumLock state + (*,/) key
492 * The following code is derived from TermPrim/TermPrim.c's
493 * _DtTermPrimActionKeyInput()
497 XKeyEvent *keyEvent = (XKeyEvent *)event;
500 unsigned char string[BUFSIZ];
503 nbytes = XmImMbLookupString(w, keyEvent, (char *) string,
504 sizeof(string), &keysym, &status);
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 !
515 if ( ( keysym == XK_KP_Add ) || ( keysym == XK_KP_Multiply ) ) {
516 if ( string[0] == '*' )
517 params[0] = "multiply";
518 else if ( string[0] == '+' )
525 while( strcmp(params[0],kpTypes[type]) && type<= no_kptypes ) type++;
527 if (type > no_kptypes) return ;
529 if ( tw->vt.td->applicationKPMode ) {
530 _DtTermWriteEscSeq(w,AppKeypadKey[type]);
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 */
540 /***********************************************************************
542 * Edit Keys (Find, Insert Here, Remove, Select, Prev Screen, Next Screen)
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 },
573 _DtTermActionEditKeyExecute(Widget w, XEvent *event, String *params,
574 Cardinal *num_params)
576 DtTermWidget tw = (DtTermWidget)w;
577 Boolean shift = False;
581 DtTermData td = tw->vt.td;
583 if (*num_params < 1) {
587 /* figure out the direction... */
588 i = stringToEnum(params[0], editTypes, XtNumber(editTypes));
594 switch( editTypes[i].value) {
596 if ( tw->vt.sunFunctionKeys == False) {
597 (void) _DtTermWriteEscSeq(w, ESC_FIND) ;
600 (void) _DtTermWriteEscSeq(w,ESC_FIND_SUN);
604 if ( tw->vt.sunFunctionKeys == False) {
605 (void) _DtTermWriteEscSeq(w, ESC_INSERT_HERE) ;
608 (void) _DtTermWriteEscSeq(w,ESC_INSERT_HERE_SUN);
612 if ( tw->vt.sunFunctionKeys == False) {
613 (void) _DtTermWriteEscSeq(w, ESC_SELECT) ;
616 (void) _DtTermWriteEscSeq(w,ESC_SELECT_SUN);
620 if ( tw->vt.sunFunctionKeys == False) {
621 (void) _DtTermWriteEscSeq(w, ESC_PREV_SCREEN) ;
624 (void) _DtTermWriteEscSeq(w,ESC_PREV_SCREEN_SUN);
628 if ( tw->vt.sunFunctionKeys == False) {
629 (void) _DtTermWriteEscSeq(w, ESC_NEXT_SCREEN) ;
632 (void) _DtTermWriteEscSeq(w,ESC_NEXT_SCREEN_SUN);
637 if ( tw->vt.sunFunctionKeys == False) {
638 (void) _DtTermWriteEscSeq(w, ESC_DELETE) ;
641 (void) _DtTermWriteEscSeq(w,ESC_DELETE_SUN);
646 if (tw->vt.sunFunctionKeys == False) {
647 (void) _DtTermWriteEscSeq(w, ESC_HELP);
649 (void) _DtTermWriteEscSeq(w, ESC_HELP_SUN);
654 if (tw->vt.sunFunctionKeys == False) {
655 (void) _DtTermWriteEscSeq(w, ESC_MENU);
657 (void) _DtTermWriteEscSeq(w, ESC_MENU_SUN);
662 if (tw->vt.sunFunctionKeys == False) {
663 (void) _DtTermWriteEscSeq(w, ESC_DO);
665 (void) _DtTermWriteEscSeq(w, ESC_DO_SUN);