gtkeditkey.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /* gtkeditkey.c - key defs for gtk
  2. Copyright (C) 1996, 1997 the Free Software Foundation
  3. Authors: 1996, 1997 Paul Sheer
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  15. #include <config.h>
  16. #include "edit.h"
  17. #include "editcmddef.h"
  18. #include <gdk/gdkkeysyms.h>
  19. int mod_type_key (guint x);
  20. int (*user_defined_key_function) (unsigned int state, unsigned int keycode, KeySym keysym) = 0;
  21. int option_interpret_numlock = 0;
  22. void edit_set_user_key_function (int (*user_def_key_func) (unsigned int, unsigned int, KeySym))
  23. {
  24. user_defined_key_function = user_def_key_func;
  25. }
  26. int edit_translate_key (unsigned int x_keycode, long x_key, int x_state, int *cmd, int *ch)
  27. {
  28. int command = -1;
  29. int char_for_insertion = -1;
  30. static long key_map[128] =
  31. {GDK_BackSpace, CK_BackSpace, GDK_Delete, CK_Delete, GDK_Return, CK_Enter, GDK_Page_Up, CK_Page_Up,
  32. GDK_Page_Down, CK_Page_Down, GDK_Left, CK_Left, GDK_Right, CK_Right, GDK_Up, CK_Up, GDK_Down, CK_Down,
  33. GDK_Home, CK_Home, GDK_End, CK_End, GDK_Tab, CK_Tab, GDK_Undo, CK_Undo, GDK_Insert, CK_Toggle_Insert,
  34. GDK_F3, CK_Mark, GDK_F5, CK_Copy, GDK_F6, CK_Move, GDK_F8, CK_Remove, GDK_F2, CK_Save, GDK_F12, CK_Save_As,
  35. GDK_F10, CK_Exit, GDK_Escape, CK_Cancel, GDK_F9, CK_Menu,
  36. GDK_F4, CK_Replace, GDK_F4, CK_Replace_Again, GDK_F17, CK_Find_Again, GDK_F7, CK_Find, GDK_F15, CK_Insert_File, 0, 0};
  37. static long key_pad_map[10] =
  38. {GDK_Insert, GDK_End, GDK_Down, GDK_Page_Down, GDK_Left,
  39. GDK_Down, GDK_Right, GDK_Home, GDK_Up, GDK_Page_Up};
  40. #define DEFAULT_NUM_LOCK 1
  41. static int num_lock = DEFAULT_NUM_LOCK;
  42. static int raw = 0;
  43. static int compose = 0;
  44. static int decimal = 0;
  45. static int hex = 0;
  46. int i = 0;
  47. int h;
  48. if (compose) {
  49. if (mod_type_key (x_key)) {
  50. goto fin;
  51. } else {
  52. int c;
  53. compose = 0;
  54. c = get_international_character (x_key);
  55. if (c == 1) {
  56. /* *** */
  57. #if 0
  58. get_international_character (0);
  59. #endif
  60. goto fin;
  61. } else if (c) {
  62. char_for_insertion = c;
  63. goto fin;
  64. }
  65. goto fin;
  66. }
  67. }
  68. if (option_international_characters) {
  69. if (x_key >= ' ' && x_key <= '~') {
  70. /* *** */
  71. #if 0
  72. extern int compose_key_pressed;
  73. #endif
  74. if (compose_key_pressed) {
  75. int c;
  76. c = (x_key >= 'A' && x_key <= 'Z') ? x_key - 'A' + 'a' : x_key;
  77. c = get_international_character ((x_state & ShiftMask) ?
  78. ((c >= 'a' && c <= 'z') ? c + 'A' - 'a' : c)
  79. : c);
  80. if (c == 1) {
  81. compose = 1;
  82. goto fin;
  83. }
  84. compose = 0;
  85. if (c)
  86. char_for_insertion = c;
  87. else
  88. goto fin;
  89. }
  90. }
  91. }
  92. if (x_key <= 0 || mod_type_key (x_key))
  93. goto fin;
  94. if (raw) {
  95. if (!x_state) {
  96. if (strchr ("0123456789abcdefh", x_key)) {
  97. char u[2] =
  98. {0, 0};
  99. if (raw == 3) {
  100. if (x_key == 'h') {
  101. char_for_insertion = hex;
  102. raw = 0;
  103. goto fin;
  104. } else {
  105. if (x_key > '9') {
  106. raw = 0;
  107. goto fin;
  108. }
  109. }
  110. }
  111. decimal += (x_key - '0') * ((int) ("d\n\001")[raw - 1]);
  112. u[0] = x_key;
  113. hex += (strcspn ("0123456789abcdef", u) << (4 * (2 - raw)));
  114. if (raw == 3) {
  115. char_for_insertion = decimal;
  116. raw = 0;
  117. goto fin;
  118. }
  119. raw++;
  120. goto fin;
  121. }
  122. }
  123. if (raw > 1) {
  124. raw = 0;
  125. goto fin;
  126. }
  127. raw = 0;
  128. if (x_key == GDK_Return)
  129. char_for_insertion = '\n';
  130. else
  131. char_for_insertion = x_key;
  132. if (x_state & ControlMask)
  133. char_for_insertion &= 31;
  134. if (x_state & (MyAltMask))
  135. char_for_insertion |= 128;
  136. goto fin;
  137. }
  138. if (user_defined_key_function)
  139. if ((h = (*(user_defined_key_function)) (x_state, x_keycode, x_key))) {
  140. command = h;
  141. goto fin;
  142. }
  143. if ((x_state & MyAltMask)) {
  144. switch ((int) x_key) {
  145. case GDK_Left:
  146. case GDK_KP_Left:
  147. command = CK_Delete_Word_Left;
  148. goto fin;
  149. case GDK_Right:
  150. case GDK_KP_Right:
  151. command = CK_Delete_Word_Right;
  152. goto fin;
  153. case GDK_l:
  154. case GDK_L:
  155. command = CK_Goto;
  156. goto fin;
  157. case GDK_Insert:
  158. case GDK_KP_Insert:
  159. command = CK_Selection_History;
  160. goto fin;
  161. case GDK_Up:
  162. case GDK_KP_Up:
  163. command = CK_Scroll_Up;
  164. goto fin;
  165. case GDK_Down:
  166. case GDK_KP_Down:
  167. command = CK_Scroll_Down;
  168. goto fin;
  169. case GDK_Delete:
  170. case GDK_KP_Delete:
  171. command = CK_Delete_To_Line_End;
  172. goto fin;
  173. case GDK_BackSpace:
  174. command = CK_Delete_To_Line_Begin;
  175. goto fin;
  176. case GDK_m:
  177. case GDK_M:
  178. command = CK_Mail;
  179. goto fin;
  180. case GDK_x:
  181. case GDK_X:
  182. command = CK_Save_And_Quit;
  183. goto fin;
  184. case GDK_p:
  185. case GDK_P:
  186. command = CK_Paragraph_Format;
  187. goto fin;
  188. }
  189. }
  190. if ((x_state & MyAltMask) && (x_state & ShiftMask)) {
  191. switch ((int) x_key) {
  192. case GDK_Up:
  193. case GDK_KP_Up:
  194. command = CK_Scroll_Up_Highlight;
  195. goto fin;
  196. case GDK_Down:
  197. case GDK_KP_Down:
  198. command = CK_Scroll_Down_Highlight;
  199. goto fin;
  200. }
  201. }
  202. if (!(x_state & MyAltMask)) {
  203. if ((x_key == GDK_a || x_key == GDK_A) && (x_state & ControlMask)) {
  204. #if 0
  205. command = CK_Macro (CKeySymMod (CRawkeyQuery (0, 0, 0, " Execute Macro ", " Press macro hotkey: ")));
  206. if (command == CK_Macro (0))
  207. #endif
  208. command = -1;
  209. goto fin;
  210. }
  211. if (x_key == GDK_Num_Lock && option_interpret_numlock) {
  212. num_lock = 1 - num_lock;
  213. goto fin;
  214. }
  215. switch ((int) x_key) {
  216. case GDK_KP_Home:
  217. x_key = GDK_Home;
  218. break;
  219. case GDK_KP_End:
  220. x_key = GDK_End;
  221. break;
  222. case GDK_KP_Page_Up:
  223. x_key = GDK_Page_Up;
  224. break;
  225. case GDK_KP_Page_Down:
  226. x_key = GDK_Page_Down;
  227. break;
  228. case GDK_KP_Up:
  229. x_key = GDK_Up;
  230. break;
  231. case GDK_KP_Down:
  232. x_key = GDK_Down;
  233. break;
  234. case GDK_KP_Left:
  235. x_key = GDK_Left;
  236. break;
  237. case GDK_KP_Right:
  238. x_key = GDK_Right;
  239. break;
  240. case GDK_KP_Insert:
  241. x_key = GDK_Insert;
  242. break;
  243. case GDK_KP_Delete:
  244. x_key = GDK_Delete;
  245. break;
  246. case GDK_KP_Enter:
  247. x_key = GDK_Return;
  248. break;
  249. case GDK_KP_Add:
  250. x_key = GDK_plus;
  251. break;
  252. case GDK_KP_Subtract:
  253. x_key = GDK_minus;
  254. break;
  255. }
  256. /* first translate the key-pad */
  257. if (num_lock) {
  258. if (x_key >= GDK_R1 && x_key <= GDK_R9) {
  259. x_key = key_pad_map[x_key - GDK_R1 + 1];
  260. } else if (x_key >= GDK_KP_0 && x_key <= GDK_KP_9) {
  261. x_key = key_pad_map[x_key - GDK_KP_0];
  262. } else if (x_key == GDK_KP_Decimal) {
  263. x_key = GDK_Delete;
  264. }
  265. } else {
  266. if (x_key >= GDK_KP_0 && x_key <= GDK_KP_9) {
  267. x_key += GDK_0 - GDK_KP_0;
  268. }
  269. if (x_key == GDK_KP_Decimal) {
  270. x_key = GDK_period;
  271. }
  272. }
  273. if ((x_state & ShiftMask) && (x_state & ControlMask)) {
  274. switch ((int) x_key) {
  275. case GDK_Page_Up:
  276. command = CK_Beginning_Of_Text_Highlight;
  277. goto fin;
  278. case GDK_Page_Down:
  279. command = CK_End_Of_Text_Highlight;
  280. goto fin;
  281. case GDK_Left:
  282. command = CK_Word_Left_Highlight;
  283. goto fin;
  284. case GDK_Right:
  285. command = CK_Word_Right_Highlight;
  286. goto fin;
  287. case GDK_Up:
  288. command = CK_Paragraph_Up_Highlight;
  289. goto fin;
  290. case GDK_Down:
  291. command = CK_Paragraph_Down_Highlight;
  292. goto fin;
  293. case GDK_Home:
  294. command = CK_Begin_Page_Highlight;
  295. goto fin;
  296. case GDK_End:
  297. command = CK_End_Page_Highlight;
  298. goto fin;
  299. }
  300. }
  301. if ((x_state & ShiftMask) && !(x_state & ControlMask)) {
  302. switch ((int) x_key) {
  303. case GDK_Page_Up:
  304. command = CK_Page_Up_Highlight;
  305. goto fin;
  306. case GDK_Page_Down:
  307. command = CK_Page_Down_Highlight;
  308. goto fin;
  309. case GDK_Left:
  310. command = CK_Left_Highlight;
  311. goto fin;
  312. case GDK_Right:
  313. command = CK_Right_Highlight;
  314. goto fin;
  315. case GDK_Up:
  316. command = CK_Up_Highlight;
  317. goto fin;
  318. case GDK_Down:
  319. command = CK_Down_Highlight;
  320. goto fin;
  321. case GDK_Home:
  322. command = CK_Home_Highlight;
  323. goto fin;
  324. case GDK_End:
  325. command = CK_End_Highlight;
  326. goto fin;
  327. case GDK_Insert:
  328. command = CK_XPaste;
  329. goto fin;
  330. case GDK_Delete:
  331. command = CK_XCut;
  332. goto fin;
  333. case GDK_Return:
  334. command = CK_Return;
  335. goto fin;
  336. /* this parallel F12, F19, F15, and F17 for some systems */
  337. case GDK_F2:
  338. command = CK_Save_As;
  339. goto fin;
  340. case GDK_F5:
  341. command = CK_Insert_File;
  342. goto fin;
  343. case GDK_F7:
  344. command = CK_Find_Again;
  345. goto fin;
  346. case GDK_F4:
  347. command = CK_Replace_Again;
  348. goto fin;
  349. case GDK_F3:
  350. command = CK_Run_Another;
  351. goto fin;
  352. }
  353. }
  354. /* things that need a control key */
  355. if (x_state & ControlMask) {
  356. switch ((int) x_key) {
  357. case GDK_F1:
  358. command = CK_Man_Page;
  359. goto fin;
  360. case GDK_U:
  361. case GDK_u:
  362. case GDK_BackSpace:
  363. command = CK_Undo;
  364. goto fin;
  365. case GDK_Page_Up:
  366. command = CK_Beginning_Of_Text;
  367. goto fin;
  368. case GDK_Page_Down:
  369. command = CK_End_Of_Text;
  370. goto fin;
  371. case GDK_Up:
  372. command = CK_Paragraph_Up;
  373. goto fin;
  374. case GDK_Down:
  375. command = CK_Paragraph_Down;
  376. goto fin;
  377. case GDK_Left:
  378. command = CK_Word_Left;
  379. goto fin;
  380. case GDK_Right:
  381. command = CK_Word_Right;
  382. goto fin;
  383. case GDK_Home:
  384. command = CK_Begin_Page;
  385. goto fin;
  386. case GDK_End:
  387. command = CK_End_Page;
  388. goto fin;
  389. case GDK_N:
  390. case GDK_n:
  391. command = CK_New;
  392. goto fin;
  393. case GDK_O:
  394. case GDK_o:
  395. command = CK_Load;
  396. goto fin;
  397. case GDK_D:
  398. case GDK_d:
  399. command = CK_Date;
  400. goto fin;
  401. case GDK_Q:
  402. case GDK_q:
  403. raw = 1;
  404. decimal = 0;
  405. hex = 0;
  406. goto fin;
  407. case GDK_F:
  408. case GDK_f:
  409. command = CK_Save_Block;
  410. goto fin;
  411. case GDK_F5:
  412. case GDK_F15:
  413. command = CK_Insert_File;
  414. goto fin;
  415. case GDK_Insert:
  416. command = CK_XStore;
  417. goto fin;
  418. case GDK_y:
  419. case GDK_Y:
  420. command = CK_Delete_Line;
  421. goto fin;
  422. case GDK_Delete:
  423. command = CK_Remove;
  424. goto fin;
  425. case GDK_F2:
  426. command = CK_Save_Desktop;
  427. goto fin;
  428. case GDK_F3:
  429. command = CK_New_Window;
  430. goto fin;
  431. case GDK_F6:
  432. command = CK_Cycle;
  433. goto fin;
  434. case GDK_F10:
  435. command = CK_Check_Save_And_Quit;
  436. goto fin;
  437. case GDK_Tab:
  438. case GDK_KP_Tab:
  439. command = CK_Complete;
  440. goto fin;
  441. case GDK_b:
  442. command = CK_Column_Mark;
  443. goto fin;
  444. }
  445. }
  446. /* an ordinary ascii character or international character */
  447. if (!(x_state & MyAltMask)) {
  448. if (!(x_state & ControlMask)) {
  449. if ((x_key >= GDK_space && x_key <= GDK_asciitilde) || ((x_key >= 160 && x_key < 256) && option_international_characters)) {
  450. char_for_insertion = x_key;
  451. goto fin;
  452. }
  453. /* other commands */
  454. if (!(x_state & ShiftMask)) {
  455. i = 0;
  456. while (key_map[i] != x_key && key_map[i])
  457. i += 2;
  458. command = key_map[i + 1];
  459. if (command)
  460. goto fin;
  461. }
  462. }
  463. }
  464. }
  465. fin:
  466. *cmd = command;
  467. *ch = char_for_insertion;
  468. if ((command == -1 || command == 0) && char_for_insertion == -1) /* unchanged, key has no function here */
  469. return 0;
  470. return 1;
  471. }