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