summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@mplayer2.org>2012-01-18 04:19:24 +0100
committerwm4 <wm4@mplayer2.org>2012-01-18 04:19:24 +0100
commit064f8c2fb656462db9662c67bdbc6716958a4de4 (patch)
tree28e2bc410b80f246629053661eeb77cfd7cfeeb2
parentf341b21a90d27977562645fb80f0cbbc2a17af7b (diff)
parent54ed2eeed394e4908e2848146543f27bc787fc63 (diff)
downloadmpv-064f8c2fb656462db9662c67bdbc6716958a4de4.tar.bz2
mpv-064f8c2fb656462db9662c67bdbc6716958a4de4.tar.xz
Merge branch 'utf8_input' into my_master
-rw-r--r--bstr.c32
-rw-r--r--bstr.h13
-rw-r--r--etc/input.conf241
-rw-r--r--input/input.c33
-rw-r--r--input/keycodes.h39
-rw-r--r--libvo/wskeys.h85
-rw-r--r--libvo/x11_common.c115
-rw-r--r--libvo/x11_common.h3
-rw-r--r--mp_fifo.c10
-rw-r--r--mp_fifo.h3
-rw-r--r--osdep/getch2.c12
11 files changed, 327 insertions, 259 deletions
diff --git a/bstr.c b/bstr.c
index 219c136d7c..0c46b1d9b0 100644
--- a/bstr.c
+++ b/bstr.c
@@ -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;
+}
diff --git a/bstr.h b/bstr.h
index 1344f0d443..8b1644cac0 100644
--- a/bstr.h
+++ b/bstr.h
@@ -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/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/input/input.c b/input/input.c
index f97487c1f7..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" },
@@ -644,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++) {
@@ -658,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);
@@ -1188,7 +1202,7 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code)
* shift modifier is still kept for special keys like arrow keys.
*/
int unmod = code & ~KEY_MODIFIER_MASK;
- if (unmod < 256 && unmod != KEY_ENTER && unmod != KEY_TAB)
+ if (unmod >= 32 && unmod < MP_KEY_BASE)
code &= ~KEY_MODIFIER_SHIFT;
if (code & MP_KEY_DOWN) {
@@ -1506,10 +1520,15 @@ int mp_input_get_key_from_name(const char *name)
found:
name = p + 1;
}
- int len = strlen(name);
- if (len == 1) // Direct key code
- return (unsigned char)name[0] + modifiers;
- else if (len > 2 && strncasecmp("0x", name, 2) == 0)
+
+ struct bstr bname = bstr(name);
+
+ struct bstr rest;
+ int code = bstr_decode_utf8(bname, &rest);
+ if (code >= 0 && rest.len == 0)
+ return code + modifiers;
+
+ if (bstr_startswith0(bname, "0x"))
return strtol(name, NULL, 16) + modifiers;
for (int i = 0; key_names[i].name != NULL; i++) {
diff --git a/input/keycodes.h b/input/keycodes.h
index 45e7ec7d4b..84b41a3e89 100644
--- a/input/keycodes.h
+++ b/input/keycodes.h
@@ -21,19 +21,16 @@
#ifndef MPLAYER_KEYCODES_H
#define MPLAYER_KEYCODES_H
+#define MP_KEY_BASE (1<<21)
+
// For appleir.c which includes another header with KEY_ENTER etc defines
#ifndef AR_DEFINES_ONLY
#define KEY_ENTER 13
#define KEY_TAB 9
-#define KEY_BASE 0x100
-
-/* Function keys */
-#define KEY_F (KEY_BASE+64)
-
/* Control keys */
-#define KEY_CTRL (KEY_BASE)
+#define KEY_CTRL (MP_KEY_BASE)
#define KEY_BACKSPACE (KEY_CTRL+0)
#define KEY_DELETE (KEY_CTRL+1)
#define KEY_INSERT (KEY_CTRL+2)
@@ -42,6 +39,7 @@
#define KEY_PAGE_UP (KEY_CTRL+5)
#define KEY_PAGE_DOWN (KEY_CTRL+6)
#define KEY_ESC (KEY_CTRL+7)
+#define KEY_PRINT (KEY_CTRL+8)
/* Control keys short name */
#define KEY_BS KEY_BACKSPACE
@@ -52,14 +50,14 @@
#define KEY_PGDWN KEY_PAGE_DOWN
/* Cursor movement */
-#define KEY_CRSR (KEY_BASE+16)
+#define KEY_CRSR (MP_KEY_BASE+0x10)
#define KEY_RIGHT (KEY_CRSR+0)
#define KEY_LEFT (KEY_CRSR+1)
#define KEY_DOWN (KEY_CRSR+2)
#define KEY_UP (KEY_CRSR+3)
/* Multimedia keyboard/remote keys */
-#define KEY_MM_BASE (0x100+384)
+#define KEY_MM_BASE (MP_KEY_BASE+0x20)
#define KEY_POWER (KEY_MM_BASE+0)
#define KEY_MENU (KEY_MM_BASE+1)
#define KEY_PLAY (KEY_MM_BASE+2)
@@ -74,8 +72,11 @@
#define KEY_VOLUME_DOWN (KEY_MM_BASE+11)
#define KEY_MUTE (KEY_MM_BASE+12)
+/* Function keys */
+#define KEY_F (MP_KEY_BASE+0x40)
+
/* Keypad keys */
-#define KEY_KEYPAD (KEY_BASE+32)
+#define KEY_KEYPAD (MP_KEY_BASE+0x60)
#define KEY_KP0 (KEY_KEYPAD+0)
#define KEY_KP1 (KEY_KEYPAD+1)
#define KEY_KP2 (KEY_KEYPAD+2)
@@ -93,7 +94,7 @@
// Joystick input module
-#define JOY_BASE (0x100+128)
+#define JOY_BASE (MP_KEY_BASE+0x70)
#define JOY_AXIS0_PLUS (JOY_BASE+0)
#define JOY_AXIS0_MINUS (JOY_BASE+1)
#define JOY_AXIS1_PLUS (JOY_BASE+2)
@@ -115,7 +116,7 @@
#define JOY_AXIS9_PLUS (JOY_BASE+18)
#define JOY_AXIS9_MINUS (JOY_BASE+19)
-#define JOY_BTN_BASE ((0x100+148)|MP_NO_REPEAT_KEY)
+#define JOY_BTN_BASE ((MP_KEY_BASE+0x90)|MP_NO_REPEAT_KEY)
#define JOY_BTN0 (JOY_BTN_BASE+0)
#define JOY_BTN1 (JOY_BTN_BASE+1)
#define JOY_BTN2 (JOY_BTN_BASE+2)
@@ -129,7 +130,7 @@
// Mouse events from VOs
-#define MOUSE_BASE ((0x100+256)|MP_NO_REPEAT_KEY)
+#define MOUSE_BASE ((MP_KEY_BASE+0xA0)|MP_NO_REPEAT_KEY)
#define MOUSE_BTN0 (MOUSE_BASE+0)
#define MOUSE_BTN1 (MOUSE_BASE+1)
#define MOUSE_BTN2 (MOUSE_BASE+2)
@@ -152,7 +153,7 @@
#define MOUSE_BTN19 (MOUSE_BASE+19)
#define MOUSE_BTN_END (MOUSE_BASE+20)
-#define MOUSE_BASE_DBL (0x300|MP_NO_REPEAT_KEY)
+#define MOUSE_BASE_DBL ((MP_KEY_BASE+0xC0)|MP_NO_REPEAT_KEY)
#define MOUSE_BTN0_DBL (MOUSE_BASE_DBL+0)
#define MOUSE_BTN1_DBL (MOUSE_BASE_DBL+1)
#define MOUSE_BTN2_DBL (MOUSE_BASE_DBL+2)
@@ -179,7 +180,7 @@
#endif // AR_DEFINES_ONLY
// Apple Remote input module
-#define AR_BASE 0x500
+#define AR_BASE (MP_KEY_BASE+0xE0)
#define AR_PLAY (AR_BASE + 0)
#define AR_PLAY_HOLD (AR_BASE + 1)
#define AR_NEXT (AR_BASE + 2)
@@ -195,14 +196,14 @@
/* Special keys */
-#define KEY_INTERN (0x1000)
+#define KEY_INTERN (MP_KEY_BASE+0x1000)
#define KEY_CLOSE_WIN (KEY_INTERN+0)
/* Modifiers added to individual keys */
-#define KEY_MODIFIER_SHIFT 0x2000
-#define KEY_MODIFIER_CTRL 0x4000
-#define KEY_MODIFIER_ALT 0x8000
-#define KEY_MODIFIER_META 0x10000
+#define KEY_MODIFIER_SHIFT (1<<22)
+#define KEY_MODIFIER_CTRL (1<<23)
+#define KEY_MODIFIER_ALT (1<<24)
+#define KEY_MODIFIER_META (1<<25)
#endif // AR_DEFINES_ONLY
diff --git a/libvo/wskeys.h b/libvo/wskeys.h
deleted file mode 100644
index a236a9fd55..0000000000
--- a/libvo/wskeys.h
+++ /dev/null
@@ -1,85 +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_WSKEYS_H
-#define MPLAYER_WSKEYS_H
-
-#define wsPause 0xff13
-#define wsUp 0xff52
-#define wsDown 0xff54
-#define wsLeft 0xff51
-#define wsRight 0xff53
-#define wsLeftCtrl 0xffe3
-#define wsRightCtrl 0xffe4
-#define wsLeftAlt 0xffe9
-#define wsRightAlt 0xff7e
-#define wsLeftShift 0xffe1
-#define wsRightShift 0xffe2
-#define wsEnter 0xff0d
-#define wsBackSpace 0xff08
-#define wsCapsLock 0xffe5
-#define wsTab 0xff09
-#define wsF1 0xffbe
-#define wsF2 0xffbf
-#define wsF3 0xffc0
-#define wsF4 0xffc1
-#define wsF5 0xffc2
-#define wsF6 0xffc3
-#define wsF7 0xffc4
-#define wsF8 0xffc5
-#define wsF9 0xffc6
-#define wsF10 0xffc7
-#define wsF11 0xffc8
-#define wsF12 0xffc9
-#define wsInsert 0xff63
-#define wsDelete 0xffff
-#define wsHome 0xff50
-#define wsEnd 0xff57
-#define wsPageUp 0xff55
-#define wsPageDown 0xff56
-#define wsNumLock 0xff7f
-#define wsEscape 0xff1b
-#define wsGrayEnter 0xff8d
-#define wsGrayPlus 0xffab
-#define wsGrayMinus 0xffad
-#define wsGrayMul 0xffaa
-#define wsGrayDiv 0xffaf
-#define wsGrayDecimal 0xffae
-#define wsGray0 0xffb0
-#define wsGray1 0xffb1
-#define wsGray2 0xffb2
-#define wsGray3 0xffb3
-#define wsGray4 0xffb4
-#define wsGray5 0xffb5
-#define wsGray6 0xffb6
-#define wsGray7 0xffb7
-#define wsGray8 0xffb8
-#define wsGray9 0xffb9
-#define wsGrayHome 0xff95
-#define wsGrayLeft 0xff96
-#define wsGrayUp 0xff97
-#define wsGrayRight 0xff98
-#define wsGrayDown 0xff99
-#define wsGrayPgUp 0xff9a
-#define wsGrayPgDn 0xff9b
-#define wsGrayEnd 0xff9c
-#define wsGray5Dup 0xff9d
-#define wsGrayInsert 0xff9e
-#define wsGrayDelete 0xff9f
-
-#endif /* MPLAYER_WSKEYS_H */
diff --git a/libvo/x11_common.c b/libvo/x11_common.c
index e33b3c7ff6..a233b7f8e2 100644
--- a/libvo/x11_common.c
+++ b/libvo/x11_common.c
@@ -23,6 +23,7 @@
#include <limits.h>
#include "config.h"
+#include "bstr.h"
#include "options.h"
#include "mp_msg.h"
#include "mp_fifo.h"
@@ -45,6 +46,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
+#include <X11/keysymdef.h>
#ifdef CONFIG_XSS
#include <X11/extensions/scrnsaver.h>
@@ -422,6 +424,8 @@ int vo_init(struct vo *vo)
x11->screen = DefaultScreen(x11->display); // screen ID
x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID
+ x11->xim = XOpenIM(x11->display, NULL, NULL, NULL);
+
init_atoms(vo->x11);
#ifdef CONFIG_XF86VM
@@ -523,6 +527,8 @@ void vo_uninit(struct vo_x11_state *x11)
"vo: x11 uninit called but X11 not initialized..\n");
} else {
mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n");
+ if (x11->xim)
+ XCloseIM(x11->xim);
XSetErrorHandler(NULL);
XCloseDisplay(x11->display);
x11->depthonscreen = 0;
@@ -531,63 +537,52 @@ void vo_uninit(struct vo_x11_state *x11)
talloc_free(x11);
}
-#include "wskeys.h"
-
-#ifdef XF86XK_AudioPause
-static const struct mp_keymap keysym_map[] = {
- {XF86XK_MenuKB, KEY_MENU},
- {XF86XK_AudioPlay, KEY_PLAY}, {XF86XK_AudioPause, KEY_PAUSE}, {XF86XK_AudioStop, KEY_STOP},
- {XF86XK_AudioPrev, KEY_PREV}, {XF86XK_AudioNext, KEY_NEXT},
- {XF86XK_AudioMute, KEY_MUTE}, {XF86XK_AudioLowerVolume, KEY_VOLUME_DOWN}, {XF86XK_AudioRaiseVolume, KEY_VOLUME_UP},
- {0, 0}
-};
-
-static void vo_x11_putkey_ext(struct vo *vo, int keysym, int modifiers)
-{
- struct mp_fifo *f = vo->key_fifo;
- int mpkey = lookup_keymap_table(keysym_map, keysym);
- if (mpkey)
- mplayer_put_key(f, mpkey + modifiers);
-}
-#endif
-
static const struct mp_keymap keymap[] = {
// special keys
- {wsPause, KEY_PAUSE}, {wsEscape, KEY_ESC}, {wsBackSpace, KEY_BS},
- {wsTab, KEY_TAB}, {wsEnter, KEY_ENTER},
+ {XK_Pause, KEY_PAUSE}, {XK_Escape, KEY_ESC}, {XK_BackSpace, KEY_BS},
+ {XK_Tab, KEY_TAB}, {XK_Return, KEY_ENTER},
+ {XK_Menu, KEY_MENU}, {XK_Print, KEY_PRINT},
// cursor keys
- {wsLeft, KEY_LEFT}, {wsRight, KEY_RIGHT}, {wsUp, KEY_UP}, {wsDown, KEY_DOWN},
+ {XK_Left, KEY_LEFT}, {XK_Right, KEY_RIGHT}, {XK_Up, KEY_UP}, {XK_Down, KEY_DOWN},
// navigation block
- {wsInsert, KEY_INSERT}, {wsDelete, KEY_DELETE}, {wsHome, KEY_HOME}, {wsEnd, KEY_END},
- {wsPageUp, KEY_PAGE_UP}, {wsPageDown, KEY_PAGE_DOWN},
+ {XK_Insert, KEY_INSERT}, {XK_Delete, KEY_DELETE}, {XK_Home, KEY_HOME}, {XK_End, KEY_END},
+ {XK_Page_Up, KEY_PAGE_UP}, {XK_Page_Down, KEY_PAGE_DOWN},
// F-keys
- {wsF1, KEY_F+1}, {wsF2, KEY_F+2}, {wsF3, KEY_F+3}, {wsF4, KEY_F+4},
- {wsF5, KEY_F+5}, {wsF6, KEY_F+6}, {wsF7, KEY_F+7}, {wsF8, KEY_F+8},
- {wsF9, KEY_F+9}, {wsF10, KEY_F+10}, {wsF11, KEY_F+11}, {wsF12, KEY_F+12},
+ {XK_F1, KEY_F+1}, {XK_F2, KEY_F+2}, {XK_F3, KEY_F+3}, {XK_F4, KEY_F+4},
+ {XK_F5, KEY_F+5}, {XK_F6, KEY_F+6}, {XK_F7, KEY_F+7}, {XK_F8, KEY_F+8},
+ {XK_F9, KEY_F+9}, {XK_F10, KEY_F+10}, {XK_F11, KEY_F+11}, {XK_F12, KEY_F+12},
// numpad independent of numlock
- {wsGrayMinus, '-'}, {wsGrayPlus, '+'}, {wsGrayMul, '*'}, {wsGrayDiv, '/'},
- {wsGrayEnter, KEY_KPENTER},
+ {XK_KP_Subtract, '-'}, {XK_KP_Add, '+'}, {XK_KP_Multiply, '*'}, {XK_KP_Divide, '/'},
+ {XK_KP_Enter, KEY_KPENTER},
// numpad with numlock
- {wsGray0, KEY_KP0}, {wsGray1, KEY_KP1}, {wsGray2, KEY_KP2},
- {wsGray3, KEY_KP3}, {wsGray4, KEY_KP4}, {wsGray5, KEY_KP5},
- {wsGray6, KEY_KP6}, {wsGray7, KEY_KP7}, {wsGray8, KEY_KP8},
- {wsGray9, KEY_KP9}, {wsGrayDecimal, KEY_KPDEC},
+ {XK_KP_0, KEY_KP0}, {XK_KP_1, KEY_KP1}, {XK_KP_2, KEY_KP2},
+ {XK_KP_3, KEY_KP3}, {XK_KP_4, KEY_KP4}, {XK_KP_5, KEY_KP5},
+ {XK_KP_6, KEY_KP6}, {XK_KP_7, KEY_KP7}, {XK_KP_8, KEY_KP8},
+ {XK_KP_9, KEY_KP9}, {XK_KP_Decimal, KEY_KPDEC},
+ {XK_KP_Separator, KEY_KPDEC},
// numpad without numlock
- {wsGrayInsert, KEY_KPINS}, {wsGrayEnd, KEY_KP1}, {wsGrayDown, KEY_KP2},
- {wsGrayPgDn, KEY_KP3}, {wsGrayLeft, KEY_KP4}, {wsGray5Dup, KEY_KP5},
- {wsGrayRight, KEY_KP6}, {wsGrayHome, KEY_KP7}, {wsGrayUp, KEY_KP8},
- {wsGrayPgUp, KEY_KP9}, {wsGrayDelete, KEY_KPDEL},
+ {XK_KP_Insert, KEY_KPINS}, {XK_KP_End, KEY_KP1}, {XK_KP_Down, KEY_KP2},
+ {XK_KP_Page_Down, KEY_KP3}, {XK_KP_Left, KEY_KP4}, {XK_KP_Begin, KEY_KP5},
+ {XK_KP_Right, KEY_KP6}, {XK_KP_Home, KEY_KP7}, {XK_KP_Up, KEY_KP8},
+ {XK_KP_Page_Up, KEY_KP9}, {XK_KP_Delete, KEY_KPDEL},
+
+#ifdef XF86XK_AudioPause
+ {XF86XK_MenuKB, KEY_MENU},
+ {XF86XK_AudioPlay, KEY_PLAY}, {XF86XK_AudioPause, KEY_PAUSE}, {XF86XK_AudioStop, KEY_STOP},
+ {XF86XK_AudioPrev, KEY_PREV}, {XF86XK_AudioNext, KEY_NEXT},
+ {XF86XK_AudioMute, KEY_MUTE}, {XF86XK_AudioLowerVolume, KEY_VOLUME_DOWN}, {XF86XK_AudioRaiseVolume, KEY_VOLUME_UP},
+#endif
{0, 0}
};
-static void vo_x11_putkey(struct vo *vo, int key, int modifiers)
+static int vo_x11_lookupkey(int key)
{
static const char *passthrough_keys = " -+*/<>`~!@#$%^&()_{}:;\"\',.?\\|=[]";
int mpkey = 0;
@@ -600,8 +595,7 @@ static void vo_x11_putkey(struct vo *vo, int key, int modifiers)
if (!mpkey)
mpkey = lookup_keymap_table(keymap, key);
- if (mpkey)
- mplayer_put_key(vo->key_fifo, mpkey + modifiers);
+ return mpkey;
}
@@ -746,6 +740,9 @@ void vo_x11_uninit(struct vo *vo)
{
XEvent xev;
+ if (x11->xic)
+ XDestroyIC(x11->xic);
+
XUnmapWindow(x11->display, x11->window);
XSelectInput(x11->display, x11->window, StructureNotifyMask);
XDestroyWindow(x11->display, x11->window);
@@ -785,8 +782,6 @@ int vo_x11_check_events(struct vo *vo)
Display *display = vo->x11->display;
int ret = 0;
XEvent Event;
- char buf[100];
- KeySym keySym;
if (x11->vo_mouse_autohide && x11->mouse_waiting_hide &&
(GetTimerMS() - x11->mouse_timer >= 1000)) {
@@ -812,8 +807,8 @@ int vo_x11_check_events(struct vo *vo)
break;
case KeyPress:
{
- XLookupString(&Event.xkey, buf, sizeof(buf), &keySym,
- &x11->compose_status);
+ char buf[100];
+ KeySym keySym = 0;
int modifiers = 0;
if (Event.xkey.state & ShiftMask)
modifiers |= KEY_MODIFIER_SHIFT;
@@ -823,10 +818,27 @@ int vo_x11_check_events(struct vo *vo)
modifiers |= KEY_MODIFIER_ALT;
if (Event.xkey.state & Mod4Mask)
modifiers |= KEY_MODIFIER_META;
-#ifdef XF86XK_AudioPause
- vo_x11_putkey_ext(vo, keySym, modifiers);
-#endif
- vo_x11_putkey(vo, keySym, modifiers);
+ if (x11->xic) {
+ Status status;
+ int len = Xutf8LookupString(x11->xic, &Event.xkey, buf,
+ sizeof(buf), &keySym,
+ &status);
+ int mpkey = vo_x11_lookupkey(keySym);
+ if (mpkey) {
+ mplayer_put_key(vo->key_fifo, mpkey | modifiers);
+ } else if (status == XLookupChars
+ || status == XLookupBoth)
+ {
+ struct bstr t = { buf, len };
+ mplayer_put_key_utf8(vo->key_fifo, modifiers, t);
+ }
+ } else {
+ XLookupString(&Event.xkey, buf, sizeof(buf), &keySym,
+ &x11->compose_status);
+ int mpkey = vo_x11_lookupkey(keySym);
+ if (mpkey)
+ mplayer_put_key(vo->key_fifo, mpkey | modifiers);
+ }
ret |= VO_EVENT_KEYPRESS;
}
break;
@@ -1128,6 +1140,11 @@ void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y,
XSetWMNormalHints(mDisplay, x11->window, &hint);
if (!vo_border) vo_x11_decoration(vo, 0);
// map window
+ x11->xic = XCreateIC(x11->xim,
+ XNInputStyle, XIMPreeditNone | XIMStatusNone,
+ XNClientWindow, x11->window,
+ XNFocusWindow, x11->window,
+ NULL);
XSelectInput(mDisplay, x11->window, NoEventMask);
vo_x11_selectinput_witherr(mDisplay, x11->window,
StructureNotifyMask | KeyPressMask | PointerMotionMask |
diff --git a/libvo/x11_common.h b/libvo/x11_common.h
index a8b13cc690..6ba2780747 100644
--- a/libvo/x11_common.h
+++ b/libvo/x11_common.h
@@ -36,6 +36,9 @@ struct vo_x11_state {
int display_is_local;
int depthonscreen;
+ XIM xim;
+ XIC xic;
+
GC vo_gc;
struct xv_ck_info_s {
diff --git a/mp_fifo.c b/mp_fifo.c
index ffb3608fbf..701b7a0bc3 100644
--- a/mp_fifo.c
+++ b/mp_fifo.c
@@ -67,3 +67,13 @@ void mplayer_put_key(struct mp_fifo *fifo, int code)
fifo->last_down_time = now;
}
}
+
+void mplayer_put_key_utf8(struct mp_fifo *fifo, int mods, struct bstr t)
+{
+ while (t.len) {
+ int code = bstr_decode_utf8(t, &t);
+ if (code < 0)
+ break;
+ mplayer_put_key(fifo, code | mods);
+ }
+}
diff --git a/mp_fifo.h b/mp_fifo.h
index 01c1fb0c37..aa7fde0f29 100644
--- a/mp_fifo.h
+++ b/mp_fifo.h
@@ -19,8 +19,11 @@
#ifndef MPLAYER_MP_FIFO_H
#define MPLAYER_MP_FIFO_H
+#include "bstr.h"
+
struct mp_fifo;
void mplayer_put_key(struct mp_fifo *fifo, int code);
+void mplayer_put_key_utf8(struct mp_fifo *fifo, int mods, struct bstr code);
// Can be freed with talloc_free()
struct input_ctx;
struct MPOpts;
diff --git a/osdep/getch2.c b/osdep/getch2.c
index 81d13d9d7b..1eb78070c0 100644
--- a/osdep/getch2.c
+++ b/osdep/getch2.c
@@ -57,6 +57,7 @@