# HG changeset patch # User ulion # Date 1196764979 0 # Node ID 96d0992c79205f313c933dd093a2961c39c32f4d # Parent f1922d2b19252ba2ffde8961f29df7bd99b1aa11 Remove hardcoded key->cmd bindings in libmenu, support custom key bindings by menu config file. diff -r f1922d2b1925 -r 96d0992c7920 etc/menu.conf --- a/etc/menu.conf Mon Dec 03 23:38:51 2007 +0000 +++ b/etc/menu.conf Tue Dec 04 10:42:59 2007 +0000 @@ -1,3 +1,23 @@ + + + + + + + + + + + + + + + + + + + + diff -r f1922d2b1925 -r 96d0992c7920 input/input.c --- a/input/input.c Mon Dec 03 23:38:51 2007 +0000 +++ b/input/input.c Tue Dec 04 10:42:59 2007 +0000 @@ -1373,7 +1373,7 @@ } -static int +int mp_input_get_key_from_name(const char *name) { int i,ret = 0,len = strlen(name); if(len == 1) { // Direct key code diff -r f1922d2b1925 -r 96d0992c7920 input/input.h --- a/input/input.h Mon Dec 03 23:38:51 2007 +0000 +++ b/input/input.h Tue Dec 04 10:42:59 2007 +0000 @@ -238,6 +238,9 @@ void mp_input_rm_event_fd(int fd); +/// Get input key from its name. +int mp_input_get_key_from_name(const char *name); + // This function can be used to put a command in the system again. It's used by libmpdemux // when it performs a blocking operation to resend the command it received to the main // loop. diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu.c --- a/libmenu/menu.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu.c Tue Dec 04 10:42:59 2007 +0000 @@ -15,6 +15,7 @@ #include "osdep/keycodes.h" #include "asxparser.h" #include "stream/stream.h" +#include "input/input.h" #include "libmpcodecs/img_format.h" #include "libmpcodecs/mp_image.h" @@ -46,6 +47,18 @@ NULL }; +typedef struct key_cmd_s { + int key; + char *cmd; +} key_cmd_t; + +typedef struct menu_cmd_bindings_s { + char *name; + key_cmd_t *bindings; + int binding_num; + struct menu_cmd_bindings_s *parent; +} menu_cmd_bindings_t; + struct menu_def_st { char* name; menu_info_t* type; @@ -56,8 +69,18 @@ static struct MPContext *menu_ctx = NULL; static menu_def_t* menu_list = NULL; static int menu_count = 0; +static menu_cmd_bindings_t *cmd_bindings = NULL; +static int cmd_bindings_num = 0; +menu_cmd_bindings_t *get_cmd_bindings(const char *name) { + int i; + for (i = 0; i < cmd_bindings_num; ++i) + if (!strcasecmp(cmd_bindings[i].name, name)) + return &cmd_bindings[i]; + return NULL; +} + static int menu_parse_config(char* buffer) { char *element,*body, **attribs, *name; menu_info_t* minfo = NULL; @@ -84,6 +107,59 @@ continue; } + if (!strcasecmp(element, "keybindings")) { + menu_cmd_bindings_t *bindings = cmd_bindings; + const char *parent_bindings; + cmd_bindings = realloc(cmd_bindings, + (cmd_bindings_num+1)*sizeof(menu_cmd_bindings_t)); + for (i = 0; i < cmd_bindings_num; ++i) + if (cmd_bindings[i].parent) + cmd_bindings[i].parent = cmd_bindings[i].parent-bindings+cmd_bindings; + bindings = &cmd_bindings[cmd_bindings_num]; + memset(bindings, 0, sizeof(menu_cmd_bindings_t)); + bindings->name = strdup(name); + parent_bindings = asx_get_attrib("parent",attribs); + if (parent_bindings) + bindings->parent = get_cmd_bindings(parent_bindings); + free(element); + asx_free_attribs(attribs); + if (body) { + char *bd = body; + char *b, *key, *cmd; + int keycode; + for(;;) { + r = asx_get_element(parser,&bd,&element,&b,&attribs); + if(r < 0) { + mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_SyntaxErrorAtLine, + parser->line); + free(body); + asx_parser_free(parser); + return 0; + } + if(r == 0) + break; + key = asx_get_attrib("key",attribs); + cmd = asx_get_attrib("cmd",attribs); + if (key && (keycode = mp_input_get_key_from_name(key)) >= 0) { + mp_msg(MSGT_GLOBAL,MSGL_V, + "[libmenu] got keybinding element %s %s=>[%s].\n", + element, key, cmd ? cmd : ""); + bindings->bindings = realloc(bindings->bindings, + (bindings->binding_num+1)*sizeof(key_cmd_t)); + bindings->bindings[bindings->binding_num].key = keycode; + bindings->bindings[bindings->binding_num].cmd = cmd ? strdup(cmd) + : NULL; + ++bindings->binding_num; + } + free(element); + asx_free_attribs(attribs); + free(b); + } + free(body); + } + ++cmd_bindings_num; + continue; + } // Try to find this menu type in our list for(i = 0, minfo = NULL ; menu_info_list[i] ; i++) { if(strcasecmp(element,menu_info_list[i]->name) == 0) { @@ -178,30 +254,34 @@ } free(menu_list); menu_count = 0; + for (i = 0; i < cmd_bindings_num; ++i) { + free(cmd_bindings[i].name); + while(cmd_bindings[i].binding_num > 0) + free(cmd_bindings[i].bindings[--cmd_bindings[i].binding_num].cmd); + free(cmd_bindings[i].bindings); + } + free(cmd_bindings); } /// Default read_key function -void menu_dflt_read_key(menu_t* menu,int cmd) { - switch(cmd) { - case KEY_UP: - menu->read_cmd(menu,MENU_CMD_UP); - break; - case KEY_DOWN: - menu->read_cmd(menu,MENU_CMD_DOWN); - break; - case KEY_LEFT: - menu->read_cmd(menu,MENU_CMD_LEFT); - break; - case KEY_ESC: - menu->read_cmd(menu,MENU_CMD_CANCEL); - break; - case KEY_RIGHT: - menu->read_cmd(menu,MENU_CMD_RIGHT); - break; - case KEY_ENTER: - menu->read_cmd(menu,MENU_CMD_OK); - break; +int menu_dflt_read_key(menu_t* menu,int cmd) { + int i; + menu_cmd_bindings_t *bindings = get_cmd_bindings(menu->type->name); + if (!bindings) + bindings = get_cmd_bindings(menu->type->type->name); + if (!bindings) + bindings = get_cmd_bindings("default"); + while (bindings) { + for (i = 0; i < bindings->binding_num; ++i) { + if (bindings->bindings[i].key == cmd) { + if (bindings->bindings[i].cmd) + mp_input_queue_cmd(mp_input_parse_cmd(bindings->bindings[i].cmd)); + return 1; + } + } + bindings = bindings->parent; } + return 0; } menu_t* menu_open(char *name) { diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu.h --- a/libmenu/menu.h Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu.h Tue Dec 04 10:42:59 2007 +0000 @@ -38,6 +38,10 @@ #define MENU_CMD_LEFT 4 #define MENU_CMD_RIGHT 5 #define MENU_CMD_ACTION 6 +#define MENU_CMD_HOME 7 +#define MENU_CMD_END 8 +#define MENU_CMD_PAGE_UP 9 +#define MENU_CMD_PAGE_DOWN 10 /// Global init/uninit int menu_init(struct MPContext *mpctx, char* cfg_file); @@ -52,7 +56,7 @@ void menu_read_key(menu_t* menu,int cmd); //// Default implementation -void menu_dflt_read_key(menu_t* menu,int cmd); +int menu_dflt_read_key(menu_t* menu,int cmd); /////////// Helpers diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_cmdlist.c --- a/libmenu/menu_cmdlist.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_cmdlist.c Tue Dec 04 10:42:59 2007 +0000 @@ -91,10 +91,6 @@ } } -static void read_key(menu_t* menu,int c){ - menu_list_read_key(menu,c,0); -} - static void free_entry(list_entry_t* entry) { if(entry->ok) free(entry->ok); @@ -152,7 +148,6 @@ static int open_cmdlist(menu_t* menu, char* args) { menu->draw = menu_list_draw; menu->read_cmd = read_cmd; - menu->read_key = read_key; menu->close = close_menu; if(!args) { diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_console.c --- a/libmenu/menu_console.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_console.c Tue Dec 04 10:42:59 2007 +0000 @@ -221,20 +221,6 @@ return; } -static void read_cmd(menu_t* menu,int cmd) { - switch(cmd) { - case MENU_CMD_UP: - break; - case MENU_CMD_DOWN: - case MENU_CMD_OK: - break; - case MENU_CMD_CANCEL: - menu->show = 0; - menu->cl = 1; - break; - } -} - static void check_child(menu_t* menu) { #ifndef __MINGW32__ fd_set rfd; @@ -362,16 +348,16 @@ //mpriv->input = mpriv->cur_history->buffer; } -static void read_key(menu_t* menu,int c) { - if(!mpriv->child || !mpriv->raw_child) switch(c) { - case KEY_ESC: +static void read_cmd(menu_t* menu,int cmd) { + switch(cmd) { + case MENU_CMD_CANCEL: if(mpriv->hide_time) mpriv->hide_ts = GetTimerMS(); else menu->show = 0; mpriv->show_ts = 0; return; - case KEY_ENTER: { + case MENU_CMD_OK: { mp_cmd_t* c; if(mpriv->child) { char *str = mpriv->cur_history->buffer; @@ -422,27 +408,31 @@ } return; } - case KEY_DELETE: - case KEY_BS: { + case MENU_CMD_UP: + if(mpriv->cur_history->prev) + mpriv->cur_history = mpriv->cur_history->prev; + break; + case MENU_CMD_DOWN: + if(mpriv->cur_history->next) + mpriv->cur_history = mpriv->cur_history->next; + break; + } +} + +static void read_key(menu_t* menu,int c) { + if(mpriv->child && mpriv->raw_child) { + write(mpriv->child_fd[0],&c,sizeof(int)); + return; + } + + if (c == KEY_DELETE || c == KEY_BS) { unsigned int i = strlen(mpriv->cur_history->buffer); if(i > 0) mpriv->cur_history->buffer[i-1] = '\0'; return; } - case KEY_UP: - if(mpriv->cur_history->prev) - mpriv->cur_history = mpriv->cur_history->prev; - break; - case KEY_DOWN: - if(mpriv->cur_history->next) - mpriv->cur_history = mpriv->cur_history->next; - break; - } - - if(mpriv->child && mpriv->raw_child) { - write(mpriv->child_fd[0],&c,sizeof(int)); + if (menu_dflt_read_key(menu, c)) return; - } if(isascii(c)) { int l = strlen(mpriv->cur_history->buffer); @@ -453,7 +443,7 @@ mpriv->cur_history->buffer[l] = (char)c; mpriv->cur_history->buffer[l+1] = '\0'; } - + return; } diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_filesel.c --- a/libmenu/menu_filesel.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_filesel.c Tue Dec 04 10:42:59 2007 +0000 @@ -370,19 +370,16 @@ } static void read_key(menu_t* menu,int c){ - if(c == KEY_BS) - read_cmd(menu,MENU_CMD_LEFT); - else { char **str; for (str=mpriv->actions; str && *str; str++) if (c == (*str)[0]) { action = &(*str)[2]; read_cmd(menu,MENU_CMD_ACTION); - break; + return; } - if (!str || !*str) - menu_list_read_key(menu,c,1); - } + if (menu_dflt_read_key(menu, c)) + return; + menu_list_jump_to_key(menu, c); } static void clos(menu_t* menu) { diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_list.c --- a/libmenu/menu_list.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_list.c Tue Dec 04 10:42:59 2007 +0000 @@ -153,6 +153,8 @@ } void menu_list_read_cmd(menu_t* menu,int cmd) { + list_entry_t* m; + int i; switch(cmd) { case MENU_CMD_UP: while(mpriv->current->prev) { @@ -179,6 +181,27 @@ if(!mpriv->current->hide) return; } break; + case MENU_CMD_HOME: + mpriv->current = mpriv->menu; + break; + case MENU_CMD_END: + for(m = mpriv->current ; m && m->next ; m = m->next) + /**/; + if(m) + mpriv->current = m; + break; + case MENU_CMD_PAGE_UP: + for(i = 0, m = mpriv->current ; m && m->prev && i < mpriv->disp_lines ; m = m->prev, i++) + /**/; + if(m) + mpriv->current = m; + break; + case MENU_CMD_PAGE_DOWN: + for(i = 0, m = mpriv->current ; m && m->next && i < mpriv->disp_lines ; m = m->next, i++) + /**/; + if(m) + mpriv->current = m; + break; case MENU_CMD_LEFT: case MENU_CMD_CANCEL: menu->show = 0; @@ -187,57 +210,25 @@ } } -void menu_list_jump_to_key(menu_t* menu,int c) { +int menu_list_jump_to_key(menu_t* menu,int c) { if(c < 256 && isalnum(c)) { list_entry_t* e = mpriv->current; if(e->txt[0] == c) e = e->next; for( ; e ; e = e->next) { if(e->txt[0] == c) { mpriv->current = e; - return; + return 1; } } for(e = mpriv->menu ; e ; e = e->next) { if(e->txt[0] == c) { mpriv->current = e; - return; + return 1; } } - } else - menu_dflt_read_key(menu,c); -} - -void menu_list_read_key(menu_t* menu,int c,int jump_to) { - list_entry_t* m; - int i; - switch(c) { - case KEY_HOME: - mpriv->current = mpriv->menu; - break; - case KEY_END: - for(m = mpriv->current ; m && m->next ; m = m->next) - /**/; - if(m) - mpriv->current = m; - break; - case KEY_PAGE_UP: - for(i = 0, m = mpriv->current ; m && m->prev && i < mpriv->disp_lines ; m = m->prev, i++) - /**/; - if(m) - mpriv->current = m; - break; - case KEY_PAGE_DOWN: - for(i = 0, m = mpriv->current ; m && m->next && i < mpriv->disp_lines ; m = m->next, i++) - /**/; - if(m) - mpriv->current = m; - break; - default: - if(jump_to) - menu_list_jump_to_key(menu,c); - else - menu_dflt_read_key(menu,c); - } + return 1; + } + return 0; } void menu_list_add_entry(menu_t* menu,list_entry_t* entry) { diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_list.h --- a/libmenu/menu_list.h Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_list.h Tue Dec 04 10:42:59 2007 +0000 @@ -38,12 +38,11 @@ typedef void (*free_entry_t)(list_entry_t* entry); void menu_list_read_cmd(menu_t* menu,int cmd); -void menu_list_read_key(menu_t* menu,int c,int jump_to); void menu_list_draw(menu_t* menu,mp_image_t* mpi); void menu_list_add_entry(menu_t* menu,list_entry_t* entry); void menu_list_init(menu_t* menu); void menu_list_uninit(menu_t* menu,free_entry_t free_func); -void menu_list_jump_to_key(menu_t* menu,int c); +int menu_list_jump_to_key(menu_t* menu,int c); extern const menu_list_priv_t menu_list_priv_dflt; diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_param.c --- a/libmenu/menu_param.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_param.c Tue Dec 04 10:42:59 2007 +0000 @@ -157,10 +157,6 @@ } } -static void read_key(menu_t* menu,int c) { - menu_list_read_key(menu,c,0); -} - static void read_cmd(menu_t* menu,int cmd) { list_entry_t* e = mpriv->p.current; @@ -247,7 +243,6 @@ menu->draw = menu_list_draw; menu->read_cmd = read_cmd; - menu->read_key = read_key; menu->close = closeMenu; diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_pt.c --- a/libmenu/menu_pt.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_pt.c Tue Dec 04 10:42:59 2007 +0000 @@ -96,7 +96,9 @@ } static void read_key(menu_t* menu,int c){ - menu_list_read_key(menu,c,1); + if (menu_dflt_read_key(menu, c)) + return; + menu_list_jump_to_key(menu, c); } static void close_menu(menu_t* menu) { diff -r f1922d2b1925 -r 96d0992c7920 libmenu/menu_txt.c --- a/libmenu/menu_txt.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/menu_txt.c Tue Dec 04 10:42:59 2007 +0000 @@ -66,26 +66,19 @@ menu->show = 0; menu->cl = 1; break; - } -} - -static void read_key(menu_t* menu,int c) { - switch (c) { - case KEY_HOME: + case MENU_CMD_HOME: mpriv->cur_line = 0; break; - case KEY_END: + case MENU_CMD_END: mpriv->cur_line = mpriv->num_lines - 1; break; - case KEY_PAGE_UP: + case MENU_CMD_PAGE_UP: mpriv->cur_line = mpriv->cur_line > mpriv->disp_lines ? mpriv->cur_line - mpriv->disp_lines : 0; break; - case KEY_PAGE_DOWN: + case MENU_CMD_PAGE_DOWN: mpriv->cur_line = mpriv->cur_line + mpriv->disp_lines > mpriv->num_lines - 1 ? mpriv->num_lines - 1 : mpriv->cur_line + mpriv->disp_lines; break; - default: - menu_dflt_read_key(menu,c); } } @@ -129,7 +122,6 @@ menu->draw = draw; menu->read_cmd = read_cmd; - menu->read_key = read_key; if(!mpriv->file) { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuTxtNeedATxtFileName); diff -r f1922d2b1925 -r 96d0992c7920 libmenu/vf_menu.c --- a/libmenu/vf_menu.c Mon Dec 03 23:38:51 2007 +0000 +++ b/libmenu/vf_menu.c Tue Dec 04 10:42:59 2007 +0000 @@ -73,6 +73,14 @@ menu_read_cmd(priv->current,MENU_CMD_OK); else if(strcmp(arg,"cancel") == 0) menu_read_cmd(priv->current,MENU_CMD_CANCEL); + else if(strcmp(arg,"home") == 0) + menu_read_cmd(priv->current,MENU_CMD_HOME); + else if(strcmp(arg,"end") == 0) + menu_read_cmd(priv->current,MENU_CMD_END); + else if(strcmp(arg,"pageup") == 0) + menu_read_cmd(priv->current,MENU_CMD_PAGE_UP); + else if(strcmp(arg,"pagedown") == 0) + menu_read_cmd(priv->current,MENU_CMD_PAGE_DOWN); else if(strcmp(arg,"hide") == 0 || strcmp(arg,"toggle") == 0) priv->current->show = 0; else