X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fcommand.c;h=656bb18e389db0bd89a1389be818a861d2a7a3e1;hb=a023de1cdf0ebcd19b1236c4132175402fc7d4b6;hp=1e9edcd0d5096e65088968c10beed11b105a6081;hpb=f55a67b3f882641abe5a9b14b045d7ce71964af7;p=ncmpc.git diff --git a/src/command.c b/src/command.c index 1e9edcd..656bb18 100644 --- a/src/command.c +++ b/src/command.c @@ -1,5 +1,6 @@ -/* - * (c) 2004 by Kalle Wallin (kaw@linux.se) +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2010 The Music Player Daemon Project + * Project homepage: http://musicpd.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -10,22 +11,26 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "command.h" +#include "config.h" +#include "ncmpc.h" +#include "i18n.h" +#include "mpdclient.h" +#include "screen.h" + #include -#include #include #include #include #include -#include - -#include "config.h" -#include "command.h" +#include +#include #undef DEBUG_KEYS @@ -35,7 +40,7 @@ #define DK(x) #endif -extern void screen_resize(void); +#define KEY_CTL(x) ((x) & 0x1f) /* KEY_CTL(A) == ^A == \1 */ #define BS KEY_BACKSPACE #define DEL KEY_DC @@ -50,380 +55,481 @@ extern void screen_resize(void); #define TAB 0x09 #define STAB 0x161 #define ESC 0x1B +#define RET '\r' #define F1 KEY_F(1) #define F2 KEY_F(2) #define F3 KEY_F(3) #define F4 KEY_F(4) #define F5 KEY_F(5) #define F6 KEY_F(6) +#define F7 KEY_F(7) +#define F8 KEY_F(8) +#define C(x) KEY_CTL(x) - -static command_definition_t cmds[] = -{ - { { 13, 0, 0 }, CMD_PLAY, "play", - "Play/Enter directory" }, - { { 'P', 0, 0 }, CMD_PAUSE,"pause", - "Pause" }, - { { 's', BS, 0 }, CMD_STOP, "stop", - "Stop" }, - { { '>', 0, 0 }, CMD_TRACK_NEXT, "next", - "Next track" }, - { { '<', 0, 0 }, CMD_TRACK_PREVIOUS, "prev", - "Previous track" }, - { { 'f', 0, 0 }, CMD_SEEK_FORWARD, "seek-forward", - "Seek forward" }, - { { 'b', 0, 0 }, CMD_SEEK_BACKWARD, "seek-backward", - "Seek backward" }, - - { { '+', RGHT, 0 }, CMD_VOLUME_UP, "volume-up", - "Increase volume" }, - { { '-', LEFT, 0 }, CMD_VOLUME_DOWN, "volume-down", - "Decrease volume" }, - - { { 'w', 0, 0 }, CMD_TOGGLE_FIND_WRAP, "wrap-mode", - "Toggle find mode" }, - { { 'U', 0, 0 }, CMD_TOGGLE_AUTOCENTER, "autocenter-mode", - "Toggle auto center mode" }, - - { { ' ', 'a', 0 }, CMD_SELECT, "select", - "Select/deselect song in playlist" }, - { { DEL, 'd', 0 }, CMD_DELETE, "delete", - "Delete song from playlist" }, - { { 'Z', 0, 0 }, CMD_SHUFFLE, "shuffle", - "Shuffle playlist" }, - { { 'c', 0, 0 }, CMD_CLEAR, "clear", - "Clear playlist" }, - { { 'r', 0, 0 }, CMD_REPEAT, "repeat", - "Toggle repeat mode" }, - { { 'z', 0, 0 }, CMD_RANDOM, "random", - "Toggle random mode" }, - { { 'x', 0, 0 }, CMD_CROSSFADE, "crossfade", - "Toggle crossfade mode" }, - { { 'S', 0, 0 }, CMD_SAVE_PLAYLIST, "save", - "Save playlist" }, - - { { 0, 0, 0 }, CMD_LIST_MOVE_UP, "move-up", - "Move item up" }, - { { 0, 0, 0 }, CMD_LIST_MOVE_DOWN, "move-down", - "Move item down" }, - - { { UP, ',', 0 }, CMD_LIST_PREVIOUS, "up", - "Move cursor up" }, - { { DWN, '.', 0 }, CMD_LIST_NEXT, "down", - "Move cursor down" }, - { { HOME, 0x01, 0 }, CMD_LIST_FIRST, "home", - "Home " }, - { { END, 0x05, 0 }, CMD_LIST_LAST, "end", - "End " }, - { { PGUP, 'A', 0 }, CMD_LIST_PREVIOUS_PAGE, "pgup", - "Page up" }, - { { PGDN, 'B', 0 }, CMD_LIST_NEXT_PAGE, "pgdn", - "Page down" }, - { { '/', 0, 0 }, CMD_LIST_FIND, "find", - "Forward find" }, - { { 'n', 0, 0 }, CMD_LIST_FIND_NEXT, "find-next", - "Forward find next" }, - { { '?', 0, 0 }, CMD_LIST_RFIND, "rfind", - "Backward find" }, - { { 'p', 0, 0 }, CMD_LIST_RFIND_NEXT, "rfind-next", - "Backward find previous" }, - - - { { TAB, 0, 0 }, CMD_SCREEN_NEXT, "screen-next", - "Next screen" }, - - { { STAB, 0, 0 }, CMD_SCREEN_PREVIOUS, "screen-prev", - "Previous screen" }, - - { { '1', F1, 'h' }, CMD_SCREEN_HELP, "screen-help", - "Help screen" }, - { { '2', F2, 0 }, CMD_SCREEN_PLAY, "screen-playlist", - "Playlist screen" }, - { { '3', F3, 0 }, CMD_SCREEN_FILE, "screen-browse", - "Browse screen" }, - { {'u', 0, 0 }, CMD_SCREEN_UPDATE, "update", - "Update screen" }, +static command_definition_t cmds[] = { #ifdef ENABLE_KEYDEF_SCREEN - { {'K', 0, 0 }, CMD_SCREEN_KEYDEF, "screen-keyedit", - "Key configuration screen" }, + { {'K', 0, 0 }, 0, CMD_SCREEN_KEYDEF, "screen-keyedit", + N_("Key configuration screen") }, +#endif + { { 'q', 'Q', C('C') }, 0, CMD_QUIT, "quit", + N_("Quit") }, + + /* movement */ + { { UP, 'k', 0 }, 0, CMD_LIST_PREVIOUS, "up", + N_("Move cursor up") }, + { { DWN, 'j', 0 }, 0, CMD_LIST_NEXT, "down", + N_("Move cursor down") }, + { { 'H', 0, 0 }, 0, CMD_LIST_TOP, "top", + N_("Move cursor to the top of screen") }, + { { 'M', 0, 0 }, 0, CMD_LIST_MIDDLE, "middle", + N_("Move cursor to the middle of screen") }, + { { 'L', 0, 0 }, 0, CMD_LIST_BOTTOM, "bottom", + N_("Move cursor to the bottom of screen") }, + { { HOME, C('A'), 0 }, 0, CMD_LIST_FIRST, "home", + N_("Move cursor to the top of the list") }, + { { END, C('E'), 0 }, 0, CMD_LIST_LAST, "end", + N_("Move cursor to the bottom of the list") }, + { { PGUP, 0, 0 }, 0, CMD_LIST_PREVIOUS_PAGE, "pgup", + N_("Page up") }, + { { PGDN, 0, 0 }, 0, CMD_LIST_NEXT_PAGE, "pgdn", + N_("Page down") }, + { { 'v', 0, 0 }, 0, CMD_LIST_RANGE_SELECT, "range-select", + N_("Range selection") }, + { { C('N'), 0, 0 }, 0, CMD_LIST_SCROLL_DOWN_LINE, "scroll-down-line", + N_("Scroll up one line") }, + { { C('B'), 0, 0 }, 0, CMD_LIST_SCROLL_UP_LINE, "scroll-up-line", + N_("Scroll down one line") }, + { { 'N', 0, 0 }, 0, CMD_LIST_SCROLL_DOWN_HALF, "scroll-down-half", + N_("Scroll up half a screen") }, + { { 'B', 0, 0 }, 0, CMD_LIST_SCROLL_UP_HALF, "scroll-up-half", + N_("Scroll down half a screen") }, + { { 'l', 0, 0 }, 0, CMD_SELECT_PLAYING, "select-playing", + N_("Select currently playing song") }, + + + /* basic screens */ + { { '1', F1, 'h' }, 0, CMD_SCREEN_HELP, "screen-help", + N_("Help screen") }, + { { '2', F2, 0 }, 0, CMD_SCREEN_PLAY, "screen-playlist", + N_("Playlist screen") }, + { { '3', F3, 0 }, 0, CMD_SCREEN_FILE, "screen-browse", + N_("Browse screen") }, + + + /* player commands */ + { { RET, 0, 0 }, 0, CMD_PLAY, "play", + N_("Play/Enter directory") }, + { { 'P', 0, 0 }, 0, CMD_PAUSE,"pause", + N_("Pause") }, + { { 's', BS, 0 }, 0, CMD_STOP, "stop", + N_("Stop") }, + { { 'o', 0, 0 }, 0, CMD_CROP, "crop", + N_("Crop") }, + { { '>', 0, 0 }, 0, CMD_TRACK_NEXT, "next", + N_("Next track") }, + { { '<', 0, 0 }, 0, CMD_TRACK_PREVIOUS, "prev", + N_("Previous track") }, + { { 'f', 0, 0 }, 0, CMD_SEEK_FORWARD, "seek-forward", + N_("Seek forward") }, + { { 'b', 0, 0 }, 0, CMD_SEEK_BACKWARD, "seek-backward", + N_("Seek backward") }, + { { '+', RGHT, 0 }, 0, CMD_VOLUME_UP, "volume-up", + N_("Increase volume") }, + { { '-', LEFT, 0 }, 0, CMD_VOLUME_DOWN, "volume-down", + N_("Decrease volume") }, + { { ' ', 0, 0 }, 0, CMD_SELECT, "select", + N_("Select/deselect song in playlist") }, + { { 't', 0, 0 }, 0, CMD_SELECT_ALL, "select_all", + N_("Select all listed items") }, + { { DEL, 'd', 0 }, 0, CMD_DELETE, "delete", + N_("Delete song from playlist") }, + { { 'Z', 0, 0 }, 0, CMD_SHUFFLE, "shuffle", + N_("Shuffle playlist") }, + { { 'c', 0, 0 }, 0, CMD_CLEAR, "clear", + N_("Clear playlist") }, + { { 'r', 0, 0 }, 0, CMD_REPEAT, "repeat", + N_("Toggle repeat mode") }, + { { 'z', 0, 0 }, 0, CMD_RANDOM, "random", + N_("Toggle random mode") }, + { { 'y', 0, 0 }, 0, CMD_SINGLE, "single", + N_("Toggle single mode") }, + { { 'C', 0, 0 }, 0, CMD_CONSUME, "consume", + N_("Toggle consume mode") }, + { { 'x', 0, 0 }, 0, CMD_CROSSFADE, "crossfade", + N_("Toggle crossfade mode") }, + { { C('U'), 0, 0 }, 0, CMD_DB_UPDATE, "db-update", + N_("Start a music database update") }, + { { 'S', 0, 0 }, 0, CMD_SAVE_PLAYLIST, "save", + N_("Save playlist") }, + { { 'a', 0, 0 }, 0, CMD_ADD, "add", + N_("Add url/file to playlist") }, + + { { '!', 0, 0 }, 0, CMD_GO_ROOT_DIRECTORY, "go-root-directory", + N_("Go to root directory") }, + { { '"', 0, 0 }, 0, CMD_GO_PARENT_DIRECTORY, "go-parent-directory", + N_("Go to parent directory") }, + + { { 'G', 0, 0 }, 0, CMD_LOCATE, "locate", + N_("Locate song in browser") }, + + /* lists */ + { { C('K'), 0, 0 }, 0, CMD_LIST_MOVE_UP, "move-up", + N_("Move item up") }, + { { C('J'), 0, 0 }, 0, CMD_LIST_MOVE_DOWN, "move-down", + N_("Move item down") }, + { { C('L'), 0, 0 }, 0, CMD_SCREEN_UPDATE, "update", + N_("Refresh screen") }, + + + /* ncmpc options */ + { { 'w', 0, 0 }, 0, CMD_TOGGLE_FIND_WRAP, "wrap-mode", + /* translators: toggle between wrapping and non-wrapping + search */ + N_("Toggle find mode") }, + { { 'U', 0, 0 }, 0, CMD_TOGGLE_AUTOCENTER, "autocenter-mode", + /* translators: the auto center mode always centers the song + currently being played */ + N_("Toggle auto center mode") }, + + + /* change screen */ + { { TAB, 0, 0 }, 0, CMD_SCREEN_NEXT, "screen-next", + N_("Next screen") }, + { { STAB, 0, 0 }, 0, CMD_SCREEN_PREVIOUS, "screen-prev", + N_("Previous screen") }, + { { '`', 0, 0 }, 0, CMD_SCREEN_SWAP, "screen-swap", + N_("Swap to most recent screen") }, + + + /* find */ + { { '/', 0, 0 }, 0, CMD_LIST_FIND, "find", + N_("Forward find") }, + { { 'n', 0, 0 }, 0, CMD_LIST_FIND_NEXT, "find-next", + N_("Forward find next") }, + { { '?', 0, 0 }, 0, CMD_LIST_RFIND, "rfind", + N_("Backward find") }, + { { 'p', 0, 0 }, 0, CMD_LIST_RFIND_NEXT, "rfind-next", + N_("Backward find previous") }, + { { '.', 0, 0 }, 0, CMD_LIST_JUMP, "jump", + /* translators: this queries the user for a string + * and jumps directly (while the user is typing) + * to the entry which begins with this string */ + N_("Jump to") }, + + + /* extra screens */ +#ifdef ENABLE_ARTIST_SCREEN + { {'4', F4, 0 }, 0, CMD_SCREEN_ARTIST, "screen-artist", + N_("Artist screen") }, +#endif +#ifdef ENABLE_SEARCH_SCREEN + { {'5', F5, 0 }, 0, CMD_SCREEN_SEARCH, "screen-search", + N_("Search screen") }, + { {'m', 0, 0 }, 0, CMD_SEARCH_MODE, "search-mode", + N_("Change search mode") }, +#endif +#ifdef ENABLE_SONG_SCREEN + { { 'i', 0, 0 }, 0, CMD_SCREEN_SONG, "view", + N_("View the selected and the currently playing song") }, +#endif +#ifdef ENABLE_LYRICS_SCREEN + { {'7', F7, 0 }, 0, CMD_SCREEN_LYRICS, "screen-lyrics", + N_("Lyrics screen") }, + { {ESC, 0, 0 }, 0, CMD_INTERRUPT, "lyrics-interrupt", + /* translators: interrupt the current background action, + e.g. stop loading lyrics from the internet */ + N_("Interrupt action") }, + { {'u', 0, 0 }, 0, CMD_LYRICS_UPDATE, "lyrics-update", + N_("Update Lyrics") }, + /* this command may move out of #ifdef ENABLE_LYRICS_SCREEN + at some point */ + { {'e', 0, 0 }, 0, CMD_EDIT, "edit", + N_("Edit the current item") }, +#endif + +#ifdef ENABLE_OUTPUTS_SCREEN + { {'8', F8, 0 }, 0, CMD_SCREEN_OUTPUTS, "screen-outputs", + N_("Outputs screen") }, #endif - { { 'q', 0, 0 }, CMD_QUIT, "quit", - "Quit " PACKAGE }, - { { -1, -1, -1 }, CMD_NONE, NULL, NULL } + { { -1, -1, -1 }, 0, CMD_NONE, NULL, NULL } }; +#ifdef ENABLE_KEYDEF_SCREEN command_definition_t * get_command_definitions(void) { - return cmds; + return cmds; } +#endif -char * +const char * key2str(int key) { - static char buf[32]; - int i; - - buf[0] = 0; - switch(key) - { - case 0: - return "Undefined"; - case ' ': - return "Space"; - case 13: - return "Enter"; - case BS: - return "Backspace"; - case DEL: - return "Delete"; - case UP: - return "Up"; - case DWN: - return "Down"; - case LEFT: - return "Left"; - case RGHT: - return "Right"; - case HOME: - return "Home"; - case END: - return "End"; - case PGDN: - return "PageDown"; - case PGUP: - return "PageUp"; - case TAB: - return "Tab"; - case STAB: - return "Shift+Tab"; - case ESC: - return "Esc"; - case KEY_IC: - return "Insert"; - default: - for(i=0; i<=63; i++) - if( key==KEY_F(i) ) - { - snprintf(buf, 32, "F%d", i ); - return buf; - } - if( !(key & ~037) ) - snprintf(buf, 32, "Ctrl-%c", 'A'+(key & 037)-1 ); - else if( (key & ~037) == 224 ) - snprintf(buf, 32, "Alt-%c", 'A'+(key & 037)-1 ); - else if( key>32 && key<256 ) - snprintf(buf, 32, "%c", key); - else - snprintf(buf, 32, "0x%03X", key); - } - return buf; + static char buf[32]; + int i; + + buf[0] = 0; + switch(key) { + case 0: + return _("Undefined"); + case ' ': + return _("Space"); + case RET: + return _("Enter"); + case BS: + return _("Backspace"); + case DEL: + return _("Delete"); + case UP: + return _("Up"); + case DWN: + return _("Down"); + case LEFT: + return _("Left"); + case RGHT: + return _("Right"); + case HOME: + return _("Home"); + case END: + return _("End"); + case PGDN: + return _("PageDown"); + case PGUP: + return _("PageUp"); + case TAB: + return _("Tab"); + case STAB: + return _("Shift+Tab"); + case ESC: + return _("Esc"); + case KEY_IC: + return _("Insert"); + default: + for (i = 0; i <= 63; i++) + if (key == KEY_F(i)) { + g_snprintf(buf, 32, _("F%d"), i ); + return buf; + } + if (!(key & ~037)) + g_snprintf(buf, 32, _("Ctrl-%c"), 'A'+(key & 037)-1 ); + else if ((key & ~037) == 224) + g_snprintf(buf, 32, _("Alt-%c"), 'A'+(key & 037)-1 ); + else if (key > 32 && key < 256) + g_snprintf(buf, 32, "%c", key); + else + g_snprintf(buf, 32, "0x%03X", key); + } + + return buf; } void command_dump_keys(void) { - int i; - - i=0; - while( cmds[i].description ) - { - if( cmds[i].command != CMD_NONE ) - printf(" %20s : %s\n", get_key_names(cmds[i].command,1),cmds[i].name); - i++; - } + for (int i = 0; cmds[i].description; i++) + if (cmds[i].command != CMD_NONE) + printf(" %20s : %s\n", + get_key_names(cmds[i].command, true), + cmds[i].name); } -char * -get_key_names(command_t command, int all) +#ifndef NCMPC_MINI + +static void +set_key_flags(command_definition_t *cp, command_t command, int flags) +{ + for (int i = 0; cp[i].name; i++) { + if (cp[i].command == command) { + cp[i].flags |= flags; + break; + } + } +} + +#endif + +const char * +get_key_names(command_t command, bool all) { - int i; - - i=0; - while( cmds[i].description ) - { - if( cmds[i].command == command ) - { - int j; - static char keystr[80]; - - strncpy(keystr, key2str(cmds[i].keys[0]), 80); - if( !all ) - return keystr; - j=1; - while( j0 ) - { - strcat(keystr, " "); - strcat(keystr, key2str(cmds[i].keys[j])); - j++; - } - return keystr; - } - i++; - } - return NULL; + for (int i = 0; cmds[i].description; i++) { + if (cmds[i].command == command) { + static char keystr[80]; + + g_strlcpy(keystr, key2str(cmds[i].keys[0]), sizeof(keystr)); + if (!all) + return keystr; + + for (int j = 1; j < MAX_COMMAND_KEYS && + cmds[i].keys[j] > 0; j++) { + g_strlcat(keystr, " ", sizeof(keystr)); + g_strlcat(keystr, key2str(cmds[i].keys[j]), sizeof(keystr)); + } + return keystr; + } + } + return NULL; } -char * +const char * get_key_description(command_t command) { - int i; - - i=0; - while( cmds[i].description ) - { - if( cmds[i].command == command ) - return cmds[i].description; - i++; - } - return NULL; + for (int i = 0; cmds[i].description; i++) + if (cmds[i].command == command) + return _(cmds[i].description); + + return NULL; } -char * +const char * get_key_command_name(command_t command) { - int i; - - i=0; - while( cmds[i].name ) - { - if( cmds[i].command == command ) - return cmds[i].name; - i++; - } - return NULL; + for (int i = 0; cmds[i].name; i++) + if (cmds[i].command == command) + return cmds[i].name; + + return NULL; } -command_t +command_t get_key_command_from_name(char *name) { - int i; - - i=0; - while( cmds[i].name ) - { - if( strcmp(name, cmds[i].name) == 0 ) - return cmds[i].command; - i++; - } - return CMD_NONE; -} + for (int i = 0; cmds[i].name; i++) + if (strcmp(name, cmds[i].name) == 0) + return cmds[i].command; + return CMD_NONE; +} -command_t -find_key_command(int key, command_definition_t *cmds) +command_t +find_key_command(int key, command_definition_t *c) { - int i; - - i=0; - while( cmds && cmds[i].name ) - { - if( cmds[i].keys[0] == key || - cmds[i].keys[1] == key || - cmds[i].keys[2] == key ) - return cmds[i].command; - i++; - } - return CMD_NONE; + assert(key != 0); + assert(c != NULL); + + for (int i = 0; c[i].name; i++) { + for (int j = 0; j < MAX_COMMAND_KEYS; j++) + if (c[i].keys[j] == key) + return c[i].command; + } + + return CMD_NONE; } -command_t +command_t get_key_command(int key) { - return find_key_command(key, cmds); + return find_key_command(key, cmds); } - command_t get_keyboard_command(void) { - int key; - - key = wgetch(stdscr); - - if( key==KEY_RESIZE ) - screen_resize(); + int key; - if( key==ERR ) - return CMD_NONE; + key = wgetch(stdscr); + if (key == ERR) + return CMD_NONE; - DK(fprintf(stderr, "key = 0x%02X\t", key)); +#ifdef HAVE_GETMOUSE + if (key == KEY_MOUSE) + return CMD_MOUSE_EVENT; +#endif - return get_key_command(key); + return get_key_command(key); } int assign_keys(command_t command, int keys[MAX_COMMAND_KEYS]) { - int i; - - i=0; - while( cmds[i].name ) - { - if( cmds[i].command == command ) - { - memcpy(cmds[i].keys, keys, sizeof(int)*MAX_COMMAND_KEYS); - return 0; + for (int i = 0; cmds[i].name; i++) { + if (cmds[i].command == command) { + memcpy(cmds[i].keys, keys, sizeof(int)*MAX_COMMAND_KEYS); +#ifndef NCMPC_MINI + cmds[i].flags |= COMMAND_KEY_MODIFIED; +#endif + return 0; + } } - i++; - } - return -1; + + return -1; } -int -check_key_bindings(void) +#ifndef NCMPC_MINI + +int +check_key_bindings(command_definition_t *cp, char *buf, size_t bufsize) { - int i; - int retval = 0; - - i=0; - while( cmds[i].name ) - { - int j; - command_t cmd; - - for(j=0; j