TermAction.c 19 KB

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