Code

Added keydef screen
authorKalle Wallin <kaw@linux.se>
Mon, 19 Apr 2004 22:12:53 +0000 (22:12 +0000)
committerKalle Wallin <kaw@linux.se>
Mon, 19 Apr 2004 22:12:53 +0000 (22:12 +0000)
git-svn-id: https://svn.musicpd.org/ncmpc/trunk@834 09075e82-0dd4-0310-85a5-a0d7c8717e4f

Makefile.am
command.h
configure.ac
screen_keydef.c [new file with mode: 0644]

index 50f0f11badf692b3120d9365d54c5f050420e2a1..bada1ea014e5e6e3258aa0097ade0786604b6a23 100644 (file)
@@ -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)
 
 
index 5c449bcb52e5280f7f06e245fcbc550b7742d9d5..d0ec67f2422d6acf3e36952af1641e70a5126cf2 100644 (file)
--- 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);
index 989f9bb0220840a91d725f36dd93e44b222788d7..bc33451082851a16508bfd74b6dc548060069c89 100644 (file)
@@ -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 (file)
index 0000000..9e439f5
--- /dev/null
@@ -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 <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <ncurses.h>
+
+#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_length<MAX_COMMAND_KEYS && cmds[subcmd].keys[subcmd_length]>0 )
+   subcmd_length ++;
+
+  if( subcmd_length<MAX_COMMAND_KEYS )
+    {
+      subcmd_addpos = subcmd_length;
+      subcmd_length++;
+    }
+  else
+    subcmd_addpos = 0;
+  subcmd_length += STATIC_SUB_ITEMS;
+}
+
+static void
+delete_key(int cmd_index, int key_index)
+{
+  int i = key_index+1;
+
+  screen_status_printf("Delete...");
+  while( i<MAX_COMMAND_KEYS && cmds[cmd_index].keys[i] )
+    cmds[cmd_index].keys[key_index++] = cmds[cmd_index].keys[i++];
+  cmds[cmd_index].keys[key_index] = 0;
+
+  check_subcmd_length();
+  lw->clear = 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( index<command_list_length )
+       return cmds[index].name;
+      else if( index==LIST_ITEM_APPLY() )
+       return LIST_ITEM_APPLY_LABEL;
+      else if( index==LIST_ITEM_SAVE() )
+       return LIST_ITEM_SAVE_LABEL;
+    }
+  else
+  {
+    if( index== 0 )
+      return "[..]";
+    index--;
+    if( index<MAX_COMMAND_KEYS && cmds[subcmd].keys[index]>0 )
+      {
+       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