mirror of https://github.com/mpv-player/mpv
x11: allow unicode input
This change allows using non-ASCII keys with X11. These keys were ingored before. Technically, this creates an invisible, non-interactive input method context. If creation fails, the code falls back to the old method, which allows a subset of ASCII only.
This commit is contained in:
parent
a63e880400
commit
ad455c43f5
|
@ -23,6 +23,7 @@
|
|||
#include <limits.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "bstr.h"
|
||||
#include "options.h"
|
||||
#include "mp_msg.h"
|
||||
#include "mp_fifo.h"
|
||||
|
@ -422,6 +423,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 +526,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;
|
||||
|
@ -533,24 +538,6 @@ void vo_uninit(struct vo_x11_state *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},
|
||||
|
@ -584,10 +571,17 @@ static const struct mp_keymap keymap[] = {
|
|||
{wsGrayRight, KEY_KP6}, {wsGrayHome, KEY_KP7}, {wsGrayUp, KEY_KP8},
|
||||
{wsGrayPgUp, KEY_KP9}, {wsGrayDelete, 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 +594,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 +739,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 +781,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 +806,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 +817,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;
|
||||
|
@ -1144,6 +1155,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 |
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue