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 #define BS KEY_BACKSPACE
39 #define DEL KEY_DC
40 #define UP KEY_UP
41 #define DWN KEY_DOWN
42 #define LEFT KEY_LEFT
43 #define RGHT KEY_RIGHT
44 #define HOME KEY_HOME
45 #define END KEY_END
46 #define PGDN KEY_NPAGE
47 #define PGUP KEY_PPAGE
48 #define TAB 0x09
49 #define STAB 0x161
50 #define ESC 0x1B
51 #define F1 KEY_F(1)
52 #define F2 KEY_F(2)
53 #define F3 KEY_F(3)
54 #define F4 KEY_F(4)
55 #define F5 KEY_F(5)
56 #define F6 KEY_F(6)
58 static command_definition_t cmds[] =
59 {
60 { { 13, 0, 0 }, CMD_PLAY, "play",
61 "Play/Enter directory" },
62 { { 'P', 0, 0 }, CMD_PAUSE,"pause",
63 "Pause" },
64 { { 's', BS, 0 }, CMD_STOP, "stop",
65 "Stop" },
66 { { '>', 0, 0 }, CMD_TRACK_NEXT, "next",
67 "Next track" },
68 { { '<', 0, 0 }, CMD_TRACK_PREVIOUS, "prev",
69 "Previous track" },
70 { { 'f', 0, 0 }, CMD_SEEK_FORWARD, "seek-forward",
71 "Seek forward" },
72 { { 'b', 0, 0 }, CMD_SEEK_BACKWARD, "seek-backward",
73 "Seek backward" },
75 { { '+', RGHT, 0 }, CMD_VOLUME_UP, "volume-up",
76 "Increase volume" },
77 { { '-', LEFT, 0 }, CMD_VOLUME_DOWN, "volume-down",
78 "Decrease volume" },
80 { { 'w', 0, 0 }, CMD_TOGGLE_FIND_WRAP, "wrap-mode",
81 "Toggle find mode" },
82 { { 'U', 0, 0 }, CMD_TOGGLE_AUTOCENTER, "autocenter-mode",
83 "Toggle auto center mode" },
85 { { ' ', 'a', 0 }, CMD_SELECT, "select",
86 "Select/deselect song in playlist" },
87 { { DEL, 'd', 0 }, CMD_DELETE, "delete",
88 "Delete song from playlist" },
89 { { 'Z', 0, 0 }, CMD_SHUFFLE, "shuffle",
90 "Shuffle playlist" },
91 { { 'c', 0, 0 }, CMD_CLEAR, "clear",
92 "Clear playlist" },
93 { { 'r', 0, 0 }, CMD_REPEAT, "repeat",
94 "Toggle repeat mode" },
95 { { 'z', 0, 0 }, CMD_RANDOM, "random",
96 "Toggle random mode" },
97 { { 'x', 0, 0 }, CMD_CROSSFADE, "crossfade",
98 "Toggle crossfade mode" },
99 { { 'S', 0, 0 }, CMD_SAVE_PLAYLIST, "save",
100 "Save playlist" },
102 { { UP, ',', 0 }, CMD_LIST_PREVIOUS, "up",
103 "Move cursor up" },
104 { { DWN, '.', 0 }, CMD_LIST_NEXT, "down",
105 "Move cursor down" },
106 { { HOME, 0x01, 0 }, CMD_LIST_FIRST, "home",
107 "Home " },
108 { { END, 0x05, 0 }, CMD_LIST_LAST, "end",
109 "End " },
110 { { PGUP, 'A', 0 }, CMD_LIST_PREVIOUS_PAGE, "pgup",
111 "Page up" },
112 { { PGDN, 'B', 0 }, CMD_LIST_NEXT_PAGE, "pgdn",
113 "Page down" },
114 { { '/', 0, 0 }, CMD_LIST_FIND, "find",
115 "Forward find" },
116 { { 'n', 0, 0 }, CMD_LIST_FIND_NEXT, "find-next",
117 "Forward find next" },
118 { { '?', 0, 0 }, CMD_LIST_RFIND, "rfind",
119 "Backward find" },
120 { { 'p', 0, 0 }, CMD_LIST_RFIND_NEXT, "rfind-next",
121 "Backward find previous" },
124 { { TAB, 0, 0 }, CMD_SCREEN_NEXT, "screen-next",
125 "Next screen" },
127 { { STAB, 0, 0 }, CMD_SCREEN_PREVIOUS, "screen-prev",
128 "Previous screen" },
130 { { '1', F1, 'h' }, CMD_SCREEN_HELP, "screen-help",
131 "Help screen" },
132 { { '2', F2, 0 }, CMD_SCREEN_PLAY, "screen-playlist",
133 "Playlist screen" },
134 { { '3', F3, 0 }, CMD_SCREEN_FILE, "screen-browse",
135 "Browse screen" },
136 { {'u', 0, 0 }, CMD_SCREEN_UPDATE, "update",
137 "Update screen" },
138 #ifdef ENABLE_KEYDEF_SCREEN
139 { {'K', 0, 0 }, CMD_SCREEN_KEYDEF, "screen-keyedit",
140 "Key configuration screen" },
141 #endif
143 { { 'q', 0, 0 }, CMD_QUIT, "quit",
144 "Quit " PACKAGE },
146 { { -1, -1, -1 }, CMD_NONE, NULL, NULL }
147 };
149 command_definition_t *
150 get_command_definitions(void)
151 {
152 return cmds;
153 }
155 char *
156 key2str(int key)
157 {
158 static char buf[4];
159 int i;
161 buf[0] = 0;
162 switch(key)
163 {
164 case 0:
165 return "Undefined";
166 case ' ':
167 return "Space";
168 case 13:
169 return "Enter";
170 case BS:
171 return "Backspace";
172 case DEL:
173 return "Delete";
174 case UP:
175 return "Up";
176 case DWN:
177 return "Down";
178 case LEFT:
179 return "Left";
180 case RGHT:
181 return "Right";
182 case HOME:
183 return "Home";
184 case END:
185 return "End";
186 case PGDN:
187 return "PageDown";
188 case PGUP:
189 return "PageUp";
190 case TAB:
191 return "Tab";
192 case STAB:
193 return "Shift+Tab";
194 case ESC:
195 return "Esc";
196 case KEY_IC:
197 return "Insert";
198 default:
199 for(i=0; i<=63; i++)
200 if( key==KEY_F(i) )
201 {
202 snprintf(buf, 4, "F%d", i );
203 return buf;
204 }
205 snprintf(buf, 4, "%c", key);
206 }
207 return buf;
208 }
210 void
211 command_dump_keys(void)
212 {
213 int i;
215 i=0;
216 while( cmds[i].description )
217 {
218 if( cmds[i].command != CMD_NONE )
219 printf(" %20s : %s\n", get_key_names(cmds[i].command,1),cmds[i].name);
220 i++;
221 }
222 }
224 char *
225 get_key_names(command_t command, int all)
226 {
227 int i;
229 i=0;
230 while( cmds[i].description )
231 {
232 if( cmds[i].command == command )
233 {
234 int j;
235 static char keystr[80];
237 strncpy(keystr, key2str(cmds[i].keys[0]), 80);
238 if( !all )
239 return keystr;
240 j=1;
241 while( j<MAX_COMMAND_KEYS && cmds[i].keys[j]>0 )
242 {
243 strcat(keystr, " ");
244 strcat(keystr, key2str(cmds[i].keys[j]));
245 j++;
246 }
247 return keystr;
248 }
249 i++;
250 }
251 return NULL;
252 }
254 char *
255 get_key_description(command_t command)
256 {
257 int i;
259 i=0;
260 while( cmds[i].description )
261 {
262 if( cmds[i].command == command )
263 return cmds[i].description;
264 i++;
265 }
266 return NULL;
267 }
269 char *
270 get_key_command_name(command_t command)
271 {
272 int i;
274 i=0;
275 while( cmds[i].name )
276 {
277 if( cmds[i].command == command )
278 return cmds[i].name;
279 i++;
280 }
281 return NULL;
282 }
284 command_t
285 get_key_command_from_name(char *name)
286 {
287 int i;
289 i=0;
290 while( cmds[i].name )
291 {
292 if( strcmp(name, cmds[i].name) == 0 )
293 return cmds[i].command;
294 i++;
295 }
296 return CMD_NONE;
297 }
300 command_t
301 find_key_command(int key, command_definition_t *cmds)
302 {
303 int i;
305 i=0;
306 while( cmds && cmds[i].name )
307 {
308 if( cmds[i].keys[0] == key ||
309 cmds[i].keys[1] == key ||
310 cmds[i].keys[2] == key )
311 return cmds[i].command;
312 i++;
313 }
314 return CMD_NONE;
315 }
317 command_t
318 get_key_command(int key)
319 {
320 return find_key_command(key, cmds);
321 }
324 command_t
325 get_keyboard_command(void)
326 {
327 int key;
329 key = wgetch(stdscr);
331 if( key==KEY_RESIZE )
332 screen_resize();
334 if( key==ERR )
335 return CMD_NONE;
337 DK(fprintf(stderr, "key = 0x%02X\t", key));
339 return get_key_command(key);
340 }
342 int
343 assign_keys(command_t command, int keys[MAX_COMMAND_KEYS])
344 {
345 int i;
347 i=0;
348 while( cmds[i].name )
349 {
350 if( cmds[i].command == command )
351 {
352 memcpy(cmds[i].keys, keys, sizeof(int)*MAX_COMMAND_KEYS);
353 return 0;
354 }
355 i++;
356 }
357 return -1;
358 }
360 int
361 check_key_bindings(void)
362 {
363 int i;
364 int retval = 0;
366 i=0;
367 while( cmds[i].name )
368 {
369 int j;
370 command_t cmd;
372 for(j=0; j<MAX_COMMAND_KEYS; j++)
373 if( cmds[i].keys[j] &&
374 (cmd=get_key_command(cmds[i].keys[j])) != cmds[i].command )
375 {
376 fprintf(stderr, "Error: Key %s assigned to %s and %s !!!\n",
377 key2str(cmds[i].keys[j]),
378 get_key_command_name(cmds[i].command),
379 get_key_command_name(cmd));
380 retval = -1;
381 }
382 i++;
383 }
384 return retval;
385 }
387 int
388 write_key_bindings(FILE *f)
389 {
390 int i,j;
392 i=0;
393 while( cmds[i].name && !ferror(f) )
394 {
395 fprintf(f, "# %s\n", cmds[i].description);
396 fprintf(f, "key %s = ", cmds[i].name);
397 for(j=0; j<MAX_COMMAND_KEYS; j++)
398 {
399 if( j && cmds[i].keys[j] )
400 fprintf(f, ", ");
401 if( !j || cmds[i].keys[j] )
402 {
403 if( cmds[i].keys[j]<256 && (isalpha(cmds[i].keys[j]) ||
404 isdigit(cmds[i].keys[j])) )
405 fprintf(f, "\'%c\'", cmds[i].keys[j]);
406 else
407 fprintf(f, "%d", cmds[i].keys[j]);
408 }
409 }
410 fprintf(f,"\n\n");
411 i++;
412 }
413 return ferror(f);
414 }