Code

Added seek, crossfade commands.
[ncmpc.git] / command.c
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)
152   return cmds;
155 char *
156 key2str(int key)
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;
210 void
211 command_dump_keys(void)
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     }
224 char *
225 get_key_names(command_t command, int all)
227   int i;
228   
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;
254 char *
255 get_key_description(command_t command)
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;
269 char *
270 get_key_command_name(command_t command)
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;
284 command_t 
285 get_key_command_from_name(char *name)
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;
300 command_t 
301 find_key_command(int key, command_definition_t *cmds)
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;
317 command_t 
318 get_key_command(int key)
320   return find_key_command(key, cmds);
324 command_t
325 get_keyboard_command(void)
327   int key;
329   key = wgetch(stdscr);
331   if( key==ERR )
332     return CMD_NONE;
334   DK(fprintf(stderr, "key = 0x%02X\t", key));
336   return get_key_command(key);
339 int
340 assign_keys(command_t command, int keys[MAX_COMMAND_KEYS])
342  int i;
344   i=0;
345   while( cmds[i].name )
346     {
347       if( cmds[i].command == command )
348         {
349           memcpy(cmds[i].keys, keys, sizeof(int)*MAX_COMMAND_KEYS);
350           return 0;
351         }
352       i++;
353     }
354   return -1;
357 int 
358 check_key_bindings(void)
360   int i;
361   int retval = 0;
362   
363   i=0;
364   while( cmds[i].name )
365     {
366       int j;
367       command_t cmd;
369       for(j=0; j<MAX_COMMAND_KEYS; j++)
370         if( cmds[i].keys[j] && 
371             (cmd=get_key_command(cmds[i].keys[j])) != cmds[i].command )
372           {
373             fprintf(stderr, "Error: Key %s assigned to %s and %s !!!\n",
374                     key2str(cmds[i].keys[j]),
375                     get_key_command_name(cmds[i].command),
376                     get_key_command_name(cmd));
377             retval = -1;
378           }
379       i++;
380     }
381   return retval;
384 int
385 write_key_bindings(FILE *f)
387   int i,j;
389   i=0;
390   while( cmds[i].name && !ferror(f) )
391     {
392       fprintf(f, "# %s\n", cmds[i].description);
393       fprintf(f, "key %s = ", cmds[i].name);
394       for(j=0; j<MAX_COMMAND_KEYS; j++)
395         {
396           if( j && cmds[i].keys[j] )
397             fprintf(f, ",  ");
398           if( !j || cmds[i].keys[j] )
399             {
400               if( cmds[i].keys[j]<256 && (isalpha(cmds[i].keys[j]) || 
401                                           isdigit(cmds[i].keys[j])) )
402                 fprintf(f, "\'%c\'", cmds[i].keys[j]);
403               else
404                 fprintf(f, "%d", cmds[i].keys[j]);
405             }
406         }
407       fprintf(f,"\n\n");
408       i++;
409     }
410   return ferror(f);