diff options
44 files changed, 726 insertions, 690 deletions
@@ -60,13 +60,8 @@ SRCS_COMMON-$(DVDREAD_INTERNAL) += libdvdread4/bitreader.c \ SRCS_COMMON-$(FAAD) += libmpcodecs/ad_faad.c SRCS_COMMON-$(FASTMEMCPY) += libvo/aclib.c -# Requires a new enough libavutil that installs eval.h -SRCS_COMMON-$(FFMPEG_EVAL_API) += libmpcodecs/vf_geq.c \ - libmpcodecs/vf_qp.c \ - # These filters use private headers and do not work with shared libavcodec. -SRCS_COMMON-$(FFMPEG_INTERNALS) += libmpcodecs/vf_fspp.c \ - libmpcodecs/vf_mcdeint.c \ +SRCS_COMMON-$(FFMPEG_INTERNALS) += libmpcodecs/vf_mcdeint.c \ libmpcodecs/vf_spp.c \ SRCS_COMMON-$(FREETYPE) += sub/font_load_ft.c @@ -316,6 +311,8 @@ SRCS_COMMON = asxparser.c \ libmpcodecs/vf_flip.c \ libmpcodecs/vf_format.c \ libmpcodecs/vf_framestep.c \ + libmpcodecs/vf_fspp.c \ + libmpcodecs/vf_geq.c \ libmpcodecs/vf_gradfun.c \ libmpcodecs/vf_halfpack.c \ libmpcodecs/vf_harddup.c \ @@ -337,6 +334,7 @@ SRCS_COMMON = asxparser.c \ libmpcodecs/vf_pp.c \ libmpcodecs/vf_pp7.c \ libmpcodecs/vf_pullup.c \ + libmpcodecs/vf_qp.c \ libmpcodecs/vf_rectangle.c \ libmpcodecs/vf_remove_logo.c \ libmpcodecs/vf_rgbtest.c \ diff --git a/access_mpcontext.h b/access_mpcontext.h deleted file mode 100644 index 4b866f255f..0000000000 --- a/access_mpcontext.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_ACCESS_MPCONTEXT_H -#define MPLAYER_ACCESS_MPCONTEXT_H - -struct MPContext; -void *mpctx_get_video_out(struct MPContext *mpctx); -void *mpctx_get_demuxer(struct MPContext *mpctx); -void *mpctx_get_playtree_iter(struct MPContext *mpctx); -void *mpctx_get_mixer(struct MPContext *mpctx); -int mpctx_get_global_sub_size(struct MPContext *mpctx); -int mpctx_get_osd_function(struct MPContext *mpctx); - -#endif /* MPLAYER_ACCESS_MPCONTEXT_H */ @@ -201,3 +201,35 @@ int bstr_sscanf(struct bstr str, const char *format, ...) talloc_free(ptr); return ret; } + +int bstr_parse_utf8_code_length(unsigned char b) +{ + if (b < 128) + return 1; + int bytes = 7 - av_log2(b ^ 255); + return (bytes >= 2 && bytes <= 4) ? bytes : -1; +} + +int bstr_decode_utf8(struct bstr s, struct bstr *out_next) +{ + if (s.len == 0) + return -1; + unsigned int codepoint = s.start[0]; + s.start++; s.len--; + if (codepoint >= 128) { + int bytes = bstr_parse_utf8_code_length(codepoint); + if (bytes < 0 || s.len < bytes - 1) + return -1; + codepoint &= 127 >> bytes; + for (int n = 1; n < bytes; n++) { + int tmp = s.start[0]; + if ((tmp & 0xC0) != 0x80) + return -1; + codepoint = (codepoint << 6) | (tmp & ~0xC0); + s.start++; s.len--; + } + } + if (out_next) + *out_next = s; + return codepoint; +} @@ -69,6 +69,19 @@ double bstrtod(struct bstr str, struct bstr *rest); void bstr_lower(struct bstr str); int bstr_sscanf(struct bstr str, const char *format, ...); +// Decode the UTF-8 code point at the start of the string,, and return the +// character. +// After calling this function, *out_next will point to the next character. +// out_next can be NULL. +// On error, -1 is returned, and *out_next is not modified. +int bstr_decode_utf8(struct bstr str, struct bstr *out_next); + +// Return the length of the UTF-8 sequence that starts with the given byte. +// Given a string char *s, the next UTF-8 code point is to be expected at +// s + bstr_parse_utf8_code_length(s[0]) +// On error, -1 is returned. On success, it returns a value in the range [1, 4]. +int bstr_parse_utf8_code_length(unsigned char b); + static inline struct bstr bstr_cut(struct bstr str, int n) { if (n > str.len) diff --git a/cfg-mplayer.h b/cfg-mplayer.h index f09cd9edd3..342fbccd62 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -926,7 +926,6 @@ const m_option_t mplayer_opts[]={ OPT_FLAG_ON("list-properties", list_properties, CONF_GLOBAL), {"identify", &mp_msg_levels[MSGT_IDENTIFY], CONF_TYPE_FLAG, CONF_GLOBAL, 0, MSGL_V, NULL}, - {"-help", (void *) help_text, CONF_TYPE_PRINT, CONF_NOCFG|CONF_GLOBAL, 0, 0, NULL}, {"help", (void *) help_text, CONF_TYPE_PRINT, CONF_NOCFG|CONF_GLOBAL, 0, 0, NULL}, {"h", (void *) help_text, CONF_TYPE_PRINT, CONF_NOCFG|CONF_GLOBAL, 0, 0, NULL}, @@ -680,10 +680,8 @@ static int mp_property_pause(m_option_t *prop, int action, void *arg, case M_PROPERTY_STEP_DOWN: if (mpctx->paused) { unpause_player(mpctx); - mpctx->osd_function = OSD_PLAY; } else { pause_player(mpctx); - mpctx->osd_function = OSD_PAUSE; } return M_PROPERTY_OK; default: @@ -6003,27 +6003,21 @@ echores "$_live" -all_libav_libs="libavutil libavcodec libavformat libswscale libpostproc" +all_libav_libs="libavutil >= 51.7.0:libavcodec >= 53.5.0:libavformat >= 53.2.0:libswscale >= 2.0.0:libpostproc >= 52.0.0" echocheck "Libav ($all_libav_libs)" if test "$ffmpeg" = auto ; then + IFS=":" # shell should not be used for programming if $_pkg_config --exists --print-errors $all_libav_libs ; then inc_ffmpeg=$($_pkg_config --cflags $all_libav_libs) _ld_tmp=$($_pkg_config --libs $all_libav_libs) extra_ldflags="$extra_ldflags $_ld_tmp" extra_cflags="$extra_cflags $inc_ffmpeg" - elif header_check libavutil/avutil.h -lpostproc -lswscale -lavformat -lavcodec -lavutil $_ld_lm ; then - extra_ldflags="$extra_ldflags -lpostproc -lswscale -lavformat -lavcodec -lavutil" + unset IFS else die "Unable to find development files for some of the required Libav libraries above. Aborting." fi fi - -ffmpeg_eval_api=no -def_ffmpeg_eval_api="#undef CONFIG_FFMPEG_EVAL_API" -if $_pkg_config --atleast-version=50.33.0 libavutil ; then - ffmpeg_eval_api=yes - def_ffmpeg_eval_api="#define CONFIG_FFMPEG_EVAL_API 1" -fi +echores "yes" def_ffmpeg_internals="#undef CONFIG_FFMPEG_INTERNALS" if ! test -z "$_ffmpeg_source" ; then @@ -6790,7 +6784,6 @@ XVR100 = $_xvr100 YUV4MPEG = $_yuv4mpeg # FFmpeg -FFMPEG_EVAL_API = $ffmpeg_eval_api FFMPEG_INTERNALS = $ffmpeg_internals FFMPEG_SOURCE_PATH = $_ffmpeg_source @@ -7143,7 +7136,6 @@ $def_yuv4mpeg /* FFmpeg */ -$def_ffmpeg_eval_api $def_ffmpeg_internals $def_arpa_inet_h diff --git a/etc/input.conf b/etc/input.conf index 509f1bf876..b358d33243 100644 --- a/etc/input.conf +++ b/etc/input.conf @@ -1,62 +1,83 @@ -## -## MPlayer input control file -## -## You are able to redefine default keyboard/joystick/mouse/LIRC bindings, or -## add new ones here. -## See DOCS/tech/slave.txt for possible commands that can be bound. -## Also see mplayer -input cmdlist for other possible options. -## The file should be placed in the $HOME/.mplayer directory. -## -## If you wish to unbind a key, use key ignore. -## e.g. ENTER ignore -## -## You can use modifier-key combinations like Shift+Left or Ctrl+Alt+x with -## modifiers Shift, Ctrl, Alt and Meta, but note that currently reading -## key combinations is only supported through the video windows of X-based -## output drivers (not in output windows of other drivers or in a terminal). +# MPlayer input control file +# +# You are able to redefine default keyboard/joystick/mouse/LIRC bindings, or +# add new ones here. +# See DOCS/tech/slave.txt for possible commands that can be bound. +# Also see mplayer -input cmdlist for other possible options. +# The file should be placed in the $HOME/.mplayer directory. +# +# If you wish to unbind a key, use key ignore. +# e.g. ENTER ignore +# +# Note that merely removing default key bindings from this file won't remove +# the default bindings mplayer was compiled with, unless +# --input=nodefault-bindings +# is specified. +# +# Lines starting with # are comments. Use SHARP to assign the # key. +# +# Some characters need to be escaped. In particular, if you want to display +# a '\' character as part of an osd_show_property_text OSD message, you have to +# escape 2 times: +# key osd_show_property_text "This is a single backslash: \\\\!" +# +# You can use modifier-key combinations like Shift+Left or Ctrl+Alt+x with +# modifiers Shift, Ctrl, Alt and Meta, but note that currently reading +# key combinations is only supported through the video windows of X-based +# output drivers (not in output windows of other drivers or in a terminal). -RIGHT seek +10 +MOUSE_BTN0_DBL vo_fullscreen # toggle fullscreen on/off +MOUSE_BTN2 pause # toggle pause on/off +MOUSE_BTN3 seek 10 +MOUSE_BTN4 seek -10 +MOUSE_BTN5 volume 1 +MOUSE_BTN6 volume -1 + +# Seek units are in seconds, but note that these are mostly limited by keyframes +RIGHT seek 10 LEFT seek -10 +UP seek 60 DOWN seek -60 -UP seek +60 # Do smaller, always exact (non-keyframe-limited), seeks with shift. -Shift+Right seek +1 0 1 -Shift+Left seek -1 0 1 -Shift+Down seek -5 0 1 -Shift+Up seek +5 0 1 +Shift+RIGHT seek 1 0 1 +Shift+LEFT seek -1 0 1 +Shift+UP seek 5 0 1 +Shift+DOWN seek -5 0 1 PGUP seek 600 PGDWN seek -600 -m mute -# switch_audio # switch audio streams -+ audio_delay 0.100 -= audio_delay 0.100 ++ audio_delay 0.100 # this changes audio/video sync - audio_delay -0.100 -[ speed_mult 0.9091 # scale playback speed +[ speed_mult 0.9091 # scale playback speed ] speed_mult 1.1 { speed_mult 0.5 } speed_mult 2.0 -BS speed_set 1.0 # reset speed to normal +BS speed_set 1.0 # reset speed to normal q quit ESC quit -ENTER pt_step 1 1 # skip to next file -p pause -. frame_step # advance one frame and pause +p pause # toggle pause/playback mode +. frame_step # advance one frame and pause SPACE pause HOME pt_up_step 1 END pt_up_step -1 -> pt_step 1 # skip to next file -< pt_step -1 # previous +> pt_step 1 # skip to next file +ENTER pt_step 1 1 # skip to next file or quit +< pt_step -1 # skip to previous file INS alt_src_step 1 DEL alt_src_step -1 -o osd -I osd_show_property_text "${filename}" # display filename in osd +o osd # cycle through OSD mode +I osd_show_property_text "${filename}" # display filename in osd P osd_show_progression -z sub_delay -0.1 # subtract 100 ms delay from subs -x sub_delay +0.1 # add +z sub_delay -0.1 # subtract 100 ms delay from subs +x sub_delay +0.1 # add +g sub_step -1 # immediately display next subtitle +y sub_step +1 # previous 9 volume -1 / volume -1 0 volume 1 * volume 1 +( balance -0.1 # adjust audio balance in favor of left +) balance 0.1 # right +m mute 1 contrast -1 2 contrast 1 3 brightness -1 @@ -65,54 +86,77 @@ x sub_delay +0.1 # add 6 hue 1 7 saturation -1 8 saturation 1 -( balance -0.1 # adjust audio balance in favor of left -) balance +0.1 # right -d frame_drop -D step_property deinterlace # toggle deinterlacer, requires -vf yadif or kerndeint -r sub_pos -1 # move subtitles up -t sub_pos +1 # down -#? sub_step +1 # immediately display next subtitle -#? sub_step -1 # previous -#? sub_scale +0.1 # increase subtitle font size -#? sub_scale -0.1 # decrease subtitle font size -V step_property_osd ass_vsfilter_aspect_compat # stretch SSA/ASS subtitles with anamorphic videos to match historical VSFilter behavior -f vo_fullscreen -T vo_ontop # toggle video window ontop of other windows -w panscan -0.1 # zoom out with -panscan 0 -fs -e panscan +0.1 # in -s screenshot # take a png screenshot with -vf screenshot - # S will take a png screenshot of every frame +d frame_drop # cycle through framedrop modes +D step_property_osd deinterlace # toggle deinterlacer, requires -vf yadif or kerndeint +c step_property_osd colormatrix +# These currently only work with --no-ass +r sub_pos -1 # move subtitles up +t sub_pos +1 # down +a sub_alignment +v sub_visibility +# stretch SSA/ASS subtitles with anamorphic videos to match historical +V step_property_osd ass_vsfilter_aspect_compat +j sub_select # cycle through subtitles +J sub_select -3 # ...backwards +F forced_subs_only +SHARP switch_audio # switch audio streams +_ step_property switch_video +TAB step_property switch_program +i edl_mark # for use with --edlout mode +T vo_ontop # toggle video window ontop of other windows +f vo_fullscreen # toggle fullscreen +C step_property_osd capturing +s screenshot 0 # take a png screenshot with -vf screenshot +S screenshot 1 # ...on every frame +Alt+s screenshot 0 1 # take a screenshot of window contents +Alt+S screenshot 1 1 # ...on every frame +w panscan -0.1 # zoom out with -panscan 0 -fs +e panscan +0.1 # in +POWER quit +MENU osd +PLAY pause +PAUSE pause +PLAYPAUSE pause +STOP quit +FORWARD seek 60 +REWIND seek -60 +NEXT pt_step 1 +PREV pt_step -1 +VOLUME_UP volume 1 +VOLUME_DOWN volume -1 +MUTE mute +CLOSE_WIN quit +! seek_chapter -1 # skip to previous chapter +@ seek_chapter 1 # next +A switch_angle 1 +U stop +# TV h tv_step_channel 1 -l tv_step_channel -1 +k tv_step_channel -1 n tv_step_norm -b tv_step_chanlist +u tv_step_chanlist +X step_property teletext_mode 1 +W step_property teletext_page 1 +Q step_property teletext_page -1 -## -## Mouse section -## +# +# DVDNAV +# Requires dvdnav:// +# -MOUSE_BTN0_DBL vo_fullscreen # toggle fullscreen on/off -MOUSE_BTN2 pause # toggle pause on/off +KP8 dvdnav up +KP2 dvdnav down +KP4 dvdnav left +KP6 dvdnav right +KP5 dvdnav menu +KP_ENTER dvdnav select +MOUSE_BTN0 dvdnav mouse +KP7 dvdnav prev -## -## Joystick section -## WARNING: joystick support has to be explicitly enabled at -## compiletime with --enable-joystick -## - -JOY_RIGHT seek 10 -JOY_LEFT seek -10 -JOY_UP seek 60 -JOY_DOWN seek -60 -JOY_BTN0 pause -JOY_BTN1 osd -JOY_BTN2 volume 1 -JOY_BTN3 volume -1 - -## -## Apple Remote section -## +# +# Apple Remote section +# AR_PLAY pause AR_PLAY_HOLD quit @@ -120,29 +164,30 @@ AR_NEXT seek 30 AR_NEXT_HOLD seek 120 AR_PREV seek -10 AR_PREV_HOLD seek -120 +AR_MENU osd AR_MENU_HOLD mute AR_VUP volume 1 AR_VDOWN volume -1 -## -## DVDNAV -## Requires dvdnav:// -## +# +# Joystick section +# WARNING: joystick support has to be explicitly enabled at +# compiletime with --enable-joystick +# -UP {dvdnav} dvdnav up # DVDNav UP -DOWN {dvdnav} dvdnav down # DVDNav DOWN -LEFT {dvdnav} dvdnav left # DVDNav LEFT -RIGHT {dvdnav} dvdnav right # DVDNav RIGHT -ESC {dvdnav} dvdnav menu # DVDNav MENU -ENTER {dvdnav} dvdnav select # DVDNav SELECT (ok) -BS {dvdnav} dvdnav prev # DVDNav PREVIOUS menu (in the order chapter->title->root) +JOY_AXIS0_PLUS seek 10 +JOY_AXIS0_MINUS seek -10 +JOY_AXIS1_MINUS seek 60 +JOY_AXIS1_PLUS seek -60 +JOY_BTN0 pause +JOY_BTN1 osd +JOY_BTN2 volume 1 +JOY_BTN3 volume -1 -AR_VUP {dvdnav} dvdnav up # DVDNav UP -AR_VDOWN {dvdnav} dvdnav down # DVDNav DOWN -AR_PREV {dvdnav} dvdnav left # DVDNav LEFT -AR_NEXT {dvdnav} dvdnav right # DVDNav RIGHT -AR_MENU {dvdnav} dvdnav menu # DVDNav MENU -AR_PLAY {dvdnav} dvdnav select # DVDNav SELECT (ok) +# +# Not assigned by default +# (not an exhaustive list of unbound commands) +# -#? seek_chapter -1 # skip to previous dvd chapter -#? seek_chapter +1 # next +#? sub_scale +0.1 # increase subtitle font size +#? sub_scale -0.1 # decrease subtitle font size diff --git a/ffmpeg_files/taglists.c b/ffmpeg_files/taglists.c index 1596110907..ec414a35c1 100644 --- a/ffmpeg_files/taglists.c +++ b/ffmpeg_files/taglists.c @@ -181,9 +181,7 @@ const struct mp_AVCodecTag mp_ff_codec_bmp_tags[] = { { CODEC_ID_RAWVIDEO, MKTAG('Y', 'U', 'V', '9') }, { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', 'U', '9') }, { CODEC_ID_FRWU, MKTAG('F', 'R', 'W', 'U') }, -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 89, 0) { CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') }, -#endif { CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, { CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '1') }, @@ -260,9 +258,7 @@ const struct mp_AVCodecTag mp_ff_codec_bmp_tags[] = { { CODEC_ID_AURA2, MKTAG('A', 'U', 'R', '2') }, { CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') }, { CODEC_ID_KGV1, MKTAG('K', 'G', 'V', '1') }, -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 108, 0) { CODEC_ID_LAGARITH, MKTAG('L', 'A', 'G', 'S') }, -#endif { CODEC_ID_NONE, 0 } }; @@ -299,15 +295,11 @@ const struct mp_AVCodecTag mp_ff_codec_wav_tags[] = { { CODEC_ID_WMALOSSLESS, 0x0163 }, { CODEC_ID_ADPCM_CT, 0x0200 }, { CODEC_ID_ATRAC3, 0x0270 }, -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 88, 0) { CODEC_ID_ADPCM_G722, 0x028F }, -#endif { CODEC_ID_IMC, 0x0401 }, { CODEC_ID_GSM_MS, 0x1500 }, { CODEC_ID_TRUESPEECH, 0x1501 }, -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 94, 0) { CODEC_ID_AAC_LATM, 0x1602 }, -#endif { CODEC_ID_AC3, 0x2000 }, { CODEC_ID_DTS, 0x2001 }, { CODEC_ID_SONIC, 0x2048 }, diff --git a/fmt-conversion.c b/fmt-conversion.c index 2adc115a4e..6ab6a4b82f 100644 --- a/fmt-conversion.c +++ b/fmt-conversion.c @@ -75,20 +75,16 @@ static const struct { {IMGFMT_420P16_LE, PIX_FMT_YUV420P16LE}, {IMGFMT_420P16_BE, PIX_FMT_YUV420P16BE}, -#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 2, 0) {IMGFMT_420P9_LE, PIX_FMT_YUV420P9LE}, {IMGFMT_420P9_BE, PIX_FMT_YUV420P9BE}, {IMGFMT_420P10_LE, PIX_FMT_YUV420P10LE}, {IMGFMT_420P10_BE, PIX_FMT_YUV420P10BE}, {IMGFMT_422P10_LE, PIX_FMT_YUV422P10LE}, {IMGFMT_422P10_BE, PIX_FMT_YUV422P10BE}, -#endif -#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 7, 0) {IMGFMT_444P9_BE , PIX_FMT_YUV444P9BE}, {IMGFMT_444P9_LE , PIX_FMT_YUV444P9LE}, {IMGFMT_444P10_BE, PIX_FMT_YUV444P10BE}, {IMGFMT_444P10_LE, PIX_FMT_YUV444P10LE}, -#endif {IMGFMT_422P16_LE, PIX_FMT_YUV422P16LE}, {IMGFMT_422P16_BE, PIX_FMT_YUV422P16BE}, {IMGFMT_444P16_LE, PIX_FMT_YUV444P16LE}, @@ -134,13 +130,9 @@ int pixfmt2imgfmt(enum PixelFormat pix_fmt) break; int fmt = conversion_map[i].fmt; if (!fmt) { -#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 2, 0) const char *fmtname = av_get_pix_fmt_name(pix_fmt); mp_msg(MSGT_GLOBAL, MSGL_ERR, "Unsupported PixelFormat %s (%d)\n", fmtname ? fmtname : "INVALID", pix_fmt); -#else - mp_msg(MSGT_GLOBAL, MSGL_ERR, "Unsupported PixelFormat %i\n", pix_fmt); -#endif } return fmt; } diff --git a/input/input.c b/input/input.c index e1c001077a..d9c95238d1 100644 --- a/input/input.c +++ b/input/input.c @@ -36,6 +36,7 @@ #include "keycodes.h" #include "osdep/timer.h" #include "libavutil/avstring.h" +#include "libavutil/common.h" #include "mp_msg.h" #include "m_config.h" #include "m_option.h" @@ -228,6 +229,7 @@ static const struct key_name key_names[] = { { KEY_PAGE_UP, "PGUP" }, { KEY_PAGE_DOWN, "PGDWN" }, { KEY_ESC, "ESC" }, + { KEY_PRINT, "PRINT" }, { KEY_RIGHT, "RIGHT" }, { KEY_LEFT, "LEFT" }, { KEY_DOWN, "DOWN" }, @@ -571,9 +573,6 @@ struct cmd_bind_section { struct cmd_queue { struct mp_cmd *first; - struct mp_cmd *last; - int num_cmds; - int num_abort_cmds; }; struct input_ctx { @@ -647,6 +646,17 @@ static const m_option_t mp_input_opts[] = { static int default_cmd_func(int fd, char *buf, int l); +// Encode the unicode codepoint as UTF-8, and append to the end of the +// talloc'ed buffer. +static char *append_utf8_buffer(char *buffer, uint32_t codepoint) +{ + char data[8]; + uint8_t tmp; + char *output = data; + PUT_UTF8(codepoint, tmp, *output++ = tmp;); + return talloc_strndup_append_buffer(buffer, data, output - data); +} + static char *get_key_name(int key, char *ret) { for (int i = 0; modifier_names[i].name; i++) { @@ -661,8 +671,9 @@ static char *get_key_name(int key, char *ret) return talloc_asprintf_append_buffer(ret, "%s", key_names[i].name); } - if (isascii(key)) - return talloc_asprintf_append_buffer(ret, "%c", key); + // printable, and valid unicode range + if (key >= 32 && key <= 0x10FFFF) + return append_utf8_buffer(ret, key); // Print the hex key code return talloc_asprintf_append_buffer(ret, "%#-8x", key); @@ -693,32 +704,52 @@ static bool is_abort_cmd(int cmd_id) return false; } +static int queue_count_cmds(struct cmd_queue *queue) +{ + int res = 0; + for (struct mp_cmd *cmd = queue->first; cmd; cmd = cmd->queue_next) + res++; + return res; +} + +static bool queue_has_abort_cmds(struct cmd_queue *queue) +{ + for (struct mp_cmd *cmd = queue->first; cmd; cmd = cmd->queue_next) { + if (is_abort_cmd(cmd->id)) + return true; + } + return false; +} + +static void queue_remove(struct cmd_queue *queue, struct mp_cmd *cmd) +{ + struct mp_cmd **p_prev = &queue->first; + while (*p_prev != cmd) { + p_prev = &(*p_prev)->q |