068a21a9d814718d1f0c785b99ef6039d8fb7661
[reactos.git] / rosapps / mc / edit / edit_key_translator.c
1 /*
2 these #defines are probably the ones most people will be interested in.
3 You can use these two #defines to hard code the key mappings --- just
4 uncomment the one you want. But only if you have trouble with learn
5 keys (which is unlikely).
6 */
7
8 /* KEY_BACKSPACE is the key learned in the learn keys menu : */
9 #define OUR_BACKSPACE_KEY KEY_BACKSPACE
10 /* ...otherwise ctrl-h : */
11 /* #define OUR_BACKSPACE_KEY XCTRL ('h') */
12 /* ...otherwise 127 or DEL in ascii : */
13 /* #define OUR_BACKSPACE_KEY 0177 */
14
15 /* KEY_DC is the key learned in the learn keys menu */
16 #define OUR_DELETE_KEY KEY_DC
17 /* ...otherwise ctrl-d : */
18 /* #define OUR_DELETE_KEY XCTRL ('d') */
19 /* ...otherwise 127 or DEL in ascii : */
20 /* #define OUR_DELETE_KEY 0177 */
21
22
23 /*
24 This is #include'd into the function edit_translate_key in edit.c.
25 This sequence of code takes 'x_state' and 'x_key' and translates them
26 into either 'command' or 'char_for_insertion'. 'x_key' holds one of
27 KEY_NPAGE, KEY_HOME etc., and 'x_state' holds a bitwise inclusive OR of
28 CONTROL_PRESSED, ALT_PRESSED or SHIFT_PRESSED, although none may
29 be supported.
30 'command' is one of the editor commands editcmddef.h.
31
32 Almost any C code can go into this file. The code below is an example
33 that may by appended or modified by the user.
34 */
35
36 /* look in this file for the list of commands : */
37 #include "editcmddef.h"
38
39 #define KEY_NUMLOCK ???
40
41 /* ordinary translations. (Some of this may be redundant.) Note that keys listed
42 first take priority when a key is assigned to more than one command */
43 static long *key_map;
44 static long cooledit_key_map[] =
45 {OUR_BACKSPACE_KEY, CK_BackSpace, OUR_DELETE_KEY, CK_Delete,
46 XCTRL ('d'), CK_Delete, '\n', CK_Enter,
47 KEY_PPAGE, CK_Page_Up, KEY_NPAGE, CK_Page_Down, KEY_LEFT, CK_Left,
48 KEY_RIGHT, CK_Right, KEY_UP, CK_Up, KEY_DOWN, CK_Down, ALT ('\t'), CK_Return, ALT ('\n'), CK_Return,
49 KEY_HOME, CK_Home, KEY_END, CK_End, '\t', CK_Tab, XCTRL ('u'), CK_Undo, KEY_IC, CK_Toggle_Insert,
50 XCTRL ('o'), CK_Load, KEY_F (3), CK_Mark, KEY_F (5), CK_Copy,
51 KEY_F (6), CK_Move, KEY_F (8), CK_Remove, KEY_F (12), CK_Save_As,
52 KEY_F (2), CK_Save, XCTRL ('n'), CK_New,
53 XCTRL ('l'), CK_Refresh, ESC_CHAR, CK_Exit, KEY_F (10), CK_Exit,
54 KEY_F (19), /*C formatter */ CK_Pipe_Block (0),
55 XCTRL ('p'), /*spell check */ CK_Pipe_Block (1),
56 KEY_F (15), CK_Insert_File,
57 XCTRL ('f'), CK_Save_Block, KEY_F (1), CK_Help,
58 ALT ('t'), CK_Sort, ALT ('m'), CK_Mail,
59 XCTRL ('z'), CK_Word_Left, XCTRL ('x'), CK_Word_Right,
60 KEY_F (4), CK_Replace, KEY_F (7), CK_Find, KEY_F (14), CK_Replace_Again,
61 XCTRL ('h'), CK_BackSpace, ALT ('l'), CK_Goto, ALT ('L'), CK_Goto, XCTRL ('y'), CK_Delete_Line,
62 KEY_F (17), CK_Find_Again, ALT ('p'), CK_Paragraph_Format, 0};
63
64 static long emacs_key_map[] =
65 {OUR_BACKSPACE_KEY, CK_BackSpace, OUR_DELETE_KEY, CK_Delete, '\n', CK_Enter,
66 KEY_PPAGE, CK_Page_Up, KEY_NPAGE, CK_Page_Down, KEY_LEFT, CK_Left,
67 KEY_RIGHT, CK_Right, KEY_UP, CK_Up, KEY_DOWN, CK_Down, ALT ('\t'), CK_Return, ALT ('\n'), CK_Return,
68 KEY_HOME, CK_Home, KEY_END, CK_End, '\t', CK_Tab, XCTRL ('u'), CK_Undo, KEY_IC, CK_Toggle_Insert,
69 XCTRL ('o'), CK_Load, KEY_F (3), CK_Mark, KEY_F (5), CK_Copy,
70 KEY_F (6), CK_Move, KEY_F (8), CK_Remove, KEY_F (12), CK_Save_As,
71 KEY_F (2), CK_Save, ALT ('p'), CK_Paragraph_Format,
72
73 ALT ('t'), CK_Sort,
74
75 XCTRL ('a'), CK_Home, XCTRL ('e'), CK_End,
76 XCTRL ('b'), CK_Left, XCTRL ('f'), CK_Right,
77 XCTRL ('n'), CK_Down, XCTRL ('p'), CK_Up,
78 XCTRL ('d'), CK_Delete,
79 XCTRL ('v'), CK_Page_Down, ALT ('v'), CK_Page_Up,
80 XCTRL ('@'), CK_Mark,
81 XCTRL ('k'), CK_Delete_To_Line_End,
82 XCTRL ('s'), CK_Find,
83
84 ALT ('b'), CK_Word_Left, ALT ('f'), CK_Word_Right,
85 XCTRL ('w'), CK_XCut,
86 XCTRL ('y'), CK_XPaste,
87 ALT ('w'), CK_XStore,
88
89 XCTRL ('l'), CK_Refresh, ESC_CHAR, CK_Exit, KEY_F (10), CK_Exit,
90 KEY_F (19), /*C formatter */ CK_Pipe_Block (0),
91 ALT ('$'), /*spell check */ CK_Pipe_Block (1),
92 KEY_F (15), CK_Insert_File,
93 KEY_F (1), CK_Help,
94
95 KEY_F (4), CK_Replace, KEY_F (7), CK_Find, KEY_F (14), CK_Replace_Again,
96 XCTRL ('h'), CK_BackSpace, ALT ('l'), CK_Goto, ALT ('L'), CK_Goto,
97 KEY_F (17), CK_Find_Again,
98 ALT ('<'), CK_Beginning_Of_Text,
99 ALT ('>'), CK_End_Of_Text,
100
101 0, 0};
102
103 static long key_pad_map[10] =
104 {XCTRL ('o'), KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT,
105 KEY_DOWN, KEY_RIGHT, KEY_HOME, KEY_UP, KEY_PPAGE};
106
107
108 #define DEFAULT_NUM_LOCK 0
109
110 static int num_lock = DEFAULT_NUM_LOCK;
111 int i = 0;
112
113 switch (edit_key_emulation) {
114 case EDIT_KEY_EMULATION_NORMAL:
115 key_map = cooledit_key_map;
116 break;
117 case EDIT_KEY_EMULATION_EMACS:
118 key_map = emacs_key_map;
119 if (x_key == XCTRL ('x')) {
120 int ext_key;
121 ext_key = edit_raw_key_query (" Ctrl-X ", _(" Emacs key: "), 0);
122 switch (ext_key) {
123 case 's':
124 command = CK_Save;
125 goto fin;
126 case 'x':
127 command = CK_Exit;
128 goto fin;
129 case 'k':
130 command = CK_New;
131 goto fin;
132 case 'e':
133 command = CK_Macro (edit_raw_key_query (_(" Execute Macro "), _(" Press macro hotkey: "), 1));
134 if (command == CK_Macro (0))
135 command = -1;
136 goto fin;
137 }
138 goto fin;
139 }
140 break;
141 }
142
143 if (x_key == XCTRL ('q')) {
144 char_for_insertion = edit_raw_key_query (_(" Insert Literal "), _(" Press any key: "), 0);
145 goto fin;
146 }
147 if (x_key == XCTRL ('a') && edit_key_emulation != EDIT_KEY_EMULATION_EMACS) {
148 command = CK_Macro (edit_raw_key_query (" Execute Macro ", " Press macro hotkey: ", 1));
149 if (command == CK_Macro (0))
150 command = -1;
151 goto fin;
152 }
153 /* edit is a pointer to the widget */
154 if (edit)
155 if (x_key == XCTRL ('r')) {
156 command = edit->macro_i < 0 ? CK_Begin_Record_Macro : CK_End_Record_Macro;
157 goto fin;
158 }
159 /* if (x_key == KEY_NUMLOCK) {
160 num_lock = 1 - num_lock;
161 return 1;
162 }
163 */
164
165 /* first translate the key-pad */
166 if (num_lock) {
167 if (x_key >= '0' && x_key <= '9') {
168 x_key = key_pad_map[x_key - '0'];
169 }
170 if (x_key == '.') {
171 x_key = KEY_DC;
172 }
173 }
174 if ((x_state & SHIFT_PRESSED) && (x_state & CONTROL_PRESSED)) {
175 switch (x_key) {
176 case KEY_PPAGE:
177 command = CK_Beginning_Of_Text_Highlight;
178 goto fin;
179 case KEY_NPAGE:
180 command = CK_End_Of_Text_Highlight;
181 goto fin;
182 case KEY_LEFT:
183 command = CK_Word_Left_Highlight;
184 goto fin;
185 case KEY_RIGHT:
186 command = CK_Word_Right_Highlight;
187 goto fin;
188 }
189 }
190 if ((x_state & SHIFT_PRESSED) && !(x_state & CONTROL_PRESSED)) {
191 switch (x_key) {
192 case KEY_PPAGE:
193 command = CK_Page_Up_Highlight;
194 goto fin;
195 case KEY_NPAGE:
196 command = CK_Page_Down_Highlight;
197 goto fin;
198 case KEY_LEFT:
199 command = CK_Left_Highlight;
200 goto fin;
201 case KEY_RIGHT:
202 command = CK_Right_Highlight;
203 goto fin;
204 case KEY_UP:
205 command = CK_Up_Highlight;
206 goto fin;
207 case KEY_DOWN:
208 command = CK_Down_Highlight;
209 goto fin;
210 case KEY_HOME:
211 command = CK_Home_Highlight;
212 goto fin;
213 case KEY_END:
214 command = CK_End_Highlight;
215 goto fin;
216 case KEY_IC:
217 command = CK_XPaste;
218 goto fin;
219 case KEY_DC:
220 command = CK_XCut;
221 goto fin;
222 }
223 }
224 /* things that need a control key */
225 if (x_state & CONTROL_PRESSED) {
226 switch (x_key) {
227 case KEY_F (2):
228 command = CK_Save_As;
229 goto fin;
230 case KEY_F (4):
231 command = CK_Replace_Again;
232 goto fin;
233 case KEY_F (7):
234 command = CK_Find_Again;
235 goto fin;
236 case KEY_BACKSPACE:
237 command = CK_Undo;
238 goto fin;
239 case KEY_PPAGE:
240 command = CK_Beginning_Of_Text;
241 goto fin;
242 case KEY_NPAGE:
243 command = CK_End_Of_Text;
244 goto fin;
245 case KEY_UP:
246 command = CK_Scroll_Up;
247 goto fin;
248 case KEY_DOWN:
249 command = CK_Scroll_Down;
250 goto fin;
251 case KEY_LEFT:
252 command = CK_Word_Left;
253 goto fin;
254 case KEY_RIGHT:
255 command = CK_Word_Right;
256 goto fin;
257 case KEY_IC:
258 command = CK_XStore;
259 goto fin;
260 case KEY_DC:
261 command = CK_Remove;
262 goto fin;
263 }
264 }
265 /* an ordinary insertable character */
266 if (x_key < 256 && is_printable (x_key)) {
267 char_for_insertion = x_key;
268 goto fin;
269 }
270 /* other commands */
271 i = 0;
272 while (key_map[i] != x_key && (key_map[i] || key_map[i + 1]))
273 i += 2;
274 command = key_map[i + 1];
275 if (command)
276 goto fin;
277
278 /* Function still not found for this key, so try macro's */
279 /* This allows the same macro to be
280 enabled by either eg "ALT('f')" or "XCTRL('f')" or "XCTRL('a'), 'f'" */
281
282 /* key.h: #define ALT(x) (0x200 | (x)) */
283 if (x_key & ALT (0)) { /* is an alt key ? */
284 command = CK_Macro (x_key - ALT (0));
285 goto fin;
286 }
287 /* key.h: #define XCTRL(x) ((x) & 31) */
288 if (x_key < ' ') { /* is a ctrl key ? */
289 command = CK_Macro (x_key);
290 goto fin;
291 }
292 fin:
293
294