Use input context in xvideo and xegl.
This commit is contained in:
parent
205f8ce90d
commit
07e3c7f7fa
|
@ -354,8 +354,6 @@ void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
|
|||
unsigned key = input_translate_keysym_to_rk(XLookupKeysym(&event->xkey, 0));
|
||||
int num = 0;
|
||||
|
||||
fprintf(stderr, "Key: %u\n", key);
|
||||
|
||||
if (down && !filter)
|
||||
{
|
||||
KeySym keysym = 0;
|
||||
|
@ -365,28 +363,18 @@ void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
|
|||
|
||||
// XwcLookupString doesn't seem to work.
|
||||
num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status);
|
||||
fprintf(stderr, "Status: %d\n", status);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
fprintf(stderr, "Char: 0x%x\n", (uint8_t)keybuf[i]);
|
||||
|
||||
// libc functions need UTF-8 locale to work properly, which makes mbrtowc a bit impractical.
|
||||
// Use custom utf8 -> UTF-32 conversion.
|
||||
num = conv_utf8_utf32(chars, ARRAY_SIZE(chars), keybuf, num);
|
||||
for (i = 0; i < num; i++)
|
||||
fprintf(stderr, "UTF32: 0x%u\n", chars[i]);
|
||||
#else
|
||||
(void)ic;
|
||||
num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); // ASCII only.
|
||||
for (i = 0; i < num; i++)
|
||||
chars[i] = keybuf[i] & 0x7f;
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "KeySym: %u\n", (unsigned)keysym);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Xwc*: %d\n", num);
|
||||
|
||||
unsigned state = event->xkey.state;
|
||||
uint16_t mod = 0;
|
||||
mod |= (state & ShiftMask) ? RETROKMOD_SHIFT : 0;
|
||||
|
@ -395,8 +383,8 @@ void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
|
|||
mod |= (state & Mod1Mask) ? RETROKMOD_ALT : 0;
|
||||
mod |= (state & Mod4Mask) ? RETROKMOD_META : 0;
|
||||
|
||||
g_extern.system.key_event(down, key, keybuf[0] == -1u ? 0 : keybuf[0], mod);
|
||||
g_extern.system.key_event(down, key, chars[0], mod);
|
||||
for (i = 1; i < num; i++)
|
||||
g_extern.system.key_event(down, RETROK_UNKNOWN, keybuf[i] == -1u ? 0 : keybuf[i], mod);
|
||||
g_extern.system.key_event(down, RETROK_UNKNOWN, chars[i], mod);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,9 @@ static bool g_has_focus;
|
|||
static bool g_true_full;
|
||||
static unsigned g_screen;
|
||||
|
||||
static XIM g_xim;
|
||||
static XIC g_xic;
|
||||
|
||||
static EGLContext g_egl_ctx;
|
||||
static EGLSurface g_egl_surf;
|
||||
static EGLDisplay g_egl_dpy;
|
||||
|
@ -137,6 +140,8 @@ static void gfx_ctx_check_window(bool *quit,
|
|||
while (XPending(g_dpy))
|
||||
{
|
||||
XNextEvent(g_dpy, &event);
|
||||
bool filter = XFilterEvent(&event, g_win);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case ClientMessage:
|
||||
|
@ -158,7 +163,7 @@ static void gfx_ctx_check_window(bool *quit,
|
|||
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
x11_handle_key_event(&event, NULL, false);
|
||||
x11_handle_key_event(&event, g_xic, filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -456,6 +461,9 @@ static bool gfx_ctx_set_video_mode(
|
|||
g_has_focus = true;
|
||||
g_inited = true;
|
||||
|
||||
if (!x11_create_input_context(g_dpy, g_win, &g_xim, &g_xic))
|
||||
goto error;
|
||||
|
||||
driver.display_type = RARCH_DISPLAY_X11;
|
||||
driver.video_display = (uintptr_t)g_dpy;
|
||||
driver.video_window = (uintptr_t)g_win;
|
||||
|
@ -473,6 +481,7 @@ error:
|
|||
|
||||
static void gfx_ctx_destroy(void)
|
||||
{
|
||||
x11_destroy_input_context(&g_xim, &g_xic);
|
||||
if (g_egl_dpy)
|
||||
{
|
||||
if (g_egl_ctx)
|
||||
|
|
113
gfx/xvideo.c
113
gfx/xvideo.c
|
@ -42,6 +42,8 @@ typedef struct xv
|
|||
Window window;
|
||||
Colormap colormap;
|
||||
XShmSegmentInfo shminfo;
|
||||
XIM xim;
|
||||
XIC xic;
|
||||
|
||||
Atom quit_atom;
|
||||
bool focus;
|
||||
|
@ -331,6 +333,53 @@ static bool adaptor_set_format(xv_t *xv, Display *dpy, XvPortID port, const vide
|
|||
return false;
|
||||
}
|
||||
|
||||
static void calc_out_rect(bool keep_aspect, struct rarch_viewport *vp, unsigned vp_width, unsigned vp_height)
|
||||
{
|
||||
vp->full_width = vp_width;
|
||||
vp->full_height = vp_height;
|
||||
|
||||
if (g_settings.video.scale_integer)
|
||||
{
|
||||
gfx_scale_integer(vp, vp_width, vp_height, g_extern.system.aspect_ratio, keep_aspect);
|
||||
}
|
||||
else if (!keep_aspect)
|
||||
{
|
||||
vp->x = 0; vp->y = 0;
|
||||
vp->width = vp_width;
|
||||
vp->height = vp_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
float desired_aspect = g_extern.system.aspect_ratio;
|
||||
float device_aspect = (float)vp_width / vp_height;
|
||||
|
||||
// If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff),
|
||||
// assume they are actually equal.
|
||||
if (fabs(device_aspect - desired_aspect) < 0.0001)
|
||||
{
|
||||
vp->x = 0; vp->y = 0;
|
||||
vp->width = vp_width;
|
||||
vp->height = vp_height;
|
||||
}
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
float delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
|
||||
vp->x = vp_width * (0.5 - delta);
|
||||
vp->y = 0;
|
||||
vp->width = 2.0 * vp_width * delta;
|
||||
vp->height = vp_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
float delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5;
|
||||
vp->x = 0;
|
||||
vp->y = vp_height * (0.5 - delta);
|
||||
vp->width = vp_width;
|
||||
vp->height = 2.0 * vp_height * delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *xv_init(const video_info_t *video, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
xv_t *xv = (xv_t*)calloc(1, sizeof(*xv));
|
||||
|
@ -489,6 +538,15 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo
|
|||
init_yuv_tables(xv);
|
||||
xv_init_font(xv, g_settings.video.font_path, g_settings.video.font_size);
|
||||
|
||||
if (!x11_create_input_context(xv->display, xv->window, &xv->xim, &xv->xic))
|
||||
goto error;
|
||||
|
||||
XWindowAttributes target;
|
||||
XGetWindowAttributes(xv->display, xv->window, &target);
|
||||
calc_out_rect(xv->keep_aspect, &xv->vp, target.width, target.height);
|
||||
xv->vp.full_width = target.width;
|
||||
xv->vp.full_height = target.height;
|
||||
|
||||
return xv;
|
||||
|
||||
error:
|
||||
|
@ -541,53 +599,6 @@ static bool check_resize(xv_t *xv, unsigned width, unsigned height)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void calc_out_rect(bool keep_aspect, struct rarch_viewport *vp, unsigned vp_width, unsigned vp_height)
|
||||
{
|
||||
vp->full_width = vp_width;
|
||||
vp->full_height = vp_height;
|
||||
|
||||
if (g_settings.video.scale_integer)
|
||||
{
|
||||
gfx_scale_integer(vp, vp_width, vp_height, g_extern.system.aspect_ratio, keep_aspect);
|
||||
}
|
||||
else if (!keep_aspect)
|
||||
{
|
||||
vp->x = 0; vp->y = 0;
|
||||
vp->width = vp_width;
|
||||
vp->height = vp_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
float desired_aspect = g_extern.system.aspect_ratio;
|
||||
float device_aspect = (float)vp_width / vp_height;
|
||||
|
||||
// If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff),
|
||||
// assume they are actually equal.
|
||||
if (fabs(device_aspect - desired_aspect) < 0.0001)
|
||||
{
|
||||
vp->x = 0; vp->y = 0;
|
||||
vp->width = vp_width;
|
||||
vp->height = vp_height;
|
||||
}
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
float delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
|
||||
vp->x = vp_width * (0.5 - delta);
|
||||
vp->y = 0;
|
||||
vp->width = 2.0 * vp_width * delta;
|
||||
vp->height = vp_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
float delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5;
|
||||
vp->x = 0;
|
||||
vp->y = vp_height * (0.5 - delta);
|
||||
vp->width = vp_width;
|
||||
vp->height = 2.0 * vp_height * delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Is there some way to render directly like GL? :(
|
||||
// Hacky C code is hacky :D Yay.
|
||||
static void xv_render_msg(xv_t *xv, const char *msg, unsigned width, unsigned height)
|
||||
|
@ -699,7 +710,7 @@ static bool xv_frame(void *data, const void *frame, unsigned width, unsigned hei
|
|||
|
||||
calc_out_rect(xv->keep_aspect, &xv->vp, target.width, target.height);
|
||||
xv->vp.full_width = target.width;
|
||||
xv->vp.full_height = target.width;
|
||||
xv->vp.full_height = target.height;
|
||||
|
||||
if (msg)
|
||||
xv_render_msg(xv, msg, width << 1, height << 1);
|
||||
|
@ -726,6 +737,8 @@ static bool xv_alive(void *data)
|
|||
while (XPending(xv->display))
|
||||
{
|
||||
XNextEvent(xv->display, &event);
|
||||
bool filter = XFilterEvent(&event, xv->window);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case ClientMessage:
|
||||
|
@ -743,7 +756,7 @@ static bool xv_alive(void *data)
|
|||
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
x11_handle_key_event(&event, NULL, false);
|
||||
x11_handle_key_event(&event, xv->xic, filter);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -760,10 +773,10 @@ static bool xv_focus(void *data)
|
|||
return xv->focus;
|
||||
}
|
||||
|
||||
|
||||
static void xv_free(void *data)
|
||||
{
|
||||
xv_t *xv = (xv_t*)data;
|
||||
x11_destroy_input_context(&xv->xim, &xv->xic);
|
||||
XShmDetach(xv->display, &xv->shminfo);
|
||||
shmdt(xv->shminfo.shmaddr);
|
||||
shmctl(xv->shminfo.shmid, IPC_RMID, NULL);
|
||||
|
|
Loading…
Reference in New Issue