summaryrefslogtreecommitdiffstats
path: root/libmenu/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmenu/menu.c')
-rw-r--r--libmenu/menu.c120
1 files changed, 100 insertions, 20 deletions
diff --git a/libmenu/menu.c b/libmenu/menu.c
index 8c9a6f7901..8b49334e17 100644
--- a/libmenu/menu.c
+++ b/libmenu/menu.c
@@ -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 @@ menu_info_t* menu_info_list[] = {
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 @@ struct menu_def_st {
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 @@ static int menu_parse_config(char* buffer) {
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 @@ void menu_unint(void) {
}
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) {