1e9edcd0d5096e65088968c10beed11b105a6081
1 /*
2 * (c) 2004 by Kalle Wallin (kaw@linux.se)
3 *
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 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
19 #include <ctype.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <ctype.h>
24 #include <glib.h>
25 #include <ncurses.h>
27 #include "config.h"
28 #include "command.h"
30 #undef DEBUG_KEYS
32 #ifdef DEBUG_KEYS
33 #define DK(x) x
34 #else
35 #define DK(x)
36 #endif
38 extern void screen_resize(void);
40 #define BS KEY_BACKSPACE
41 #define DEL KEY_DC
42 #define UP KEY_UP
43 #define DWN KEY_DOWN
44 #define LEFT KEY_LEFT
45 #define RGHT KEY_RIGHT
46 #define HOME KEY_HOME
47 #define END KEY_END
48 #define PGDN KEY_NPAGE
49 #define PGUP KEY_PPAGE
50 #define TAB 0x09
51 #define STAB 0x161
52 #define ESC 0x1B
53 #define F1 KEY_F(1)
54 #define F2 KEY_F(2)
55 #define F3 KEY_F(3)
56 #define F4 KEY_F(4)
57 #define F5 KEY_F(5)
58 #define F6 KEY_F(6)
61 static command_definition_t cmds[] =
62 {
63 { { 13, 0, 0 }, CMD_PLAY, "play",
64 "Play/Enter directory" },
65 { { 'P', 0, 0 }, CMD_PAUSE,"pause",
66 "Pause" },
67 { { 's', BS, 0 }, CMD_STOP, "stop",
68 "Stop" },
69 { { '>', 0, 0 }, CMD_TRACK_NEXT, "next",
70 "Next track" },
71 { { '<', 0, 0 }, CMD_TRACK_PREVIOUS, "prev",
72 "Previous track" },
73 { { 'f', 0, 0 }, CMD_SEEK_FORWARD, "seek-forward",
74 "Seek forward" },
75 { { 'b', 0, 0 }, CMD_SEEK_BACKWARD, "seek-backward",
76 "Seek backward" },
78 { { '+', RGHT, 0 }, CMD_VOLUME_UP, "volume-up",
79 "Increase volume" },
80 { { '-', LEFT, 0 }, CMD_VOLUME_DOWN, "volume-down",
81 "Decrease volume" },
83 { { 'w', 0, 0 }, CMD_TOGGLE_FIND_WRAP, "wrap-mode",
84 "Toggle find mode" },
85 { { 'U', 0, 0 }, CMD_TOGGLE_AUTOCENTER, "autocenter-mode",
86 "Toggle auto center mode" },
88 { { ' ', 'a', 0 }, CMD_SELECT, "select",
89 "Select/deselect song in playlist" },
90 { { DEL, 'd', 0 }, CMD_DELETE, "delete",
91 "Delete song from playlist" },
92 { { 'Z', 0, 0 }, CMD_SHUFFLE, "shuffle",
93 "Shuffle playlist" },
94 { { 'c', 0, 0 }, CMD_CLEAR, "clear",
95 "Clear playlist" },
96 { { 'r', 0, 0 }, CMD_REPEAT, "repeat",
97 "Toggle repeat mode" },
98 { { 'z', 0, 0 }, CMD_RANDOM, "random",
99 "Toggle random mode" },
100 { { 'x', 0, 0 }, CMD_CROSSFADE, "crossfade",
101 "Toggle crossfade mode" },
102 { { 'S', 0, 0 }, CMD_SAVE_PLAYLIST, "save",
103 "Save playlist" },
105 { { 0, 0, 0 }, CMD_LIST_MOVE_UP, "move-up",
106 "Move item up" },
107 { { 0, 0, 0 }, CMD_LIST_MOVE_DOWN, "move-down",
108 "Move item down" },
110 { { UP, ',', 0 }, CMD_LIST_PREVIOUS, "up",
111 "Move cursor up" },
112 { { DWN, '.', 0 }, CMD_LIST_NEXT, "down",
113 "Move cursor down" },
114 { { HOME, 0x01, 0 }, CMD_LIST_FIRST, "home",
115 "Home " },
116 { { END, 0x05, 0 }, CMD_LIST_LAST, "end",
117 "End " },
118 { { PGUP, 'A', 0 }, CMD_LIST_PREVIOUS_PAGE, "pgup",
119 "Page up" },
120 { { PGDN, 'B', 0 }, CMD_LIST_NEXT_PAGE, "pgdn",
121 "Page down" },
122 { { '/', 0, 0 }, CMD_LIST_FIND, "find",
123 "Forward find" },
124 { { 'n', 0, 0 }, CMD_LIST_FIND_NEXT, "find-next",
125 "Forward find next" },
126 { { '?', 0, 0 }, CMD_LIST_RFIND, "rfind",
127 "Backward find" },
128 { { 'p', 0, 0 }, CMD_LIST_RFIND_NEXT, "rfind-next",
129 "Backward find previous" },
132 { { TAB, 0, 0 }, CMD_SCREEN_NEXT, "screen-next",
133 "Next screen" },
135 { { STAB, 0, 0 }, CMD_SCREEN_PREVIOUS, "screen-prev",
136 "Previous screen" },
138 { { '1', F1, 'h' }, CMD_SCREEN_HELP, "screen-help",
139 "Help screen" },
140 { { '2', F2, 0 }, CMD_SCREEN_PLAY, "screen-playlist",
141 "Playlist screen" },
142 { { '3', F3, 0 }, CMD_SCREEN_FILE, "screen-browse",
143 "Browse screen" },
144 { {'u', 0, 0 }, CMD_SCREEN_UPDATE, "update",
145 "Update screen" },
146 #ifdef ENABLE_KEYDEF_SCREEN
147 { {'K', 0, 0 }, CMD_SCREEN_KEYDEF, "screen-keyedit",
148 "Key configuration screen" },
149 #endif
151 { { 'q', 0, 0 }, CMD_QUIT, "quit",
152 "Quit " PACKAGE },
154 { { -1, -1, -1 }, CMD_NONE, NULL, NULL }
155 };
157 command_definition_t *
158 get_command_definitions(void)
159 {
160 return cmds;
161 }
163 char *
164 key2str(int key)
165 {
166 static char buf[32];
167 int i;
169 buf[0] = 0;
170 switch(key)
171 {
172 case 0:
173 return "Undefined";
174 case ' ':
175 return "Space";
176 case 13:
177 return "Enter";
178 case BS:
179 return "Backspace";
180 case DEL:
181 return "Delete";
182 case UP:
183 return "Up";
184 case DWN:
185 return "Down";
186 case LEFT:
187 return "Left";
188 case RGHT:
189 return "Right";
190 case HOME:
191 return "Home";
192 case END:
193 return "End";
194 case PGDN:
195 return "PageDown";
196 case PGUP:
197 return "PageUp";
198 case TAB:
199 return "Tab";
200 case STAB:
201 return "Shift+Tab";
202 case ESC:
203 return "Esc";
204 case KEY_IC:
205 return "Insert";
206 default:
207 for(i=0; i<=63; i++)
208 if( key==KEY_F(i) )
209 {
210 snprintf(buf, 32, "F%d", i );
211 return buf;
212 }
213 if( !(key & ~037) )
214 snprintf(buf, 32, "Ctrl-%c", 'A'+(key & 037)-1 );
215 else if( (key & ~037) == 224 )
216 snprintf(buf, 32, "Alt-%c", 'A'+(key & 037)-1 );
217 else if( key>32 && key<256 )
218 snprintf(buf, 32, "%c", key);
219 else
220 snprintf(buf, 32, "0x%03X", key);
221 }
222 return buf;
223 }
225 void
226 command_dump_keys(void)
227 {
228 int i;
230 i=0;
231 while( cmds[i].description )
232 {
233 if( cmds[i].command != CMD_NONE )
234 printf(" %20s : %s\n", get_key_names(cmds[i].command,1),cmds[i].name);
235 i++;
236 }
237 }
239 char *
240 get_key_names(command_t command, int all)
241 {
242 int i;
244 i=0;
245 while( cmds[i].description )
246 {
247 if( cmds[i].command == command )
248 {
249 int j;
250 static char keystr[80];
252 strncpy(keystr, key2str(cmds[i].keys[0]), 80);
253 if( !all )
254 return keystr;
255 j=1;
256 while( j<MAX_COMMAND_KEYS && cmds[i].keys[j]>0 )
257 {
258 strcat(keystr, " ");
259 strcat(keystr, key2str(cmds[i].keys[j]));
260 j++;
261 }
262 return keystr;
263 }
264 i++;
265 }
266 return NULL;
267 }
269 char *
270 get_key_description(command_t command)
271 {
272 int i;
274 i=0;
275 while( cmds[i].description )
276 {
277 if( cmds[i].command == command )
278 return cmds[i].description;
279 i++;
280 }
281 return NULL;
282 }
284 char *
285 get_key_command_name(command_t command)
286 {
287 int i;
289 i=0;
290 while( cmds[i].name )
291 {
292 if( cmds[i].command == command )
293 return cmds[i].name;
294 i++;
295 }
296 return NULL;
297 }
299 command_t
300 get_key_command_from_name(char *name)
301 {
302 int i;
304 i=0;
305 while( cmds[i].name )
306 {
307 if( strcmp(name, cmds[i].name) == 0 )
308 return cmds[i].command;
309 i++;
310 }
311 return CMD_NONE;
312 }
315 command_t
316 find_key_command(int key, command_definition_t *cmds)
317 {
318 int i;
320 i=0;
321 while( cmds && cmds[i].name )
322 {
323 if( cmds[i].keys[0] == key ||
324 cmds[i].keys[1] == key ||
325 cmds[i].keys[2] == key )
326 return cmds[i].command;
327 i++;
328 }
329 return CMD_NONE;
330 }
332 command_t
333 get_key_command(int key)
334 {
335 return find_key_command(key, cmds);
336 }
339 command_t
340 get_keyboard_command(void)
341 {
342 int key;
344 key = wgetch(stdscr);
346 if( key==KEY_RESIZE )
347 screen_resize();
349 if( key==ERR )
350 return CMD_NONE;
352 DK(fprintf(stderr, "key = 0x%02X\t", key));
354 return get_key_command(key);
355 }
357 int
358 assign_keys(command_t command, int keys[MAX_COMMAND_KEYS])
359 {
360 int i;
362 i=0;
363 while( cmds[i].name )
364 {
365 if( cmds[i].command == command )
366 {
367 memcpy(cmds[i].keys, keys, sizeof(int)*MAX_COMMAND_KEYS);
368 return 0;
369 }
370 i++;
371 }
372 return -1;
373 }
375 int
376 check_key_bindings(void)
377 {
378 int i;
379 int retval = 0;
381 i=0;
382 while( cmds[i].name )
383 {
384 int j;
385 command_t cmd;
387 for(j=0; j<MAX_COMMAND_KEYS; j++)
388 if( cmds[i].keys[j] &&
389 (cmd=get_key_command(cmds[i].keys[j])) != cmds[i].command )
390 {
391 fprintf(stderr, "Error: Key %s assigned to %s and %s !!!\n",
392 key2str(cmds[i].keys[j]),
393 get_key_command_name(cmds[i].command),
394 get_key_command_name(cmd));
395 retval = -1;
396 }
397 i++;
398 }
399 return retval;
400 }
402 int
403 write_key_bindings(FILE *f)
404 {
405 int i,j;
407 i=0;
408 while( cmds[i].name && !ferror(f) )
409 {
410 fprintf(f, "# %s\n", cmds[i].description);
411 fprintf(f, "key %s = ", cmds[i].name);
412 for(j=0; j<MAX_COMMAND_KEYS; j++)
413 {
414 if( j && cmds[i].keys[j] )
415 fprintf(f, ", ");
416 if( !j || cmds[i].keys[j] )
417 {
418 if( cmds[i].keys[j]<256 && (isalpha(cmds[i].keys[j]) ||
419 isdigit(cmds[i].keys[j])) )
420 fprintf(f, "\'%c\'", cmds[i].keys[j]);
421 else
422 fprintf(f, "%d", cmds[i].keys[j]);
423 }
424 }
425 fprintf(f,"\n\n");
426 i++;
427 }
428 return ferror(f);
429 }