From: Kalle Wallin Date: Mon, 19 Apr 2004 22:12:53 +0000 (+0000) Subject: Added keydef screen X-Git-Tag: v0.12_alpha1~578 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=7e3af33b2a6623f026fe80eb8c5026817f9d444a;p=ncmpc.git Added keydef screen git-svn-id: https://svn.musicpd.org/ncmpc/trunk@834 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- diff --git a/Makefile.am b/Makefile.am index 50f0f11..bada1ea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ ncmpc_headers = libmpdclient.h mpc.h options.h conf.h command.h screen.h \ ncmpc_SOURCES = libmpdclient.c main.c mpc.c options.c conf.c command.c \ screen.c screen_utils.c screen_play.c screen_file.c \ - screen_search.c screen_help.c \ + screen_search.c screen_help.c screen_keydef.c \ list_window.c support.c $(ncmpc_headers) diff --git a/command.h b/command.h index 5c449bc..d0ec67f 100644 --- a/command.h +++ b/command.h @@ -38,6 +38,7 @@ typedef enum CMD_SCREEN_PLAY, CMD_SCREEN_FILE, CMD_SCREEN_SEARCH, + CMD_SCREEN_KEYDEF, CMD_SCREEN_HELP, CMD_QUIT } command_t; @@ -50,11 +51,14 @@ typedef struct char *description; } command_definition_t; +command_definition_t *get_command_definitions(void); +command_t find_key_command(int key, command_definition_t *cmds); void command_dump_keys(void); int check_key_bindings(void); int write_key_bindings(FILE *f); +char *key2str(int key); char *get_key_description(command_t command); char *get_key_command_name(command_t command); char *get_key_names(command_t command, int all); diff --git a/configure.ac b/configure.ac index 989f9bb..bc33451 100644 --- a/configure.ac +++ b/configure.ac @@ -17,6 +17,8 @@ dnl ======================================================= set -- $CFLAGS CFLAGS="-Wall $CFLAGS" +keydef_screen=yes + dnl dnl Check for types dnl @@ -27,9 +29,6 @@ dnl ) AC_SOCKLEN_T - - - dnl dnl Check for headers dnl @@ -71,23 +70,35 @@ AC_CHECK_LIB(popt, dnl Debugging AC_ARG_ENABLE(debug, - [ --enable-debug Enable debugging [default=no]], + AS_HELP_STRING([--enable-debug],[Enable debugging]), , enable_debug=no) if test "$enable_debug" = yes; then - CFLAGS="$CFLAGS -g -DDEBUG" + CFLAGS="$CFLAGS -g -DDEBUG" fi +dnl Key editor +AC_ARG_ENABLE(key-editor, + AS_HELP_STRING([--enable-key-editor],[Enable key editor]), + keydef_screen=no, + keydef_screen=yes) +if test "$keydef_screen" = yes; then + CFLAGS="$CFLAGS -DENABLE_KEYDEF_SCREEN" +fi +dnl AC_DEFINE(ENABLE_KEYDEF_SCREEN, 1, [Enable builtin key editor]), + + dnl Default host AC_ARG_WITH(default-host, - [ --with-default-host=HOST Default host (localhost)], + AS_HELP_STRING([--with-default-host=ARG], + [Default MPD host (localhost)]), DEFAULT_HOST="$withval", DEFAULT_HOST="localhost") dnl Default port AC_ARG_WITH(default-port, - [ --with-default-port=PORT Default port (2100)], + AS_HELP_STRING([--with-default-port=ARG],[Default port (2100)]), DEFAULT_PORT="$withval", DEFAULT_PORT="2100") @@ -109,8 +120,9 @@ echo " Configuration: prefix: ${prefix} sysconfdir: ${sysconfdir} - Enable debugging: ${enable_debug} Default MPD host: ${DEFAULT_HOST} Default MPD port: ${DEFAULT_PORT} + Enable debugging: ${enable_debug} + Key edit screen: ${keydef_screen} " echo diff --git a/screen_keydef.c b/screen_keydef.c new file mode 100644 index 0000000..9e439f5 --- /dev/null +++ b/screen_keydef.c @@ -0,0 +1,381 @@ +/* + * (c) 2004 by Kalle Wallin (kaw@linux.se) + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * 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 + * + */ + +#include +#include +#include +#include +#include + +#include "config.h" + +#ifdef ENABLE_KEYDEF_SCREEN +#include "libmpdclient.h" +#include "options.h" +#include "conf.h" +#include "mpc.h" +#include "command.h" +#include "screen.h" +#include "screen_utils.h" + +#define STATIC_ITEMS 0 +#define STATIC_SUB_ITEMS 1 +#define BUFSIZE 256 + +#define LIST_ITEM_APPLY() (command_list_length) +#define LIST_ITEM_SAVE() (LIST_ITEM_APPLY()+1) +#define LIST_LENGTH() (LIST_ITEM_SAVE()+1) + +#define LIST_ITEM_SAVE_LABEL "===> Apply & Save key bindings " +#define LIST_ITEM_APPLY_LABEL "===> Apply key bindings " + + +static list_window_t *lw = NULL; +static int command_list_length = 0; +static command_definition_t *cmds = NULL; + +static int subcmd = -1; +static int subcmd_length = 0; +static int subcmd_addpos = 0; + +static int +keybindings_changed(void) +{ + command_definition_t *orginal_cmds = get_command_definitions(); + size_t size = command_list_length*sizeof(command_definition_t); + + return memcmp(orginal_cmds, cmds, size); +} + +static void +apply_keys(void) +{ + if( keybindings_changed() ) + { + command_definition_t *orginal_cmds = get_command_definitions(); + size_t size = command_list_length*sizeof(command_definition_t); + + memcpy(orginal_cmds, cmds, size); + screen_status_printf("You have new key bindings!"); + } + else + screen_status_printf("Keybindings unchanged."); +} + +static int +save_keys(void) +{ + FILE *f; + char *filename; + + if( check_user_conf_dir() ) + { + screen_status_printf("Error: Unable to create direcory ~/.ncmpc - %s", + strerror(errno)); + beep(); + return -1; + } + + filename = get_user_key_binding_filename(); + + if( (f=fopen(filename,"w")) == NULL ) + { + screen_status_printf("Error: %s - %s", filename, strerror(errno)); + beep(); + g_free(filename); + return -1; + } + if( write_key_bindings(f) ) + screen_status_printf("Error: %s - %s", filename, strerror(errno)); + else + screen_status_printf("Wrote %s", filename); + + g_free(filename); + return fclose(f); +} + +static void +check_subcmd_length(void) +{ + subcmd_length = 0; + while( subcmd_length0 ) + subcmd_length ++; + + if( subcmd_lengthclear = 1; + lw->repaint = 1; +} + +static void +assign_new_key(WINDOW *w, int cmd_index, int key_index) +{ + int key; + char buf[BUFSIZE]; + command_t cmd; + + snprintf(buf, BUFSIZE, "Enter new key for %s: ", cmds[cmd_index].name); + key = screen_getch(w, buf); + if( key==ERR ) + { + screen_status_printf("Aborted!"); + return; + } + cmd = find_key_command(key, cmds); + if( cmd!=CMD_NONE && cmd!= cmds[cmd_index].command ) + { + screen_status_printf("Error: key %s is already used for %s", + key2str(key), + get_key_command_name(cmd)); + beep(); + return; + } + cmds[cmd_index].keys[key_index] = key; + screen_status_printf("Assigned %s to %s", key2str(key),cmds[cmd_index].name); + check_subcmd_length(); + lw->repaint = 1; +} + +static char * +list_callback(int index, int *highlight, void *data) +{ + static char buf[BUFSIZE]; + + if( subcmd <0 ) + { + if( index0 ) + { + snprintf(buf, + BUFSIZE, "%d. %-20s (%d) ", + index+1, + key2str(cmds[subcmd].keys[index]), + cmds[subcmd].keys[index]); + return buf; + } + else if ( index==subcmd_addpos ) + { + snprintf(buf, BUFSIZE, "%d. Add new key ", index+1 ); + return buf; + } + } + + return NULL; +} + +static void +keydef_init(WINDOW *w, int cols, int rows) +{ + lw = list_window_init(w, cols, rows); +} + +static void +keydef_exit(void) +{ + list_window_free(lw); + if( cmds ) + g_free(cmds); + cmds = NULL; + lw = NULL; +} + +static void +keydef_open(screen_t *screen, mpd_client_t *c) +{ + if( cmds == NULL ) + { + command_definition_t *current_cmds = get_command_definitions(); + size_t cmds_size; + + command_list_length = 0; + while( current_cmds[command_list_length].name ) + command_list_length++; + + cmds_size = (command_list_length+1)*sizeof(command_definition_t); + cmds = g_malloc0(cmds_size); + memcpy(cmds, current_cmds, cmds_size); + command_list_length += STATIC_ITEMS; + screen_status_printf("Welcome to the key editor!"); + } + + subcmd = -1; + list_window_check_selected(lw, LIST_LENGTH()); +} + +static void +keydef_close(void) +{ + if( cmds && !keybindings_changed() ) + { + g_free(cmds); + cmds = NULL; + } +} + +static char * +keydef_title(void) +{ + static char buf[BUFSIZE]; + + if( subcmd<0 ) + return (TOP_HEADER_PREFIX "Edit key bindings"); + + snprintf(buf, BUFSIZE, + TOP_HEADER_PREFIX "Edit keys for %s", + cmds[subcmd].name); + return buf; +} + +static void +keydef_paint(screen_t *screen, mpd_client_t *c) +{ + lw->clear = 1; + list_window_paint(lw, list_callback, NULL); + wrefresh(lw->w); +} + +static void +keydef_update(screen_t *screen, mpd_client_t *c) +{ + if( lw->repaint ) + { + list_window_paint(lw, list_callback, NULL); + wrefresh(lw->w); + lw->repaint = 0; + } +} + +static int +keydef_cmd(screen_t *screen, mpd_client_t *c, command_t cmd) +{ + int length = LIST_LENGTH(); + + if( subcmd>=0 ) + length = subcmd_length; + + switch(cmd) + { + case CMD_PLAY: + if( subcmd<0 ) + { + if( lw->selected == LIST_ITEM_APPLY() ) + apply_keys(); + else if( lw->selected == LIST_ITEM_SAVE() ) + { + apply_keys(); + save_keys(); + } + else + { + subcmd = lw->selected; + lw->selected=0; + check_subcmd_length(); + } + } + else + { + if( lw->selected == 0 ) /* up */ + { + lw->selected = subcmd; + subcmd = -1; + } + else + assign_new_key(screen->status_window.w, + subcmd, + lw->selected-STATIC_SUB_ITEMS); + } + lw->repaint = 1; + lw->clear = 1; + return 1; + case CMD_DELETE: + if( subcmd>=0 && lw->selected-STATIC_SUB_ITEMS>=0 ) + delete_key(subcmd, lw->selected-STATIC_SUB_ITEMS); + return 1; + break; + case CMD_LIST_FIND: + case CMD_LIST_RFIND: + case CMD_LIST_FIND_NEXT: + case CMD_LIST_RFIND_NEXT: + return screen_find(screen, c, + lw, length, + cmd, list_callback); + + default: + break; + } + + return list_window_cmd(lw, length, cmd); +} + +static list_window_t * +keydef_lw(void) +{ + return lw; +} + +screen_functions_t * +get_screen_keydef(void) +{ + static screen_functions_t functions; + + memset(&functions, 0, sizeof(screen_functions_t)); + functions.init = keydef_init; + functions.exit = keydef_exit; + functions.open = keydef_open; + functions.close = keydef_close; + functions.paint = keydef_paint; + functions.update = keydef_update; + functions.cmd = keydef_cmd; + functions.get_lw = keydef_lw; + functions.get_title = keydef_title; + + return &functions; +} + + +#endif