📄 menu.c
字号:
#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <fcntl.h>#include <mplaylib.h>#include "libvo/osd.h"#include "libvo/font_load.h"#include "libvo/sub.h"#include "osdep/keycodes.h"#include "asxparser.h"#include "stream/stream.h"#include "libmpcodecs/img_format.h"#include "libmpcodecs/mp_image.h"#include "m_option.h"#include "m_struct.h"#include "menu.h"extern menu_info_t menu_info_cmdlist;extern menu_info_t menu_info_pt;extern menu_info_t menu_info_filesel;extern menu_info_t menu_info_txt;extern menu_info_t menu_info_console;extern menu_info_t menu_info_pref;#ifdef HAS_DVBIN_SUPPORTextern menu_info_t menu_info_dvbsel;#endifmenu_info_t* menu_info_list[] = { &menu_info_pt, &menu_info_cmdlist, &menu_info_filesel, &menu_info_txt, &menu_info_console,#ifdef HAS_DVBIN_SUPPORT &menu_info_dvbsel,#endif &menu_info_pref, NULL};typedef struct menu_def_st { char* name; menu_info_t* type; void* cfg; char* args;} menu_def_t;static struct MPContext *menu_ctx = NULL;static menu_def_t* menu_list = NULL;static int menu_count = 0;static int menu_parse_config(char* buffer) { char *element,*body, **attribs, *name; menu_info_t* minfo = NULL; int r,i; ASX_Parser_t* parser = asx_parser_new(); while(1) { r = asx_get_element(parser,&buffer,&element,&body,&attribs); if(r < 0) { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_SyntaxErrorAtLine,parser->line); asx_parser_free(parser); return 0; } else if(r == 0) { asx_parser_free(parser); return 1; } // Has it a name ? name = asx_get_attrib("name",attribs); if(!name) { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuDefinitionsNeedANameAttrib,parser->line); free(element); if(body) free(body); asx_free_attribs(attribs); 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) { minfo = menu_info_list[i]; break; } } // Got it : add this to our list if(minfo) { menu_list = realloc(menu_list,(menu_count+2)*sizeof(menu_def_t)); menu_list[menu_count].name = name; menu_list[menu_count].type = minfo; menu_list[menu_count].cfg = m_struct_alloc(&minfo->priv_st); menu_list[menu_count].args = body; // Setup the attribs for(i = 0 ; attribs[2*i] ; i++) { if(strcasecmp(attribs[2*i],"name") == 0) continue; if(!m_struct_set(&minfo->priv_st,menu_list[menu_count].cfg,attribs[2*i], attribs[2*i+1])) mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_BadAttrib,attribs[2*i],attribs[2*i+1], name,parser->line); } menu_count++; memset(&menu_list[menu_count],0,sizeof(menu_def_t)); } else { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_UnknownMenuType,element,parser->line); free(name); if(body) free(body); } free(element); asx_free_attribs(attribs); }} /// This will build the menu_defs list from the cfg file#define BUF_STEP 1024#define BUF_MIN 128#define BUF_MAX BUF_STEP*1024int menu_init(struct MPContext *mpctx, char* cfg_file) { char* buffer = NULL; int bl = BUF_STEP, br = 0; int f, fd;#ifndef HAVE_FREETYPE if(vo_font == NULL) return 0;#endif fd = open(cfg_file, O_RDONLY); if(fd < 0) { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_CantOpenConfigFile,cfg_file); return 0; } buffer = malloc(bl); while(1) { int r; if(bl - br < BUF_MIN) { if(bl >= BUF_MAX) { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_ConfigFileIsTooBig,BUF_MAX/1024); close(fd); free(buffer); return 0; } bl += BUF_STEP; buffer = realloc(buffer,bl); } r = read(fd,buffer+br,bl-br); if(r == 0) break; br += r; } if(!br) { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_ConfigFileIsEmpty); return 0; } buffer[br-1] = '\0'; close(fd); menu_ctx = mpctx; f = menu_parse_config(buffer); free(buffer); return f;}// Destroy all this stuffvoid menu_unint(void) { int i; for(i = 0 ; menu_list && menu_list[i].name ; i++) { free(menu_list[i].name); m_struct_free(&menu_list[i].type->priv_st,menu_list[i].cfg); if(menu_list[i].args) free(menu_list[i].args); } free(menu_list); menu_count = 0;}/// Default read_key functionvoid 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; }}menu_t* menu_open(char *name) { menu_t* m; int i; for(i = 0 ; menu_list[i].name != NULL ; i++) { if(strcmp(name,menu_list[i].name) == 0) break; } if(menu_list[i].name == NULL) { mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuNotFound,name); return NULL; } m = calloc(1,sizeof(menu_t)); m->priv_st = &(menu_list[i].type->priv_st); m->priv = m_struct_copy(m->priv_st,menu_list[i].cfg); m->ctx = menu_ctx; if(menu_list[i].type->open(m,menu_list[i].args)) return m; if(m->priv) m_struct_free(m->priv_st,m->priv); free(m); mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuInitFailed,name); return NULL;}void menu_draw(menu_t* menu,mp_image_t* mpi) { if(menu->show && menu->draw) menu->draw(menu,mpi);}void menu_read_cmd(menu_t* menu,int cmd) { if(menu->read_cmd) menu->read_cmd(menu,cmd);}void menu_close(menu_t* menu) { if(menu->close) menu->close(menu); if(menu->priv) m_struct_free(menu->priv_st,menu->priv); free(menu);}void menu_read_key(menu_t* menu,int cmd) { if(menu->read_key) menu->read_key(menu,cmd); else menu_dflt_read_key(menu,cmd);}///////////////////////////// Helpers ////////////////////////////////////typedef void (*draw_alpha_f)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);inline static draw_alpha_f get_draw_alpha(uint32_t fmt) { switch(fmt) { case IMGFMT_BGR15: case IMGFMT_RGB15: return vo_draw_alpha_rgb15; case IMGFMT_BGR16: case IMGFMT_RGB16: return vo_draw_alpha_rgb16; case IMGFMT_BGR24: case IMGFMT_RGB24: return vo_draw_alpha_rgb24; case IMGFMT_BGR32: case IMGFMT_RGB32: return vo_draw_alpha_rgb32; case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YVU9: case IMGFMT_IF09: case IMGFMT_Y800: case IMGFMT_Y8: return vo_draw_alpha_yv12; case IMGFMT_YUY2: return vo_draw_alpha_yuy2; case IMGFMT_UYVY: return vo_draw_alpha_uyvy; } return NULL;}// return the real height of a char:static inline int get_height(int c,int h){ int font; if ((font=vo_font->font[c])>=0) if(h<vo_font->pic_a[font]->h) h=vo_font->pic_a[font]->h; return h;}static void render_txt(char *txt){ while (*txt) { int c = utf8_get_char(&txt); render_one_glyph(vo_font, c); }}#ifdef USE_FRIBIDI#include <fribidi/fribidi.h>#include "libavutil/common.h"char *menu_fribidi_charset = NULL;int menu_flip_hebrew = 0;int menu_fribidi_flip_commas = 0;static char *menu_fribidi(char *txt){ static int char_set_num = -1; static FriBidiChar *logical, *visual; static size_t buffer_size = 1024; static char *outputstr; FriBidiCharType base; fribidi_boolean log2vis; size_t len; if (menu_flip_hebrew) { len = strlen(txt); if (char_set_num == -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -