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 librararies 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,NULL,1) ;
231 (void) _DtTermPrimCursorOn(w);
236 _DtTermActionEndOfBuffer(Widget w, XEvent *event,
237 String *params, Cardinal *num_params)
239 _DtTermFuncEndOfBuffer(w,NULL,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,
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);