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 <limits.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "bstr.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "mp_msg.h"
|
#include "mp_msg.h"
|
||||||
#include "mp_fifo.h"
|
#include "mp_fifo.h"
|
||||||
|
@ -422,6 +423,8 @@ int vo_init(struct vo *vo)
|
||||||
x11->screen = DefaultScreen(x11->display); // screen ID
|
x11->screen = DefaultScreen(x11->display); // screen ID
|
||||||
x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID
|
x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID
|
||||||
|
|
||||||
|
x11->xim = XOpenIM(x11->display, NULL, NULL, NULL);
|
||||||
|
|
||||||
init_atoms(vo->x11);
|
init_atoms(vo->x11);
|
||||||
|
|
||||||
#ifdef CONFIG_XF86VM
|
#ifdef CONFIG_XF86VM
|
||||||
|
@ -523,6 +526,8 @@ void vo_uninit(struct vo_x11_state *x11)
|
||||||
"vo: x11 uninit called but X11 not initialized..\n");
|
"vo: x11 uninit called but X11 not initialized..\n");
|
||||||
} else {
|
} else {
|
||||||
mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n");
|
mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n");
|
||||||
|
if (x11->xim)
|
||||||
|
XCloseIM(x11->xim);
|
||||||
XSetErrorHandler(NULL);
|
XSetErrorHandler(NULL);
|
||||||
XCloseDisplay(x11->display);
|
XCloseDisplay(x11->display);
|
||||||
x11->depthonscreen = 0;
|
x11->depthonscreen = 0;
|
||||||
|
@ -533,24 +538,6 @@ void vo_uninit(struct vo_x11_state *x11)
|
||||||
|
|
||||||
#include "wskeys.h"
|
#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[] = {
|
static const struct mp_keymap keymap[] = {
|
||||||
// special keys
|
// special keys
|
||||||
{wsPause, KEY_PAUSE}, {wsEscape, KEY_ESC}, {wsBackSpace, KEY_BS},
|
{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},
|
{wsGrayRight, KEY_KP6}, {wsGrayHome, KEY_KP7}, {wsGrayUp, KEY_KP8},
|
||||||
{wsGrayPgUp, KEY_KP9}, {wsGrayDelete, KEY_KPDEL},
|
{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}
|
{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 = " -+*/<>`~!@#$%^&()_{}:;\"\',.?\\|=[]";
|
static const char *passthrough_keys = " -+*/<>`~!@#$%^&()_{}:;\"\',.?\\|=[]";
|
||||||
int mpkey = 0;
|
int mpkey = 0;
|
||||||
|
@ -600,8 +594,7 @@ static void vo_x11_putkey(struct vo *vo, int key, int modifiers)
|
||||||
if (!mpkey)
|
if (!mpkey)
|
||||||
mpkey = lookup_keymap_table(keymap, key);
|
mpkey = lookup_keymap_table(keymap, key);
|
||||||
|
|
||||||
if (mpkey)
|
return mpkey;
|
||||||
mplayer_put_key(vo->key_fifo, mpkey + modifiers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -746,6 +739,9 @@ void vo_x11_uninit(struct vo *vo)
|
||||||
{
|
{
|
||||||
XEvent xev;
|
XEvent xev;
|
||||||
|
|
||||||
|
if (x11->xic)
|
||||||
|
XDestroyIC(x11->xic);
|
||||||
|
|
||||||
XUnmapWindow(x11->display, x11->window);
|
XUnmapWindow(x11->display, x11->window);
|
||||||
XSelectInput(x11->display, x11->window, StructureNotifyMask);
|
XSelectInput(x11->display, x11->window, StructureNotifyMask);
|
||||||
XDestroyWindow(x11->display, x11->window);
|
XDestroyWindow(x11->display, x11->window);
|
||||||
|
@ -785,8 +781,6 @@ int vo_x11_check_events(struct vo *vo)
|
||||||
Display *display = vo->x11->display;
|
Display *display = vo->x11->display;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
XEvent Event;
|
XEvent Event;
|
||||||
char buf[100];
|
|
||||||
KeySym keySym;
|
|
||||||
|
|
||||||
if (x11->vo_mouse_autohide && x11->mouse_waiting_hide &&
|
if (x11->vo_mouse_autohide && x11->mouse_waiting_hide &&
|
||||||
(GetTimerMS() - x11->mouse_timer >= 1000)) {
|
(GetTimerMS() - x11->mouse_timer >= 1000)) {
|
||||||
|
@ -812,8 +806,8 @@ int vo_x11_check_events(struct vo *vo)
|
||||||
break;
|
break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
{
|
||||||
XLookupString(&Event.xkey, buf, sizeof(buf), &keySym,
|
char buf[100];
|
||||||
&x11->compose_status);
|
KeySym keySym = 0;
|
||||||
int modifiers = 0;
|
int modifiers = 0;
|
||||||
if (Event.xkey.state & ShiftMask)
|
if (Event.xkey.state & ShiftMask)
|
||||||
modifiers |= KEY_MODIFIER_SHIFT;
|
modifiers |= KEY_MODIFIER_SHIFT;
|
||||||
|
@ -823,10 +817,27 @@ int vo_x11_check_events(struct vo *vo)
|
||||||
modifiers |= KEY_MODIFIER_ALT;
|
modifiers |= KEY_MODIFIER_ALT;
|
||||||
if (Event.xkey.state & Mod4Mask)
|
if (Event.xkey.state & Mod4Mask)
|
||||||
modifiers |= KEY_MODIFIER_META;
|
modifiers |= KEY_MODIFIER_META;
|
||||||
#ifdef XF86XK_AudioPause
|
if (x11->xic) {
|
||||||
vo_x11_putkey_ext(vo, keySym, modifiers);
|
Status status;
|
||||||
#endif
|
int len = Xutf8LookupString(x11->xic, &Event.xkey, buf,
|
||||||
vo_x11_putkey(vo, keySym, modifiers);
|
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;
|
ret |= VO_EVENT_KEYPRESS;
|
||||||
}
|
}
|
||||||
break;
|
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);
|
XSetWMNormalHints(mDisplay, x11->window, &hint);
|
||||||
if (!vo_border) vo_x11_decoration(vo, 0);
|
if (!vo_border) vo_x11_decoration(vo, 0);
|
||||||
// map window
|
// map window
|
||||||
|
x11->xic = XCreateIC(x11->xim,
|
||||||
|
XNInputStyle, XIMPreeditNone | XIMStatusNone,
|
||||||
|
XNClientWindow, x11->window,
|
||||||
|
XNFocusWindow, x11->window,
|
||||||
|
NULL);
|
||||||
XSelectInput(mDisplay, x11->window, NoEventMask);
|
XSelectInput(mDisplay, x11->window, NoEventMask);
|
||||||
vo_x11_selectinput_witherr(mDisplay, x11->window,
|
vo_x11_selectinput_witherr(mDisplay, x11->window,
|
||||||
StructureNotifyMask | KeyPressMask | PointerMotionMask |
|
StructureNotifyMask | KeyPressMask | PointerMotionMask |
|
||||||
|
|
|
@ -36,6 +36,9 @@ struct vo_x11_state {
|
||||||
int display_is_local;
|
int display_is_local;
|
||||||
int depthonscreen;
|
int depthonscreen;
|
||||||
|
|
||||||
|
XIM xim;
|
||||||
|
XIC xic;
|
||||||
|
|
||||||
GC vo_gc;
|
GC vo_gc;
|
||||||
|
|
||||||
struct xv_ck_info_s {
|
struct xv_ck_info_s {
|
||||||
|
|
Loading…
Reference in New Issue