diff options
Diffstat (limited to 'platform/linuxbsd/x11')
18 files changed, 1507 insertions, 2046 deletions
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index d4f82cc81e..428cf3a145 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1324,6 +1324,8 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) { } #endif + XDestroyWindow(x11_display, wd.x11_xim_window); + XUnmapWindow(x11_display, wd.x11_window); XDestroyWindow(x11_display, wd.x11_window); if (wd.xic) { @@ -1608,7 +1610,7 @@ void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent // a subwindow and its parent are both destroyed. if (!wd_window.no_focus && !wd_window.is_popup && wd_window.focused) { if ((xwa.map_state == IsViewable) && !wd_parent.no_focus && !wd_window.is_popup) { - XSetInputFocus(x11_display, wd_parent.x11_window, RevertToPointerRoot, CurrentTime); + XSetInputFocus(x11_display, wd_parent.x11_window, RevertToParent, CurrentTime); } } } else { @@ -2490,23 +2492,40 @@ void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_win ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - wd.im_active = p_active; - if (!wd.xic) { return; } + if (!wd.focused) { + wd.ime_active = false; + im_text = String(); + im_selection = Vector2i(); + return; + } // Block events polling while changing input focus // because it triggers some event polling internally. if (p_active) { - { - MutexLock mutex_lock(events_mutex); - XSetICFocus(wd.xic); + MutexLock mutex_lock(events_mutex); + + wd.ime_active = true; + + XMapWindow(x11_display, wd.x11_xim_window); + + XWindowAttributes xwa; + XSync(x11_display, False); + XGetWindowAttributes(x11_display, wd.x11_xim_window, &xwa); + if (xwa.map_state == IsViewable) { + XSetInputFocus(x11_display, wd.x11_xim_window, RevertToPointerRoot, CurrentTime); } - window_set_ime_position(wd.im_position, p_window); + XSetICFocus(wd.xic); } else { MutexLock mutex_lock(events_mutex); XUnsetICFocus(wd.xic); + XUnmapWindow(x11_display, wd.x11_xim_window); + wd.ime_active = false; + + im_text = String(); + im_selection = Vector2i(); } } @@ -2516,25 +2535,29 @@ void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_ ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - wd.im_position = p_pos; - if (!wd.xic) { return; } + if (!wd.focused) { + return; + } - ::XPoint spot; - spot.x = short(p_pos.x); - spot.y = short(p_pos.y); - XVaNestedList preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, nullptr); - - { - // Block events polling during this call - // because it triggers some event polling internally. - MutexLock mutex_lock(events_mutex); - XSetICValues(wd.xic, XNPreeditAttributes, preedit_attr, nullptr); + if (wd.ime_active) { + XWindowAttributes xwa; + XSync(x11_display, False); + XGetWindowAttributes(x11_display, wd.x11_xim_window, &xwa); + if (xwa.map_state == IsViewable) { + XMoveWindow(x11_display, wd.x11_xim_window, p_pos.x, p_pos.y); + } } +} + +Point2i DisplayServerX11::ime_get_selection() const { + return im_selection; +} - XFree(preedit_attr); +String DisplayServerX11::ime_get_text() const { + return im_text; } void DisplayServerX11::cursor_set_shape(CursorShape p_shape) { @@ -2872,6 +2895,16 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, // X11 functions don't know what const is XKeyEvent *xkeyevent = p_event; + if (wd.ime_in_progress) { + return; + } + if (wd.ime_suppress_next_keyup) { + wd.ime_suppress_next_keyup = false; + if (xkeyevent->type != KeyPress) { + return; + } + } + // This code was pretty difficult to write. // The docs stink and every toolkit seems to // do it in a different way. @@ -2895,13 +2928,20 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, KeySym keysym_unicode = 0; // keysym used to find unicode // XLookupString returns keysyms usable as nice keycodes. - char str[256 + 1]; + char str[256] = {}; XKeyEvent xkeyevent_no_mod = *xkeyevent; xkeyevent_no_mod.state &= ~ShiftMask; xkeyevent_no_mod.state &= ~ControlMask; - XLookupString(xkeyevent, str, 256, &keysym_unicode, nullptr); + XLookupString(xkeyevent, str, 255, &keysym_unicode, nullptr); XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_keycode, nullptr); + String keysym; + if (xkb_keysym_to_utf32 && xkb_keysym_to_upper) { + KeySym keysym_unicode_nm = 0; // keysym used to find unicode + XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_unicode_nm, nullptr); + keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(keysym_unicode_nm))); + } + // Meanwhile, XLookupString returns keysyms useful for unicode. if (!xmbstring) { @@ -2950,13 +2990,18 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, _get_key_modifier_state(xkeyevent->state, k); k->set_window_id(p_window); - k->set_unicode(tmp[i]); - k->set_pressed(keypress); k->set_keycode(keycode); - - k->set_physical_keycode((Key)physical_keycode); + k->set_physical_keycode(physical_keycode); + if (!keysym.is_empty()) { + k->set_key_label(fix_key_label(keysym[0], keycode)); + } else { + k->set_key_label(keycode); + } + if (keypress) { + k->set_unicode(fix_unicode(tmp[i])); + } k->set_echo(false); @@ -2999,7 +3044,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, // KeyMappingX11 also translates keysym to unicode. // It does a binary search on a table to translate // most properly. - unsigned int unicode = keysym_unicode > 0 ? KeyMappingX11::get_unicode_from_keysym(keysym_unicode) : 0; + char32_t unicode = keysym_unicode > 0 ? KeyMappingX11::get_unicode_from_keysym(keysym_unicode) : 0; /* Phase 4, determine if event must be filtered */ @@ -3085,7 +3130,14 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, k->set_keycode(keycode); k->set_physical_keycode((Key)physical_keycode); - k->set_unicode(unicode); + if (!keysym.is_empty()) { + k->set_key_label(fix_key_label(keysym[0], keycode)); + } else { + k->set_key_label(keycode); + } + if (keypress) { + k->set_unicode(fix_unicode(unicode)); + } k->set_echo(p_echo); if (k->get_keycode() == Key::BACKTAB) { @@ -3237,6 +3289,81 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p XFlush(x11_display); } +int DisplayServerX11::_xim_preedit_start_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data) { + DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data); + WindowID window_id = ds->_get_focused_window_or_popup(); + WindowData &wd = ds->windows[window_id]; + if (wd.ime_active) { + wd.ime_in_progress = true; + } + + return -1; // Allow preedit strings of any length (no limit). +} + +void DisplayServerX11::_xim_preedit_done_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data) { + DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data); + WindowID window_id = ds->_get_focused_window_or_popup(); + WindowData &wd = ds->windows[window_id]; + if (wd.ime_active) { + wd.ime_in_progress = false; + wd.ime_suppress_next_keyup = true; + } +} + +void DisplayServerX11::_xim_preedit_draw_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditDrawCallbackStruct *call_data) { + DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data); + WindowID window_id = ds->_get_focused_window_or_popup(); + WindowData &wd = ds->windows[window_id]; + + XIMText *xim_text = call_data->text; + if (wd.ime_active) { + if (xim_text != nullptr) { + String changed_text; + if (xim_text->encoding_is_wchar) { + changed_text = String(xim_text->string.wide_char); + } else { + changed_text.parse_utf8(xim_text->string.multi_byte); + } + + if (call_data->chg_length < 0) { + ds->im_text = ds->im_text.substr(0, call_data->chg_first) + changed_text; + } else { + ds->im_text = ds->im_text.substr(0, call_data->chg_first) + changed_text + ds->im_text.substr(call_data->chg_length); + } + + // Find the start and end of the selection. + int start = 0, count = 0; + for (int i = 0; i < xim_text->length; i++) { + if (xim_text->feedback[i] & XIMReverse) { + if (count == 0) { + start = i; + count = 1; + } else { + count++; + } + } + } + if (count > 0) { + ds->im_selection = Point2i(start + call_data->chg_first, count); + } else { + ds->im_selection = Point2i(call_data->caret, 0); + } + } else { + ds->im_text = String(); + ds->im_selection = Point2i(); + } + + OS_Unix::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); + } +} + +void DisplayServerX11::_xim_preedit_caret_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditCaretCallbackStruct *call_data) { +} + void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data, ::XPointer call_data) { WARN_PRINT("Input method stopped"); @@ -3286,10 +3413,6 @@ void DisplayServerX11::_window_changed(XEvent *event) { if (new_rect == Rect2i(wd.position, wd.size)) { return; } - if (wd.xic) { - // Not portable. - window_set_ime_position(Point2(0, 1)); - } wd.position = new_rect.position; wd.size = new_rect.size; @@ -3637,6 +3760,7 @@ void DisplayServerX11::process_events() { continue; } + bool ime_window_event = false; WindowID window_id = MAIN_WINDOW_ID; // Assign the event to the relevant window @@ -3645,6 +3769,11 @@ void DisplayServerX11::process_events() { window_id = E.key; break; } + if (event.xany.window == E.value.x11_xim_window) { + window_id = E.key; + ime_window_event = true; + break; + } } if (XGetEventData(x11_display, &event.xcookie)) { @@ -3659,6 +3788,9 @@ void DisplayServerX11::process_events() { _refresh_device_info(); } break; case XI_RawMotion: { + if (ime_window_event) { + break; + } XIRawEvent *raw_event = (XIRawEvent *)event_data; int device_id = raw_event->sourceid; @@ -3761,6 +3893,9 @@ void DisplayServerX11::process_events() { #ifdef TOUCH_ENABLED case XI_TouchBegin: case XI_TouchEnd: { + if (ime_window_event) { + break; + } bool is_begin = event_data->evtype == XI_TouchBegin; Ref<InputEventScreenTouch> st; @@ -3791,6 +3926,9 @@ void DisplayServerX11::process_events() { } break; case XI_TouchUpdate: { + if (ime_window_event) { + break; + } HashMap<int, Vector2>::Iterator curr_pos_elem = xi.state.find(index); if (!curr_pos_elem) { // Defensive break; @@ -3817,6 +3955,9 @@ void DisplayServerX11::process_events() { switch (event.type) { case MapNotify: { DEBUG_LOG_X11("[%u] MapNotify window=%lu (%u) \n", frame, event.xmap.window, window_id); + if (ime_window_event) { + break; + } const WindowData &wd = windows[window_id]; @@ -3837,6 +3978,9 @@ void DisplayServerX11::process_events() { case Expose: { DEBUG_LOG_X11("[%u] Expose window=%lu (%u), count='%u' \n", frame, event.xexpose.window, window_id, event.xexpose.count); + if (ime_window_event) { + break; + } windows[window_id].fullscreen = _window_fullscreen_check(window_id); @@ -3845,18 +3989,27 @@ void DisplayServerX11::process_events() { case NoExpose: { DEBUG_LOG_X11("[%u] NoExpose drawable=%lu (%u) \n", frame, event.xnoexpose.drawable, window_id); + if (ime_window_event) { + break; + } windows[window_id].minimized = true; } break; case VisibilityNotify: { DEBUG_LOG_X11("[%u] VisibilityNotify window=%lu (%u), state=%u \n", frame, event.xvisibility.window, window_id, event.xvisibility.state); + if (ime_window_event) { + break; + } windows[window_id].minimized = _window_minimize_check(window_id); } break; case LeaveNotify: { DEBUG_LOG_X11("[%u] LeaveNotify window=%lu (%u), mode='%u' \n", frame, event.xcrossing.window, window_id, event.xcrossing.mode); + if (ime_window_event) { + break; + } if (!mouse_mode_grab) { _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT); @@ -3866,6 +4019,9 @@ void DisplayServerX11::process_events() { case EnterNotify: { DEBUG_LOG_X11("[%u] EnterNotify window=%lu (%u), mode='%u' \n", frame, event.xcrossing.window, window_id, event.xcrossing.mode); + if (ime_window_event) { + break; + } if (!mouse_mode_grab) { _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); @@ -3874,18 +4030,14 @@ void DisplayServerX11::process_events() { case FocusIn: { DEBUG_LOG_X11("[%u] FocusIn window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode); + if (ime_window_event) { + break; + } WindowData &wd = windows[window_id]; last_focused_window = window_id; wd.focused = true; - if (wd.xic) { - // Block events polling while changing input focus - // because it triggers some event polling internally. - MutexLock mutex_lock(events_mutex); - XSetICFocus(wd.xic); - } - // Keep track of focus order for overlapping windows. static unsigned int focus_order = 0; wd.focus_order = ++focus_order; @@ -3925,17 +4077,20 @@ void DisplayServerX11::process_events() { case FocusOut: { DEBUG_LOG_X11("[%u] FocusOut window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode); - WindowData &wd = windows[window_id]; - - wd.focused = false; - - if (wd.xic) { - // Block events polling while changing input focus - // because it triggers some event polling internally. + if (wd.ime_active && event.xfocus.detail == NotifyInferior) { + break; + } + if (wd.ime_active) { MutexLock mutex_lock(events_mutex); XUnsetICFocus(wd.xic); + XUnmapWindow(x11_display, wd.x11_xim_window); + wd.ime_active = false; + im_text = String(); + im_selection = Vector2i(); + OS_Unix::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); } + wd.focused = false; Input::get_singleton()->release_pressed_events(); _send_window_event(wd, WINDOW_EVENT_FOCUS_OUT); @@ -3971,6 +4126,9 @@ void DisplayServerX11::process_events() { case ConfigureNotify: { DEBUG_LOG_X11("[%u] ConfigureNotify window=%lu (%u), event=%lu, above=%lu, override_redirect=%u \n", frame, event.xconfigure.window, window_id, event.xconfigure.event, event.xconfigure.above, event.xconfigure.override_redirect); + if (event.xconfigure.window == windows[window_id].x11_xim_window) { + break; + } const WindowData &wd = windows[window_id]; @@ -3990,6 +4148,9 @@ void DisplayServerX11::process_events() { case ButtonPress: case ButtonRelease: { + if (ime_window_event) { + break; + } /* exit in case of a mouse button press */ last_timestamp = event.xbutton.time; if (mouse_mode == MOUSE_MODE_CAPTURED) { @@ -4088,6 +4249,9 @@ void DisplayServerX11::process_events() { } break; case MotionNotify: { + if (ime_window_event) { + break; + } // The X11 API requires filtering one-by-one through the motion // notify events, in order to figure out which event is the one // generated by warping the mouse pointer. @@ -4248,7 +4412,9 @@ void DisplayServerX11::process_events() { } break; case SelectionNotify: - + if (ime_window_event) { + break; + } if (event.xselection.target == requested) { Property p = _read_property(x11_display, windows[window_id].x11_window, XInternAtom(x11_display, "PRIMARY", 0)); @@ -4283,7 +4449,9 @@ void DisplayServerX11::process_events() { break; case ClientMessage: - + if (ime_window_event) { + break; + } if ((unsigned int)event.xclient.data.l[0] == (unsigned int)wm_delete) { _send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST); } @@ -4693,6 +4861,11 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V { wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo.screen), win_rect.position.x, win_rect.position.y, win_rect.size.width > 0 ? win_rect.size.width : 1, win_rect.size.height > 0 ? win_rect.size.height : 1, 0, visualInfo.depth, InputOutput, visualInfo.visual, valuemask, &windowAttributes); + XSetWindowAttributes window_attributes_ime = {}; + window_attributes_ime.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; + + wd.x11_xim_window = XCreateWindow(x11_display, wd.x11_window, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWEventMask, &window_attributes_ime); + // Enable receiving notification when the window is initialized (MapNotify) // so the focus can be set at the right time. if (!wd.no_focus && !wd.is_popup) { @@ -4763,7 +4936,50 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V // because it triggers some event polling internally. MutexLock mutex_lock(events_mutex); - wd.xic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, wd.x11_window, XNFocusWindow, wd.x11_window, (char *)nullptr); + // Force on-the-spot for the over-the-spot style. + if ((xim_style & XIMPreeditPosition) != 0) { + xim_style &= ~XIMPreeditPosition; + xim_style |= XIMPreeditCallbacks; + } + if ((xim_style & XIMPreeditCallbacks) != 0) { + ::XIMCallback preedit_start_callback; + preedit_start_callback.client_data = (::XPointer)(this); + preedit_start_callback.callback = (::XIMProc)(void *)(_xim_preedit_start_callback); + + ::XIMCallback preedit_done_callback; + preedit_done_callback.client_data = (::XPointer)(this); + preedit_done_callback.callback = (::XIMProc)(_xim_preedit_done_callback); + + ::XIMCallback preedit_draw_callback; + preedit_draw_callback.client_data = (::XPointer)(this); + preedit_draw_callback.callback = (::XIMProc)(_xim_preedit_draw_callback); + + ::XIMCallback preedit_caret_callback; + preedit_caret_callback.client_data = (::XPointer)(this); + preedit_caret_callback.callback = (::XIMProc)(_xim_preedit_caret_callback); + + ::XVaNestedList preedit_attributes = XVaCreateNestedList(0, + XNPreeditStartCallback, &preedit_start_callback, + XNPreeditDoneCallback, &preedit_done_callback, + XNPreeditDrawCallback, &preedit_draw_callback, + XNPreeditCaretCallback, &preedit_caret_callback, + (char *)nullptr); + + wd.xic = XCreateIC(xim, + XNInputStyle, xim_style, + XNClientWindow, wd.x11_xim_window, + XNFocusWindow, wd.x11_xim_window, + XNPreeditAttributes, preedit_attributes, + (char *)nullptr); + XFree(preedit_attributes); + } else { + wd.xic = XCreateIC(xim, + XNInputStyle, xim_style, + XNClientWindow, wd.x11_xim_window, + XNFocusWindow, wd.x11_xim_window, + (char *)nullptr); + } + if (XGetICValues(wd.xic, XNFilterEvents, &im_event_mask, nullptr) != nullptr) { WARN_PRINT("XGetICValues couldn't obtain XNFilterEvents value"); XDestroyIC(wd.xic); @@ -4854,7 +5070,66 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V return id; } +static bool _is_xim_style_supported(const ::XIMStyle &p_style) { + const ::XIMStyle supported_preedit = XIMPreeditCallbacks | XIMPreeditPosition | XIMPreeditNothing | XIMPreeditNone; + const ::XIMStyle supported_status = XIMStatusNothing | XIMStatusNone; + + // Check preedit style is supported + if ((p_style & supported_preedit) == 0) { + return false; + } + + // Check status style is supported + if ((p_style & supported_status) == 0) { + return false; + } + + return true; +} + +static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMStyle &p_style_b) { + if (p_style_a == 0) { + return p_style_b; + } + if (p_style_b == 0) { + return p_style_a; + } + + const ::XIMStyle preedit = XIMPreeditArea | XIMPreeditCallbacks | XIMPreeditPosition | XIMPreeditNothing | XIMPreeditNone; + const ::XIMStyle status = XIMStatusArea | XIMStatusCallbacks | XIMStatusNothing | XIMStatusNone; + + ::XIMStyle a = p_style_a & preedit; + ::XIMStyle b = p_style_b & preedit; + if (a != b) { + // Compare preedit styles. + if ((a | b) & XIMPreeditCallbacks) { + return a == XIMPreeditCallbacks ? p_style_a : p_style_b; + } else if ((a | b) & XIMPreeditPosition) { + return a == XIMPreeditPosition ? p_style_a : p_style_b; + } else if ((a | b) & XIMPreeditArea) { + return a == XIMPreeditArea ? p_style_a : p_style_b; + } else if ((a | b) & XIMPreeditNothing) { + return a == XIMPreeditNothing ? p_style_a : p_style_b; + } + } else { + // Preedit styles are the same, compare status styles. + a = p_style_a & status; + b = p_style_b & status; + + if ((a | b) & XIMStatusCallbacks) { + return a == XIMStatusCallbacks ? p_style_a : p_style_b; + } else if ((a | b) & XIMStatusArea) { + return a == XIMStatusArea ? p_style_a : p_style_b; + } else if ((a | b) & XIMStatusNothing) { + return a == XIMStatusNothing ? p_style_a : p_style_b; + } + } + return p_style_a; +} + DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) { + KeyMappingX11::initialize(); + #ifdef DEBUG_ENABLED int dylibloader_verbose = 1; #else @@ -4870,6 +5145,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode ERR_FAIL_MSG("Can't load XCursor dynamically."); } + initialize_xkbcommon(dylibloader_verbose); // Optional, used for key_label. + if (initialize_xext(dylibloader_verbose) != 0) { r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Can't load Xext dynamically."); @@ -5001,11 +5278,13 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (xim_styles) { xim_style = 0L; for (int i = 0; i < xim_styles->count_styles; i++) { - if (xim_styles->supported_styles[i] == - (XIMPreeditNothing | XIMStatusNothing)) { - xim_style = xim_styles->supported_styles[i]; - break; + const ::XIMStyle &style = xim_styles->supported_styles[i]; + + if (!_is_xim_style_supported(style)) { + continue; } + + xim_style = _get_best_xim_style(xim_style, style); } XFree(xim_styles); diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 437766d953..bfb97ae44c 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -78,6 +78,8 @@ #include "dynwrappers/xrandr-so_wrap.h" #include "dynwrappers/xrender-so_wrap.h" +#include "../xkbcommon-so_wrap.h" + typedef struct _xrr_monitor_info { Atom name; Bool primary = false; @@ -135,14 +137,16 @@ class DisplayServerX11 : public DisplayServer { struct WindowData { Window x11_window; + Window x11_xim_window; ::XIC xic; + bool ime_active = false; + bool ime_in_progress = false; + bool ime_suppress_next_keyup = false; Size2i min_size; Size2i max_size; Point2i position; Size2i size; - Point2i im_position; - bool im_active = false; Callable rect_changed_callback; Callable event_callback; Callable input_event_callback; @@ -178,6 +182,9 @@ class DisplayServerX11 : public DisplayServer { unsigned int focus_order = 0; }; + Point2i im_selection; + String im_text; + HashMap<WindowID, WindowData> windows; unsigned int last_mouse_monitor_mask = 0; @@ -200,6 +207,15 @@ class DisplayServerX11 : public DisplayServer { ::Time last_keyrelease_time = 0; ::XIM xim; ::XIMStyle xim_style; + + static int _xim_preedit_start_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data); + static void _xim_preedit_done_callback(::XIM xim, ::XPointer client_data, + ::XPointer call_data); + static void _xim_preedit_draw_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditDrawCallbackStruct *call_data); + static void _xim_preedit_caret_callback(::XIM xim, ::XPointer client_data, + ::XIMPreeditCaretCallbackStruct *call_data); static void _xim_destroy_callback(::XIM im, ::XPointer client_data, ::XPointer call_data); @@ -433,6 +449,9 @@ public: virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID) override; + virtual Point2i ime_get_selection() const override; + virtual String ime_get_text() const override; + virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; diff --git a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c index 7042a60d47..ecd2c25662 100644 --- a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:48:06 -// flags: ./generate-wrapper.py --include /usr/include/X11/Xcursor/Xcursor.h --sys-include <X11/Xcursor/Xcursor.h> --soname libXcursor.so.1 --init-name xcursor --output-header xcursor-so_wrap.h --output-implementation xcursor-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:09:53 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c // // NOTE: Generated from Xcursor 1.2.0. // This has been handpatched to workaround some issues with the generator that @@ -68,7 +68,7 @@ #define XcursorGetTheme XcursorGetTheme_dylibloader_orig_xcursor #define XcursorGetThemeCore XcursorGetThemeCore_dylibloader_orig_xcursor #define XcursorSetThemeCore XcursorSetThemeCore_dylibloader_orig_xcursor -#include <X11/Xcursor/Xcursor.h> +#include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" #undef XcursorImageCreate #undef XcursorImageDestroy #undef XcursorImagesCreate diff --git a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h index d00fccffda..dc3684ff09 100644 --- a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_XCURSOR // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:48:06 -// flags: ./generate-wrapper.py --include /usr/include/X11/Xcursor/Xcursor.h --sys-include <X11/Xcursor/Xcursor.h> --soname libXcursor.so.1 --init-name xcursor --output-header xcursor-so_wrap.h --output-implementation xcursor-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:09:53 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c // // NOTE: Generated from Xcursor 1.2.0. // This has been handpatched to workaround some issues with the generator that @@ -70,7 +70,7 @@ #define XcursorGetTheme XcursorGetTheme_dylibloader_orig_xcursor #define XcursorGetThemeCore XcursorGetThemeCore_dylibloader_orig_xcursor #define XcursorSetThemeCore XcursorSetThemeCore_dylibloader_orig_xcursor -#include <X11/Xcursor/Xcursor.h> +#include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" #undef XcursorImageCreate #undef XcursorImageDestroy #undef XcursorImagesCreate diff --git a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c index c8e87a6b85..e9af9033a3 100644 --- a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:51:55 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xext.h --sys-include <X11/extensions/Xext.h> --include /usr/include/X11/extensions/shape.h --sys-include <X11/extensions/shape.h> --soname libXext.so.6 --init-name xext --output-header xext-so_wrap.h --output-implementation xext-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:11:29 +// flags: ../dynload-wrapper/generate-wrapper.py --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c // // NOTE: Generated from Xext 1.3.5. // This has been handpatched to workaround some issues with the generator that @@ -12,7 +12,7 @@ #include <stdint.h> // HANDPATCH: Needed for a successful compilation. -#include <X11/Xlib.h> +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" #define XShapeQueryExtension XShapeQueryExtension_dylibloader_orig_xext #define XShapeQueryVersion XShapeQueryVersion_dylibloader_orig_xext @@ -25,8 +25,8 @@ #define XShapeSelectInput XShapeSelectInput_dylibloader_orig_xext #define XShapeInputSelected XShapeInputSelected_dylibloader_orig_xext #define XShapeGetRectangles XShapeGetRectangles_dylibloader_orig_xext -#include <X11/extensions/Xext.h> -#include <X11/extensions/shape.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" +#include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" #undef XShapeQueryExtension #undef XShapeQueryVersion #undef XShapeCombineRegion diff --git a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h index aee92b593e..bbf23fff34 100644 --- a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_XEXT // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:51:55 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xext.h --sys-include <X11/extensions/Xext.h> --include /usr/include/X11/extensions/shape.h --sys-include <X11/extensions/shape.h> --soname libXext.so.6 --init-name xext --output-header xext-so_wrap.h --output-implementation xext-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:11:29 +// flags: ../dynload-wrapper/generate-wrapper.py --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c // // NOTE: Generated from Xext 1.3.5. // This has been handpatched to workaround some issues with the generator that @@ -14,7 +14,7 @@ #include <stdint.h> // HANDPATCH: Needed for a successful compilation. -#include <X11/Xlib.h> +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" #define XShapeQueryExtension XShapeQueryExtension_dylibloader_orig_xext #define XShapeQueryVersion XShapeQueryVersion_dylibloader_orig_xext @@ -27,8 +27,8 @@ #define XShapeSelectInput XShapeSelectInput_dylibloader_orig_xext #define XShapeInputSelected XShapeInputSelected_dylibloader_orig_xext #define XShapeGetRectangles XShapeGetRectangles_dylibloader_orig_xext -#include <X11/extensions/Xext.h> -#include <X11/extensions/shape.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" +#include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" #undef XShapeQueryExtension #undef XShapeQueryVersion #undef XShapeCombineRegion diff --git a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c index 85ac80e3f2..ab53b232d6 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:53:11 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xinerama.h --sys-include <X11/extensions/Xinerama.h> --soname libXinerama.so.1 --init-name xinerama --output-header xinerama-so_wrap.h --output-implementation xinerama-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:11:35 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c // // NOTE: Generated from Xinerama 1.1.4. // This has been handpatched to workaround some issues with the generator that @@ -13,7 +13,7 @@ #define XineramaQueryVersion XineramaQueryVersion_dylibloader_orig_xinerama #define XineramaIsActive XineramaIsActive_dylibloader_orig_xinerama #define XineramaQueryScreens XineramaQueryScreens_dylibloader_orig_xinerama -#include <X11/extensions/Xinerama.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" #undef XineramaQueryExtension #undef XineramaQueryVersion #undef XineramaIsActive diff --git a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h index 9139421cd6..48d5cc44b7 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_XINERAMA // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:53:11 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xinerama.h --sys-include <X11/extensions/Xinerama.h> --soname libXinerama.so.1 --init-name xinerama --output-header xinerama-so_wrap.h --output-implementation xinerama-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:11:35 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c // // NOTE: Generated from Xinerama 1.1.4. // This has been handpatched to workaround some issues with the generator that @@ -15,7 +15,7 @@ #define XineramaQueryVersion XineramaQueryVersion_dylibloader_orig_xinerama #define XineramaIsActive XineramaIsActive_dylibloader_orig_xinerama #define XineramaQueryScreens XineramaQueryScreens_dylibloader_orig_xinerama -#include <X11/extensions/Xinerama.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" #undef XineramaQueryExtension #undef XineramaQueryVersion #undef XineramaIsActive diff --git a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c index 5f16bc6111..d37f2b4d94 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:54:10 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/XInput2.h --sys-include <X11/extensions/XInput2.h> --soname libXi.so.6 --init-name xinput2 --output-header xinput2-so_wrap.h --output-implementation xinput2-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:12:16 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c // // NOTE: Generated from Xi 1.7.10. // This has been handpatched to workaround some issues with the generator that @@ -43,7 +43,7 @@ #define XIBarrierReleasePointers XIBarrierReleasePointers_dylibloader_orig_xinput2 #define XIBarrierReleasePointer XIBarrierReleasePointer_dylibloader_orig_xinput2 #define XIFreeDeviceInfo XIFreeDeviceInfo_dylibloader_orig_xinput2 -#include <X11/extensions/XInput2.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" #undef XIQueryPointer #undef XIWarpPointer #undef XIDefineCursor diff --git a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h index ecb7aa5048..e39661ffb9 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_XINPUT2 // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:54:10 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/XInput2.h --sys-include <X11/extensions/XInput2.h> --soname libXi.so.6 --init-name xinput2 --output-header xinput2-so_wrap.h --output-implementation xinput2-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:12:16 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c // // NOTE: Generated from Xi 1.7.10. // This has been handpatched to workaround some issues with the generator that @@ -45,7 +45,7 @@ #define XIBarrierReleasePointers XIBarrierReleasePointers_dylibloader_orig_xinput2 #define XIBarrierReleasePointer XIBarrierReleasePointer_dylibloader_orig_xinput2 #define XIFreeDeviceInfo XIFreeDeviceInfo_dylibloader_orig_xinput2 -#include <X11/extensions/XInput2.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" #undef XIQueryPointer #undef XIWarpPointer #undef XIDefineCursor diff --git a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c index 12097a2987..a746b6c526 100644 --- a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:54:53 -// flags: ./generate-wrapper.py --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include <X11/Xlib.h> --sys-include <X11/Xutil.h> --sys-include <X11/XKBlib.h> --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib-so_wrap.h --output-implementation xlib-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:13:26 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include "thirdparty/linuxbsd_headers/X11/Xlib.h" --sys-include "thirdparty/linuxbsd_headers/X11/Xutil.h" --sys-include "thirdparty/linuxbsd_headers/X11/XKBlib.h" --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c~ // // NOTE: Generated from Xlib 1.6.9. // This has been handpatched to workaround some issues with the generator that @@ -614,9 +614,9 @@ #define XkbApplyVirtualModChanges XkbApplyVirtualModChanges_dylibloader_orig_xlib #define XkbUpdateActionVirtualMods XkbUpdateActionVirtualMods_dylibloader_orig_xlib #define XkbUpdateKeyTypeVirtualMods XkbUpdateKeyTypeVirtualMods_dylibloader_orig_xlib -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/XKBlib.h> +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" +#include "thirdparty/linuxbsd_headers/X11/Xutil.h" +#include "thirdparty/linuxbsd_headers/X11/XKBlib.h" #undef _Xmblen #undef XLoadQueryFont #undef XQueryFont diff --git a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h index 47464078e3..b40a25f601 100644 --- a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_XLIB // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:54:53 -// flags: ./generate-wrapper.py --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include <X11/Xlib.h> --sys-include <X11/Xutil.h> --sys-include <X11/XKBlib.h> --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib-so_wrap.h --output-implementation xlib-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:13:26 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include "thirdparty/linuxbsd_headers/X11/Xlib.h" --sys-include "thirdparty/linuxbsd_headers/X11/Xutil.h" --sys-include "thirdparty/linuxbsd_headers/X11/XKBlib.h" --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c~ // // NOTE: Generated from Xlib 1.6.9. // This has been handpatched to workaround some issues with the generator that @@ -617,9 +617,9 @@ #define XkbApplyVirtualModChanges XkbApplyVirtualModChanges_dylibloader_orig_xlib #define XkbUpdateActionVirtualMods XkbUpdateActionVirtualMods_dylibloader_orig_xlib #define XkbUpdateKeyTypeVirtualMods XkbUpdateKeyTypeVirtualMods_dylibloader_orig_xlib -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/XKBlib.h> +#include "thirdparty/linuxbsd_headers/X11/Xlib.h" +#include "thirdparty/linuxbsd_headers/X11/Xutil.h" +#include "thirdparty/linuxbsd_headers/X11/XKBlib.h" #undef _Xmblen #undef XLoadQueryFont #undef XQueryFont diff --git a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c index f37f3a9db0..21e30a03de 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:55:12 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xrandr.h --sys-include <X11/extensions/Xrandr.h> --soname libXrandr.so.2 --init-name xrandr --output-header xrandr-so_wrap.h --output-implementation xrandr-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:13:54 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c // // NOTE: Generated from Xrandr 1.5.2. // This has been handpatched to workaround some issues with the generator that @@ -79,7 +79,7 @@ #define XRRSetMonitor XRRSetMonitor_dylibloader_orig_xrandr #define XRRDeleteMonitor XRRDeleteMonitor_dylibloader_orig_xrandr #define XRRFreeMonitors XRRFreeMonitors_dylibloader_orig_xrandr -#include <X11/extensions/Xrandr.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" #undef XRRQueryExtension #undef XRRQueryVersion #undef XRRGetScreenInfo diff --git a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h index 046d4c7de3..f301234b53 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_XRANDR // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:55:12 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xrandr.h --sys-include <X11/extensions/Xrandr.h> --soname libXrandr.so.2 --init-name xrandr --output-header xrandr-so_wrap.h --output-implementation xrandr-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:13:54 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c // // NOTE: Generated from Xrandr 1.5.2. // This has been handpatched to workaround some issues with the generator that @@ -81,7 +81,7 @@ #define XRRSetMonitor XRRSetMonitor_dylibloader_orig_xrandr #define XRRDeleteMonitor XRRDeleteMonitor_dylibloader_orig_xrandr #define XRRFreeMonitors XRRFreeMonitors_dylibloader_orig_xrandr -#include <X11/extensions/Xrandr.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" #undef XRRQueryExtension #undef XRRQueryVersion #undef XRRGetScreenInfo diff --git a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c index 2d3847e584..5c720bee21 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c @@ -1,7 +1,7 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:55:28 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xrender.h --sys-include <X11/extensions/Xrender.h> --soname libXrender.so.1 --init-name xrender --output-header xrender-so_wrap.h --output-implementation xrender-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:14:14 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c~ // // NOTE: Generated from Xrender 0.9.10. // This has been handpatched to workaround some issues with the generator that @@ -53,7 +53,7 @@ #define XRenderCreateLinearGradient XRenderCreateLinearGradient_dylibloader_orig_xrender #define XRenderCreateRadialGradient XRenderCreateRadialGradient_dylibloader_orig_xrender #define XRenderCreateConicalGradient XRenderCreateConicalGradient_dylibloader_orig_xrender -#include <X11/extensions/Xrender.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" #undef XRenderQueryExtension #undef XRenderQueryVersion #undef XRenderQueryFormats diff --git a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h index e873448ec5..29a8430476 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h @@ -2,8 +2,8 @@ #define DYLIBLOAD_WRAPPER_XRENDER // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by ./generate-wrapper.py 0.3 on 2022-12-02 12:55:28 -// flags: ./generate-wrapper.py --include /usr/include/X11/extensions/Xrender.h --sys-include <X11/extensions/Xrender.h> --soname libXrender.so.1 --init-name xrender --output-header xrender-so_wrap.h --output-implementation xrender-so_wrap.c +// generated by ../dynload-wrapper/generate-wrapper.py 0.3 on 2023-01-23 15:14:14 +// flags: ../dynload-wrapper/generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c~ // // NOTE: Generated from Xrender 0.9.10. // This has been handpatched to workaround some issues with the generator that @@ -55,7 +55,7 @@ #define XRenderCreateLinearGradient XRenderCreateLinearGradient_dylibloader_orig_xrender #define XRenderCreateRadialGradient XRenderCreateRadialGradient_dylibloader_orig_xrender #define XRenderCreateConicalGradient XRenderCreateConicalGradient_dylibloader_orig_xrender -#include <X11/extensions/Xrender.h> +#include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" #undef XRenderQueryExtension #undef XRenderQueryVersion #undef XRenderQueryFormats diff --git a/platform/linuxbsd/x11/key_mapping_x11.cpp b/platform/linuxbsd/x11/key_mapping_x11.cpp index 52b7e865bd..e5eba6ccad 100644 --- a/platform/linuxbsd/x11/key_mapping_x11.cpp +++ b/platform/linuxbsd/x11/key_mapping_x11.cpp @@ -30,1972 +30,1122 @@ #include "key_mapping_x11.h" -/***** SCAN CODE CONVERSION ******/ +void KeyMappingX11::initialize() { + // X11 Keysym to Godot Key map. -struct _XTranslatePair { - KeySym keysym; - Key keycode; -}; + xkeysym_map[XK_Escape] = Key::ESCAPE; + xkeysym_map[XK_Tab] = Key::TAB; + xkeysym_map[XK_ISO_Left_Tab] = Key::BACKTAB; + xkeysym_map[XK_BackSpace] = Key::BACKSPACE; + xkeysym_map[XK_Return] = Key::ENTER; + xkeysym_map[XK_Insert] = Key::INSERT; + xkeysym_map[XK_Delete] = Key::KEY_DELETE; + xkeysym_map[XK_Clear] = Key::KEY_DELETE; + xkeysym_map[XK_Pause] = Key::PAUSE; + xkeysym_map[XK_Print] = Key::PRINT; + xkeysym_map[XK_Home] = Key::HOME; + xkeysym_map[XK_End] = Key::END; + xkeysym_map[XK_Left] = Key::LEFT; + xkeysym_map[XK_Up] = Key::UP; + xkeysym_map[XK_Right] = Key::RIGHT; + xkeysym_map[XK_Down] = Key::DOWN; + xkeysym_map[XK_Prior] = Key::PAGEUP; + xkeysym_map[XK_Next] = Key::PAGEDOWN; + xkeysym_map[XK_Shift_L] = Key::SHIFT; + xkeysym_map[XK_Shift_R] = Key::SHIFT; + xkeysym_map[XK_Shift_Lock] = Key::SHIFT; + xkeysym_map[XK_Control_L] = Key::CTRL; + xkeysym_map[XK_Control_R] = Key::CTRL; + xkeysym_map[XK_Meta_L] = Key::META; + xkeysym_map[XK_Meta_R] = Key::META; + xkeysym_map[XK_Alt_L] = Key::ALT; + xkeysym_map[XK_Alt_R] = Key::ALT; + xkeysym_map[XK_Caps_Lock] = Key::CAPSLOCK; + xkeysym_map[XK_Num_Lock] = Key::NUMLOCK; + xkeysym_map[XK_Scroll_Lock] = Key::SCROLLLOCK; + xkeysym_map[XK_less] = Key::QUOTELEFT; + xkeysym_map[XK_grave] = Key::SECTION; + xkeysym_map[XK_Super_L] = Key::META; + xkeysym_map[XK_Super_R] = Key::META; + xkeysym_map[XK_Menu] = Key::MENU; + xkeysym_map[XK_Hyper_L] = Key::HYPER; + xkeysym_map[XK_Hyper_R] = Key::HYPER; + xkeysym_map[XK_Help] = Key::HELP; + xkeysym_map[XK_KP_Space] = Key::SPACE; + xkeysym_map[XK_KP_Tab] = Key::TAB; + xkeysym_map[XK_KP_Enter] = Key::KP_ENTER; + xkeysym_map[XK_Home] = Key::HOME; + xkeysym_map[XK_Left] = Key::LEFT; + xkeysym_map[XK_Up] = Key::UP; + xkeysym_map[XK_Right] = Key::RIGHT; + xkeysym_map[XK_Down] = Key::DOWN; + xkeysym_map[XK_Prior] = Key::PAGEUP; + xkeysym_map[XK_Next] = Key::PAGEDOWN; + xkeysym_map[XK_End] = Key::END; + xkeysym_map[XK_Begin] = Key::CLEAR; + xkeysym_map[XK_Insert] = Key::INSERT; + xkeysym_map[XK_Delete] = Key::KEY_DELETE; + //xkeysym_map[XK_KP_Equal] + //xkeysym_map[XK_KP_Separator] + xkeysym_map[XK_KP_Decimal] = Key::KP_PERIOD; + xkeysym_map[XK_KP_Delete] = Key::KP_PERIOD; + xkeysym_map[XK_KP_Multiply] = Key::KP_MULTIPLY; + xkeysym_map[XK_KP_Divide] = Key::KP_DIVIDE; + xkeysym_map[XK_KP_Subtract] = Key::KP_SUBTRACT; + xkeysym_map[XK_KP_Add] = Key::KP_ADD; + xkeysym_map[XK_KP_0] = Key::KP_0; + xkeysym_map[XK_KP_1] = Key::KP_1; + xkeysym_map[XK_KP_2] = Key::KP_2; + xkeysym_map[XK_KP_3] = Key::KP_3; + xkeysym_map[XK_KP_4] = Key::KP_4; + xkeysym_map[XK_KP_5] = Key::KP_5; + xkeysym_map[XK_KP_6] = Key::KP_6; + xkeysym_map[XK_KP_7] = Key::KP_7; + xkeysym_map[XK_KP_8] = Key::KP_8; + xkeysym_map[XK_KP_9] = Key::KP_9; + // Same keys but with numlock off. + xkeysym_map[XK_KP_Insert] = Key::INSERT; + xkeysym_map[XK_KP_End] = Key::END; + xkeysym_map[XK_KP_Down] = Key::DOWN; + xkeysym_map[XK_KP_Page_Down] = Key::PAGEDOWN; + xkeysym_map[XK_KP_Left] = Key::LEFT; + // X11 documents this (numpad 5) as "begin of line" but no toolkit seems to interpret it this way. + // On Windows this is emitting Key::Clear so for consistency it will be mapped to Key::Clear + xkeysym_map[XK_KP_Begin] = Key::CLEAR; + xkeysym_map[XK_KP_Right] = Key::RIGHT; + xkeysym_map[XK_KP_Home] = Key::HOME; + xkeysym_map[XK_KP_Up] = Key::UP; + xkeysym_map[XK_KP_Page_Up] = Key::PAGEUP; + xkeysym_map[XK_F1] = Key::F1; + xkeysym_map[XK_F2] = Key::F2; + xkeysym_map[XK_F3] = Key::F3; + xkeysym_map[XK_F4] = Key::F4; + xkeysym_map[XK_F5] = Key::F5; + xkeysym_map[XK_F6] = Key::F6; + xkeysym_map[XK_F7] = Key::F7; + xkeysym_map[XK_F8] = Key::F8; + xkeysym_map[XK_F9] = Key::F9; + xkeysym_map[XK_F10] = Key::F10; + xkeysym_map[XK_F11] = Key::F11; + xkeysym_map[XK_F12] = Key::F12; + xkeysym_map[XK_F13] = Key::F13; + xkeysym_map[XK_F14] = Key::F14; + xkeysym_map[XK_F15] = Key::F15; + xkeysym_map[XK_F16] = Key::F16; + xkeysym_map[XK_F17] = Key::F17; + xkeysym_map[XK_F18] = Key::F18; + xkeysym_map[XK_F19] = Key::F19; + xkeysym_map[XK_F20] = Key::F20; + xkeysym_map[XK_F21] = Key::F21; + xkeysym_map[XK_F22] = Key::F22; + xkeysym_map[XK_F23] = Key::F23; + xkeysym_map[XK_F24] = Key::F24; + xkeysym_map[XK_F25] = Key::F25; + xkeysym_map[XK_F26] = Key::F26; + xkeysym_map[XK_F27] = Key::F27; + xkeysym_map[XK_F28] = Key::F28; + xkeysym_map[XK_F29] = Key::F29; + xkeysym_map[XK_F30] = Key::F30; + xkeysym_map[XK_F31] = Key::F31; + xkeysym_map[XK_F32] = Key::F32; + xkeysym_map[XK_F33] = Key::F33; + xkeysym_map[XK_F34] = Key::F34; + xkeysym_map[XK_F35] = Key::F35; + xkeysym_map[XK_yen] = Key::YEN; + xkeysym_map[XK_section] = Key::SECTION; + // Media keys. + xkeysym_map[XF86XK_Back] = Key::BACK; + xkeysym_map[XF86XK_Forward] = Key::FORWARD; + xkeysym_map[XF86XK_Stop] = Key::STOP; + xkeysym_map[XF86XK_Refresh] = Key::REFRESH; + xkeysym_map[XF86XK_Favorites] = Key::FAVORITES; + xkeysym_map[XF86XK_OpenURL] = Key::OPENURL; + xkeysym_map[XF86XK_HomePage] = Key::HOMEPAGE; + xkeysym_map[XF86XK_Search] = Key::SEARCH; + xkeysym_map[XF86XK_AudioLowerVolume] = Key::VOLUMEDOWN; + xkeysym_map[XF86XK_AudioMute] = Key::VOLUMEMUTE; + xkeysym_map[XF86XK_AudioRaiseVolume] = Key::VOLUMEUP; + xkeysym_map[XF86XK_AudioPlay] = Key::MEDIAPLAY; + xkeysym_map[XF86XK_AudioStop] = Key::MEDIASTOP; + xkeysym_map[XF86XK_AudioPrev] = Key::MEDIAPREVIOUS; + xkeysym_map[XF86XK_AudioNext] = Key::MEDIANEXT; + xkeysym_map[XF86XK_AudioRecord] = Key::MEDIARECORD; + xkeysym_map[XF86XK_Standby] = Key::STANDBY; + // Launch keys. + xkeysym_map[XF86XK_Mail] = Key::LAUNCHMAIL; + xkeysym_map[XF86XK_AudioMedia] = Key::LAUNCHMEDIA; + xkeysym_map[XF86XK_MyComputer] = Key::LAUNCH0; + xkeysym_map[XF86XK_Calculator] = Key::LAUNCH1; + xkeysym_map[XF86XK_Launch0] = Key::LAUNCH2; + xkeysym_map[XF86XK_Launch1] = Key::LAUNCH3; + xkeysym_map[XF86XK_Launch2] = Key::LAUNCH4; + xkeysym_map[XF86XK_Launch3] = Key::LAUNCH5; + xkeysym_map[XF86XK_Launch4] = Key::LAUNCH6; + xkeysym_map[XF86XK_Launch5] = Key::LAUNCH7; + xkeysym_map[XF86XK_Launch6] = Key::LAUNCH8; + xkeysym_map[XF86XK_Launch7] = Key::LAUNCH9; + xkeysym_map[XF86XK_Launch8] = Key::LAUNCHA; + xkeysym_map[XF86XK_Launch9] = Key::LAUNCHB; + xkeysym_map[XF86XK_LaunchA] = Key::LAUNCHC; + xkeysym_map[XF86XK_LaunchB] = Key::LAUNCHD; + xkeysym_map[XF86XK_LaunchC] = Key::LAUNCHE; + xkeysym_map[XF86XK_LaunchD] = Key::LAUNCHF; -static _XTranslatePair _xkeysym_to_keycode[] = { - // misc keys + // Scancode to Godot Key map. + scancode_map[0x09] = Key::ESCAPE; + scancode_map[0x0A] = Key::KEY_1; + scancode_map[0x0B] = Key::KEY_2; + scancode_map[0x0C] = Key::KEY_3; + scancode_map[0x0D] = Key::KEY_4; + scancode_map[0x0E] = Key::KEY_5; + scancode_map[0x0F] = Key::KEY_6; + scancode_map[0x10] = Key::KEY_7; + scancode_map[0x11] = Key::KEY_8; + scancode_map[0x12] = Key::KEY_9; + scancode_map[0x13] = Key::KEY_0; + scancode_map[0x14] = Key::MINUS; + scancode_map[0x15] = Key::EQUAL; + scancode_map[0x16] = Key::BACKSPACE; + scancode_map[0x17] = Key::TAB; + scancode_map[0x18] = Key::Q; + scancode_map[0x19] = Key::W; + scancode_map[0x1A] = Key::E; + scancode_map[0x1B] = Key::R; + scancode_map[0x1C] = Key::T; + scancode_map[0x1D] = Key::Y; + scancode_map[0x1E] = Key::U; + scancode_map[0x1F] = Key::I; + scancode_map[0x20] = Key::O; + scancode_map[0x21] = Key::P; + scancode_map[0x22] = Key::BRACELEFT; + scancode_map[0x23] = Key::BRACERIGHT; + scancode_map[0x24] = Key::ENTER; + scancode_map[0x25] = Key::CTRL; + scancode_map[0x26] = Key::A; + scancode_map[0x27] = Key::S; + scancode_map[0x28] = Key::D; + scancode_map[0x29] = Key::F; + scancode_map[0x2A] = Key::G; + scancode_map[0x2B] = Key::H; + scancode_map[0x2C] = Key::J; + scancode_map[0x2D] = Key::K; + scancode_map[0x2E] = Key::L; + scancode_map[0x2F] = Key::SEMICOLON; + scancode_map[0x30] = Key::APOSTROPHE; + scancode_map[0x31] = Key::SECTION; + scancode_map[0x32] = Key::SHIFT; + scancode_map[0x33] = Key::BACKSLASH; + scancode_map[0x34] = Key::Z; + scancode_map[0x35] = Key::X; + scancode_map[0x36] = Key::C; + scancode_map[0x37] = Key::V; + scancode_map[0x38] = Key::B; + scancode_map[0x39] = Key::N; + scancode_map[0x3A] = Key::M; + scancode_map[0x3B] = Key::COMMA; + scancode_map[0x3C] = Key::PERIOD; + scancode_map[0x3D] = Key::SLASH; + scancode_map[0x3E] = Key::SHIFT; + scancode_map[0x3F] = Key::KP_MULTIPLY; + scancode_map[0x40] = Key::ALT; + scancode_map[0x41] = Key::SPACE; + scancode_map[0x42] = Key::CAPSLOCK; + scancode_map[0x43] = Key::F1; + scancode_map[0x44] = Key::F2; + scancode_map[0x45] = Key::F3; + scancode_map[0x46] = Key::F4; + scancode_map[0x47] = Key::F5; + scancode_map[0x48] = Key::F6; + scancode_map[0x49] = Key::F7; + scancode_map[0x4A] = Key::F8; + scancode_map[0x4B] = Key::F9; + scancode_map[0x4C] = Key::F10; + scancode_map[0x4D] = Key::NUMLOCK; + scancode_map[0x4E] = Key::SCROLLLOCK; + scancode_map[0x4F] = Key::KP_7; + scancode_map[0x50] = Key::KP_8; + scancode_map[0x51] = Key::KP_9; + scancode_map[0x52] = Key::KP_SUBTRACT; + scancode_map[0x53] = Key::KP_4; + scancode_map[0x54] = Key::KP_5; + scancode_map[0x55] = Key::KP_6; + scancode_map[0x56] = Key::KP_ADD; + scancode_map[0x57] = Key::KP_1; + scancode_map[0x58] = Key::KP_2; + scancode_map[0x59] = Key::KP_3; + scancode_map[0x5A] = Key::KP_0; + scancode_map[0x5B] = Key::KP_PERIOD; + scancode_map[0x5E] = Key::QUOTELEFT; + scancode_map[0x5F] = Key::F11; + scancode_map[0x60] = Key::F12; + scancode_map[0x68] = Key::KP_ENTER; + scancode_map[0x69] = Key::CTRL; + scancode_map[0x6A] = Key::KP_DIVIDE; + scancode_map[0x6B] = Key::PRINT; + scancode_map[0x6C] = Key::ALT; + scancode_map[0x6D] = Key::ENTER; + scancode_map[0x6E] = Key::HOME; + scancode_map[0x6F] = Key::UP; + scancode_map[0x70] = Key::PAGEUP; + scancode_map[0x71] = Key::LEFT; + scancode_map[0x72] = Key::RIGHT; + scancode_map[0x73] = Key::END; + scancode_map[0x74] = Key::DOWN; + scancode_map[0x75] = Key::PAGEDOWN; + scancode_map[0x76] = Key::INSERT; + scancode_map[0x77] = Key::KEY_DELETE; + scancode_map[0x79] = Key::VOLUMEMUTE; + scancode_map[0x7A] = Key::VOLUMEDOWN; + scancode_map[0x7B] = Key::VOLUMEUP; + scancode_map[0x7F] = Key::PAUSE; + scancode_map[0x85] = Key::META; + scancode_map[0x86] = Key::META; + scancode_map[0x87] = Key::MENU; + scancode_map[0xBF] = Key::F13; + scancode_map[0xC0] = Key::F14; + scancode_map[0xC1] = Key::F15; + scancode_map[0xC2] = Key::F16; + scancode_map[0xC3] = Key::F17; + scancode_map[0xC4] = Key::F18; + scancode_map[0xC5] = Key::F19; + scancode_map[0xC6] = Key::F20; + scancode_map[0xC7] = Key::F21; + scancode_map[0xC8] = Key::F22; + scancode_map[0xC9] = Key::F23; + scancode_map[0xCA] = Key::F24; + scancode_map[0xCB] = Key::F25; + scancode_map[0xCC] = Key::F26; + scancode_map[0xCD] = Key::F27; + scancode_map[0xCE] = Key::F28; + scancode_map[0xCF] = Key::F29; + scancode_map[0xD0] = Key::F30; + scancode_map[0xD1] = Key::F31; + scancode_map[0xD2] = Key::F32; + scancode_map[0xD3] = Key::F33; + scancode_map[0xD4] = Key::F34; + scancode_map[0xD5] = Key::F35; - { XK_Escape, Key::ESCAPE }, - { XK_Tab, Key::TAB }, - { XK_ISO_Left_Tab, Key::BACKTAB }, - { XK_BackSpace, Key::BACKSPACE }, - { XK_Return, Key::ENTER }, - { XK_Insert, Key::INSERT }, - { XK_Delete, Key::KEY_DELETE }, - { XK_Clear, Key::KEY_DELETE }, - { XK_Pause, Key::PAUSE }, - { XK_Print, Key::PRINT }, - { XK_Home, Key::HOME }, - { XK_End, Key::END }, - { XK_Left, Key::LEFT }, - { XK_Up, Key::UP }, - { XK_Right, Key::RIGHT }, - { XK_Down, Key::DOWN }, - { XK_Prior, Key::PAGEUP }, - { XK_Next, Key::PAGEDOWN }, - { XK_Shift_L, Key::SHIFT }, - { XK_Shift_R, Key::SHIFT }, - { XK_Shift_Lock, Key::SHIFT }, - { XK_Control_L, Key::CTRL }, - { XK_Control_R, Key::CTRL }, - { XK_Meta_L, Key::META }, - { XK_Meta_R, Key::META }, - { XK_Alt_L, Key::ALT }, - { XK_Alt_R, Key::ALT }, - { XK_Caps_Lock, Key::CAPSLOCK }, - { XK_Num_Lock, Key::NUMLOCK }, - { XK_Scroll_Lock, Key::SCROLLLOCK }, - { XK_Super_L, Key::SUPER_L }, - { XK_Super_R, Key::SUPER_R }, - { XK_Menu, Key::MENU }, - { XK_Hyper_L, Key::HYPER_L }, - { XK_Hyper_R, Key::HYPER_R }, - { XK_Help, Key::HELP }, - { XK_KP_Space, Key::SPACE }, - { XK_KP_Tab, Key::TAB }, - { XK_KP_Enter, Key::KP_ENTER }, - { XK_Home, Key::HOME }, - { XK_Left, Key::LEFT }, - { XK_Up, Key::UP }, - { XK_Right, Key::RIGHT }, - { XK_Down, Key::DOWN }, - { XK_Prior, Key::PAGEUP }, - { XK_Next, Key::PAGEDOWN }, - { XK_End, Key::END }, - { XK_Begin, Key::CLEAR }, - { XK_Insert, Key::INSERT }, - { XK_Delete, Key::KEY_DELETE }, - //{ XK_KP_Equal, Key::EQUAL }, - //{ XK_KP_Separator, Key::COMMA }, - { XK_KP_Decimal, Key::KP_PERIOD }, - { XK_KP_Delete, Key::KP_PERIOD }, - { XK_KP_Multiply, Key::KP_MULTIPLY }, - { XK_KP_Divide, Key::KP_DIVIDE }, - { XK_KP_Subtract, Key::KP_SUBTRACT }, - { XK_KP_Add, Key::KP_ADD }, - { XK_KP_0, Key::KP_0 }, - { XK_KP_1, Key::KP_1 }, - { XK_KP_2, Key::KP_2 }, - { XK_KP_3, Key::KP_3 }, - { XK_KP_4, Key::KP_4 }, - { XK_KP_5, Key::KP_5 }, - { XK_KP_6, Key::KP_6 }, - { XK_KP_7, Key::KP_7 }, - { XK_KP_8, Key::KP_8 }, - { XK_KP_9, Key::KP_9 }, - // same keys but with numlock off - { XK_KP_Insert, Key::INSERT }, - { XK_KP_End, Key::END }, - { XK_KP_Down, Key::DOWN }, - { XK_KP_Page_Down, Key::PAGEDOWN }, - { XK_KP_Left, Key::LEFT }, - // X11 documents this (numpad 5) as "begin of line" but no toolkit - // seems to interpret it this way. - // On Windows this is emitting Key::Clear so for consistency it - // will be mapped to Key::Clear - { XK_KP_Begin, Key::CLEAR }, - { XK_KP_Right, Key::RIGHT }, - { XK_KP_Home, Key::HOME }, - { XK_KP_Up, Key::UP }, - { XK_KP_Page_Up, Key::PAGEUP }, - { XK_F1, Key::F1 }, - { XK_F2, Key::F2 }, - { XK_F3, Key::F3 }, - { XK_F4, Key::F4 }, - { XK_F5, Key::F5 }, - { XK_F6, Key::F6 }, - { XK_F7, Key::F7 }, - { XK_F8, Key::F8 }, - { XK_F9, Key::F9 }, - { XK_F10, Key::F10 }, - { XK_F11, Key::F11 }, - { XK_F12, Key::F12 }, - { XK_F13, Key::F13 }, - { XK_F14, Key::F14 }, - { XK_F15, Key::F15 }, - { XK_F16, Key::F16 }, - { XK_F17, Key::F17 }, - { XK_F18, Key::F18 }, - { XK_F19, Key::F19 }, - { XK_F20, Key::F20 }, - { XK_F21, Key::F21 }, - { XK_F22, Key::F22 }, - { XK_F23, Key::F23 }, - { XK_F24, Key::F24 }, - { XK_F25, Key::F25 }, - { XK_F26, Key::F26 }, - { XK_F27, Key::F27 }, - { XK_F28, Key::F28 }, - { XK_F29, Key::F29 }, - { XK_F30, Key::F30 }, - { XK_F31, Key::F31 }, - { XK_F32, Key::F32 }, - { XK_F33, Key::F33 }, - { XK_F34, Key::F34 }, - { XK_F35, Key::F35 }, - - // media keys - { XF86XK_Back, Key::BACK }, - { XF86XK_Forward, Key::FORWARD }, - { XF86XK_Stop, Key::STOP }, - { XF86XK_Refresh, Key::REFRESH }, - { XF86XK_Favorites, Key::FAVORITES }, - { XF86XK_AudioMedia, Key::LAUNCHMEDIA }, - { XF86XK_OpenURL, Key::OPENURL }, - { XF86XK_HomePage, Key::HOMEPAGE }, - { XF86XK_Search, Key::SEARCH }, - { XF86XK_AudioLowerVolume, Key::VOLUMEDOWN }, - { XF86XK_AudioMute, Key::VOLUMEMUTE }, - { XF86XK_AudioRaiseVolume, Key::VOLUMEUP }, - { XF86XK_AudioPlay, Key::MEDIAPLAY }, - { XF86XK_AudioStop, Key::MEDIASTOP }, - { XF86XK_AudioPrev, Key::MEDIAPREVIOUS }, - { XF86XK_AudioNext, Key::MEDIANEXT }, - { XF86XK_AudioRecord, Key::MEDIARECORD }, - - // launch keys - { XF86XK_Mail, Key::LAUNCHMAIL }, - { XF86XK_MyComputer, Key::LAUNCH0 }, - { XF86XK_Calculator, Key::LAUNCH1 }, - { XF86XK_Standby, Key::STANDBY }, - - { XF86XK_Launch0, Key::LAUNCH2 }, - { XF86XK_Launch1, Key::LAUNCH3 }, - { XF86XK_Launch2, Key::LAUNCH4 }, - { XF86XK_Launch3, Key::LAUNCH5 }, - { XF86XK_Launch4, Key::LAUNCH6 }, - { XF86XK_Launch5, Key::LAUNCH7 }, - { XF86XK_Launch6, Key::LAUNCH8 }, - { XF86XK_Launch7, Key::LAUNCH9 }, - { XF86XK_Launch8, Key::LAUNCHA }, - { XF86XK_Launch9, Key::LAUNCHB }, - { XF86XK_LaunchA, Key::LAUNCHC }, - { XF86XK_LaunchB, Key::LAUNCHD }, - { XF86XK_LaunchC, Key::LAUNCHE }, - { XF86XK_LaunchD, Key::LAUNCHF }, - - { 0, Key::NONE } -}; - -struct _TranslatePair { - Key keysym; - unsigned int keycode; -}; - -static _TranslatePair _scancode_to_keycode[] = { - { Key::ESCAPE, 0x09 }, - { Key::KEY_1, 0x0A }, - { Key::KEY_2, 0x0B }, - { Key::KEY_3, 0x0C }, - { Key::KEY_4, 0x0D }, - { Key::KEY_5, 0x0E }, - { Key::KEY_6, 0x0F }, - { Key::KEY_7, 0x10 }, - { Key::KEY_8, 0x11 }, - { Key::KEY_9, 0x12 }, - { Key::KEY_0, 0x13 }, - { Key::MINUS, 0x14 }, - { Key::EQUAL, 0x15 }, - { Key::BACKSPACE, 0x16 }, - { Key::TAB, 0x17 }, - { Key::Q, 0x18 }, - { Key::W, 0x19 }, - { Key::E, 0x1A }, - { Key::R, 0x1B }, - { Key::T, 0x1C }, - { Key::Y, 0x1D }, - { Key::U, 0x1E }, - { Key::I, 0x1F }, - { Key::O, 0x20 }, - { Key::P, 0x21 }, - { Key::BRACELEFT, 0x22 }, - { Key::BRACERIGHT, 0x23 }, - { Key::ENTER, 0x24 }, - { Key::CTRL, 0x25 }, - { Key::A, 0x26 }, - { Key::S, 0x27 }, - { Key::D, 0x28 }, - { Key::F, 0x29 }, - { Key::G, 0x2A }, - { Key::H, 0x2B }, - { Key::J, 0x2C }, - { Key::K, 0x2D }, - { Key::L, 0x2E }, - { Key::SEMICOLON, 0x2F }, - { Key::APOSTROPHE, 0x30 }, - { Key::QUOTELEFT, 0x31 }, - { Key::SHIFT, 0x32 }, - { Key::BACKSLASH, 0x33 }, - { Key::Z, 0x34 }, - { Key::X, 0x35 }, - { Key::C, 0x36 }, - { Key::V, 0x37 }, - { Key::B, 0x38 }, - { Key::N, 0x39 }, - { Key::M, 0x3A }, - { Key::COMMA, 0x3B }, - { Key::PERIOD, 0x3C }, - { Key::SLASH, 0x3D }, - { Key::SHIFT, 0x3E }, - { Key::KP_MULTIPLY, 0x3F }, - { Key::ALT, 0x40 }, - { Key::SPACE, 0x41 }, - { Key::CAPSLOCK, 0x42 }, - { Key::F1, 0x43 }, - { Key::F2, 0x44 }, - { Key::F3, 0x45 }, - { Key::F4, 0x46 }, - { Key::F5, 0x47 }, - { Key::F6, 0x48 }, - { Key::F7, 0x49 }, - { Key::F8, 0x4A }, - { Key::F9, 0x4B }, - { Key::F10, 0x4C }, - { Key::NUMLOCK, 0x4D }, - { Key::SCROLLLOCK, 0x4E }, - { Key::KP_7, 0x4F }, - { Key::KP_8, 0x50 }, - { Key::KP_9, 0x51 }, - { Key::KP_SUBTRACT, 0x52 }, - { Key::KP_4, 0x53 }, - { Key::KP_5, 0x54 }, - { Key::KP_6, 0x55 }, - { Key::KP_ADD, 0x56 }, - { Key::KP_1, 0x57 }, - { Key::KP_2, 0x58 }, - { Key::KP_3, 0x59 }, - { Key::KP_0, 0x5A }, - { Key::KP_PERIOD, 0x5B }, - //{ Key::???, 0x5E }, //NON US BACKSLASH - { Key::F11, 0x5F }, - { Key::F12, 0x60 }, - { Key::KP_ENTER, 0x68 }, - { Key::CTRL, 0x69 }, - { Key::KP_DIVIDE, 0x6A }, - { Key::PRINT, 0x6B }, - { Key::ALT, 0x6C }, - { Key::ENTER, 0x6D }, - { Key::HOME, 0x6E }, - { Key::UP, 0x6F }, - { Key::PAGEUP, 0x70 }, - { Key::LEFT, 0x71 }, - { Key::RIGHT, 0x72 }, - { Key::END, 0x73 }, - { Key::DOWN, 0x74 }, - { Key::PAGEDOWN, 0x75 }, - { Key::INSERT, 0x76 }, - { Key::KEY_DELETE, 0x77 }, - { Key::VOLUMEMUTE, 0x79 }, - { Key::VOLUMEDOWN, 0x7A }, - { Key::VOLUMEUP, 0x7B }, - { Key::PAUSE, 0x7F }, - { Key::SUPER_L, 0x85 }, - { Key::SUPER_R, 0x86 }, - { Key::MENU, 0x87 }, - { Key::F13, 0xBF }, - { Key::F14, 0xC0 }, - { Key::F15, 0xC1 }, - { Key::F16, 0xC2 }, - { Key::F17, 0xC3 }, - { Key::F18, 0xC4 }, - { Key::F19, 0xC5 }, - { Key::F20, 0xC6 }, - { Key::F21, 0xC7 }, - { Key::F22, 0xC8 }, - { Key::F23, 0xC9 }, - { Key::F24, 0xCA }, - { Key::F25, 0xCB }, - { Key::F26, 0xCC }, - { Key::F27, 0xCD }, - { Key::F28, 0xCE }, - { Key::F29, 0xCF }, - { Key::F30, 0xD0 }, - { Key::F31, 0xD1 }, - { Key::F32, 0xD2 }, - { Key::F33, 0xD3 }, - { Key::F34, 0xD4 }, - { Key::F35, 0xD5 }, - { Key::UNKNOWN, 0 } -}; - -Key KeyMappingX11::get_scancode(unsigned int p_code) { - Key keycode = Key::UNKNOWN; - for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_scancode_to_keycode[i].keycode == p_code) { - keycode = _scancode_to_keycode[i].keysym; - break; - } + // Godot to scancode map. + for (const KeyValue<unsigned int, Key> &E : scancode_map) { + scancode_map_inv[E.value] = E.key; } - return keycode; + // Keysym to Unicode map, tables taken from FOX toolkit. + xkeysym_unicode_map[0x01A1] = 0x0104; + xkeysym_unicode_map[0x01A2] = 0x02D8; + xkeysym_unicode_map[0x01A3] = 0x0141; + xkeysym_unicode_map[0x01A5] = 0x013D; + xkeysym_unicode_map[0x01A6] = 0x015A; + xkeysym_unicode_map[0x01A9] = 0x0160; + xkeysym_unicode_map[0x01AA] = 0x015E; + xkeysym_unicode_map[0x01AB] = 0x0164; + xkeysym_unicode_map[0x01AC] = 0x0179; + xkeysym_unicode_map[0x01AE] = 0x017D; + xkeysym_unicode_map[0x01AF] = 0x017B; + xkeysym_unicode_map[0x01B1] = 0x0105; + xkeysym_unicode_map[0x01B2] = 0x02DB; + xkeysym_unicode_map[0x01B3] = 0x0142; + xkeysym_unicode_map[0x01B5] = 0x013E; + xkeysym_unicode_map[0x01B6] = 0x015B; + xkeysym_unicode_map[0x01B7] = 0x02C7; + xkeysym_unicode_map[0x01B9] = 0x0161; + xkeysym_unicode_map[0x01BA] = 0x015F; + xkeysym_unicode_map[0x01BB] = 0x0165; + xkeysym_unicode_map[0x01BC] = 0x017A; + xkeysym_unicode_map[0x01BD] = 0x02DD; + xkeysym_unicode_map[0x01BE] = 0x017E; + xkeysym_unicode_map[0x01BF] = 0x017C; + xkeysym_unicode_map[0x01C0] = 0x0154; + xkeysym_unicode_map[0x01C3] = 0x0102; + xkeysym_unicode_map[0x01C5] = 0x0139; + xkeysym_unicode_map[0x01C6] = 0x0106; + xkeysym_unicode_map[0x01C8] = 0x010C; + xkeysym_unicode_map[0x01CA] = 0x0118; + xkeysym_unicode_map[0x01CC] = 0x011A; + xkeysym_unicode_map[0x01CF] = 0x010E; + xkeysym_unicode_map[0x01D0] = 0x0110; + xkeysym_unicode_map[0x01D1] = 0x0143; + xkeysym_unicode_map[0x01D2] = 0x0147; + xkeysym_unicode_map[0x01D5] = 0x0150; + xkeysym_unicode_map[0x01D8] = 0x0158; + xkeysym_unicode_map[0x01D9] = 0x016E; + xkeysym_unicode_map[0x01DB] = 0x0170; + xkeysym_unicode_map[0x01DE] = 0x0162; + xkeysym_unicode_map[0x01E0] = 0x0155; + xkeysym_unicode_map[0x01E3] = 0x0103; + xkeysym_unicode_map[0x01E5] = 0x013A; + xkeysym_unicode_map[0x01E6] = 0x0107; + xkeysym_unicode_map[0x01E8] = 0x010D; + xkeysym_unicode_map[0x01EA] = 0x0119; + xkeysym_unicode_map[0x01EC] = 0x011B; + xkeysym_unicode_map[0x01EF] = 0x010F; + xkeysym_unicode_map[0x01F0] = 0x0111; + xkeysym_unicode_map[0x01F1] = 0x0144; + xkeysym_unicode_map[0x01F2] = 0x0148; + xkeysym_unicode_map[0x01F5] = 0x0151; + xkeysym_unicode_map[0x01F8] = 0x0159; + xkeysym_unicode_map[0x01F9] = 0x016F; + xkeysym_unicode_map[0x01FB] = 0x0171; + xkeysym_unicode_map[0x01FE] = 0x0163; + xkeysym_unicode_map[0x01FF] = 0x02D9; + xkeysym_unicode_map[0x02A1] = 0x0126; + xkeysym_unicode_map[0x02A6] = 0x0124; + xkeysym_unicode_map[0x02A9] = 0x0130; + xkeysym_unicode_map[0x02AB] = 0x011E; + xkeysym_unicode_map[0x02AC] = 0x0134; + xkeysym_unicode_map[0x02B1] = 0x0127; + xkeysym_unicode_map[0x02B6] = 0x0125; + xkeysym_unicode_map[0x02B9] = 0x0131; + xkeysym_unicode_map[0x02BB] = 0x011F; + xkeysym_unicode_map[0x02BC] = 0x0135; + xkeysym_unicode_map[0x02C5] = 0x010A; + xkeysym_unicode_map[0x02C6] = 0x0108; + xkeysym_unicode_map[0x02D5] = 0x0120; + xkeysym_unicode_map[0x02D8] = 0x011C; + xkeysym_unicode_map[0x02DD] = 0x016C; + xkeysym_unicode_map[0x02DE] = 0x015C; + xkeysym_unicode_map[0x02E5] = 0x010B; + xkeysym_unicode_map[0x02E6] = 0x0109; + xkeysym_unicode_map[0x02F5] = 0x0121; + xkeysym_unicode_map[0x02F8] = 0x011D; + xkeysym_unicode_map[0x02FD] = 0x016D; + xkeysym_unicode_map[0x02FE] = 0x015D; + xkeysym_unicode_map[0x03A2] = 0x0138; + xkeysym_unicode_map[0x03A3] = 0x0156; + xkeysym_unicode_map[0x03A5] = 0x0128; + xkeysym_unicode_map[0x03A6] = 0x013B; + xkeysym_unicode_map[0x03AA] = 0x0112; + xkeysym_unicode_map[0x03AB] = 0x0122; + xkeysym_unicode_map[0x03AC] = 0x0166; + xkeysym_unicode_map[0x03B3] = 0x0157; + xkeysym_unicode_map[0x03B5] = 0x0129; + xkeysym_unicode_map[0x03B6] = 0x013C; + xkeysym_unicode_map[0x03BA] = 0x0113; + xkeysym_unicode_map[0x03BB] = 0x0123; + xkeysym_unicode_map[0x03BC] = 0x0167; + xkeysym_unicode_map[0x03BD] = 0x014A; + xkeysym_unicode_map[0x03BF] = 0x014B; + xkeysym_unicode_map[0x03C0] = 0x0100; + xkeysym_unicode_map[0x03C7] = 0x012E; + xkeysym_unicode_map[0x03CC] = 0x0116; + xkeysym_unicode_map[0x03CF] = 0x012A; + xkeysym_unicode_map[0x03D1] = 0x0145; + xkeysym_unicode_map[0x03D2] = 0x014C; + xkeysym_unicode_map[0x03D3] = 0x0136; + xkeysym_unicode_map[0x03D9] = 0x0172; + xkeysym_unicode_map[0x03DD] = 0x0168; + xkeysym_unicode_map[0x03DE] = 0x016A; + xkeysym_unicode_map[0x03E0] = 0x0101; + xkeysym_unicode_map[0x03E7] = 0x012F; + xkeysym_unicode_map[0x03EC] = 0x0117; + xkeysym_unicode_map[0x03EF] = 0x012B; + xkeysym_unicode_map[0x03F1] = 0x0146; + xkeysym_unicode_map[0x03F2] = 0x014D; + xkeysym_unicode_map[0x03F3] = 0x0137; + xkeysym_unicode_map[0x03F9] = 0x0173; + xkeysym_unicode_map[0x03FD] = 0x0169; + xkeysym_unicode_map[0x03FE] = 0x016B; + xkeysym_unicode_map[0x047E] = 0x203E; + xkeysym_unicode_map[0x04A1] = 0x3002; + xkeysym_unicode_map[0x04A2] = 0x300C; + xkeysym_unicode_map[0x04A3] = 0x300D; + xkeysym_unicode_map[0x04A4] = 0x3001; + xkeysym_unicode_map[0x04A5] = 0x30FB; + xkeysym_unicode_map[0x04A6] = 0x30F2; + xkeysym_unicode_map[0x04A7] = 0x30A1; + xkeysym_unicode_map[0x04A8] = 0x30A3; + xkeysym_unicode_map[0x04A9] = 0x30A5; + xkeysym_unicode_map[0x04AA] = 0x30A7; + xkeysym_unicode_map[0x04AB] = 0x30A9; + xkeysym_unicode_map[0x04AC] = 0x30E3; + xkeysym_unicode_map[0x04AD] = 0x30E5; + xkeysym_unicode_map[0x04AE] = 0x30E7; + xkeysym_unicode_map[0x04AF] = 0x30C3; + xkeysym_unicode_map[0x04B0] = 0x30FC; + xkeysym_unicode_map[0x04B1] = 0x30A2; + xkeysym_unicode_map[0x04B2] = 0x30A4; + xkeysym_unicode_map[0x04B3] = 0x30A6; + xkeysym_unicode_map[0x04B4] = 0x30A8; + xkeysym_unicode_map[0x04B5] = 0x30AA; + xkeysym_unicode_map[0x04B6] = 0x30AB; + xkeysym_unicode_map[0x04B7] = 0x30AD; + xkeysym_unicode_map[0x04B8] = 0x30AF; + xkeysym_unicode_map[0x04B9] = 0x30B1; + xkeysym_unicode_map[0x04BA] = 0x30B3; + xkeysym_unicode_map[0x04BB] = 0x30B5; + xkeysym_unicode_map[0x04BC] = 0x30B7; + xkeysym_unicode_map[0x04BD] = 0x30B9; + xkeysym_unicode_map[0x04BE] = 0x30BB; + xkeysym_unicode_map[0x04BF] = 0x30BD; + xkeysym_unicode_map[0x04C0] = 0x30BF; + xkeysym_unicode_map[0x04C1] = 0x30C1; + xkeysym_unicode_map[0x04C2] = 0x30C4; + xkeysym_unicode_map[0x04C3] = 0x30C6; + xkeysym_unicode_map[0x04C4] = 0x30C8; + xkeysym_unicode_map[0x04C5] = 0x30CA; + xkeysym_unicode_map[0x04C6] = 0x30CB; + xkeysym_unicode_map[0x04C7] = 0x30CC; + xkeysym_unicode_map[0x04C8] = 0x30CD; + xkeysym_unicode_map[0x04C9] = 0x30CE; + xkeysym_unicode_map[0x04CA] = 0x30CF; + xkeysym_unicode_map[0x04CB] = 0x30D2; + xkeysym_unicode_map[0x04CC] = 0x30D5; + xkeysym_unicode_map[0x04CD] = 0x30D8; + xkeysym_unicode_map[0x04CE] = 0x30DB; + xkeysym_unicode_map[0x04CF] = 0x30DE; + xkeysym_unicode_map[0x04D0] = 0x30DF; + xkeysym_unicode_map[0x04D1] = 0x30E0; + xkeysym_unicode_map[0x04D2] = 0x30E1; + xkeysym_unicode_map[0x04D3] = 0x30E2; + xkeysym_unicode_map[0x04D4] = 0x30E4; + xkeysym_unicode_map[0x04D5] = 0x30E6; + xkeysym_unicode_map[0x04D6] = 0x30E8; + xkeysym_unicode_map[0x04D7] = 0x30E9; + xkeysym_unicode_map[0x04D8] = 0x30EA; + xkeysym_unicode_map[0x04D9] = 0x30EB; + xkeysym_unicode_map[0x04DA] = 0x30EC; + xkeysym_unicode_map[0x04DB] = 0x30ED; + xkeysym_unicode_map[0x04DC] = 0x30EF; + xkeysym_unicode_map[0x04DD] = 0x30F3; + xkeysym_unicode_map[0x04DE] = 0x309B; + xkeysym_unicode_map[0x04DF] = 0x309C; + xkeysym_unicode_map[0x05AC] = 0x060C; + xkeysym_unicode_map[0x05BB] = 0x061B; + xkeysym_unicode_map[0x05BF] = 0x061F; + xkeysym_unicode_map[0x05C1] = 0x0621; + xkeysym_unicode_map[0x05C2] = 0x0622; + xkeysym_unicode_map[0x05C3] = 0x0623; + xkeysym_unicode_map[0x05C4] = 0x0624; + xkeysym_unicode_map[0x05C5] = 0x0625; + xkeysym_unicode_map[0x05C6] = 0x0626; + xkeysym_unicode_map[0x05C7] = 0x0627; + xkeysym_unicode_map[0x05C8] = 0x0628; + xkeysym_unicode_map[0x05C9] = 0x0629; + xkeysym_unicode_map[0x05CA] = 0x062A; + xkeysym_unicode_map[0x05CB] = 0x062B; + xkeysym_unicode_map[0x05CC] = 0x062C; + xkeysym_unicode_map[0x05CD] = 0x062D; + xkeysym_unicode_map[0x05CE] = 0x062E; + xkeysym_unicode_map[0x05CF] = 0x062F; + xkeysym_unicode_map[0x05D0] = 0x0630; + xkeysym_unicode_map[0x05D1] = 0x0631; + xkeysym_unicode_map[0x05D2] = 0x0632; + xkeysym_unicode_map[0x05D3] = 0x0633; + xkeysym_unicode_map[0x05D4] = 0x0634; + xkeysym_unicode_map[0x05D5] = 0x0635; + xkeysym_unicode_map[0x05D6] = 0x0636; + xkeysym_unicode_map[0x05D7] = 0x0637; + xkeysym_unicode_map[0x05D8] = 0x0638; + xkeysym_unicode_map[0x05D9] = 0x0639; + xkeysym_unicode_map[0x05DA] = 0x063A; + xkeysym_unicode_map[0x05E0] = 0x0640; + xkeysym_unicode_map[0x05E1] = 0x0641; + xkeysym_unicode_map[0x05E2] = 0x0642; + xkeysym_unicode_map[0x05E3] = 0x0643; + xkeysym_unicode_map[0x05E4] = 0x0644; + xkeysym_unicode_map[0x05E5] = 0x0645; + xkeysym_unicode_map[0x05E6] = 0x0646; + xkeysym_unicode_map[0x05E7] = 0x0647; + xkeysym_unicode_map[0x05E8] = 0x0648; + xkeysym_unicode_map[0x05E9] = 0x0649; + xkeysym_unicode_map[0x05EA] = 0x064A; + xkeysym_unicode_map[0x05EB] = 0x064B; + xkeysym_unicode_map[0x05EC] = 0x064C; + xkeysym_unicode_map[0x05ED] = 0x064D; + xkeysym_unicode_map[0x05EE] = 0x064E; + xkeysym_unicode_map[0x05EF] = 0x064F; + xkeysym_unicode_map[0x05F0] = 0x0650; + xkeysym_unicode_map[0x05F1] = 0x0651; + xkeysym_unicode_map[0x05F2] = 0x0652; + xkeysym_unicode_map[0x06A1] = 0x0452; + xkeysym_unicode_map[0x06A2] = 0x0453; + xkeysym_unicode_map[0x06A3] = 0x0451; + xkeysym_unicode_map[0x06A4] = 0x0454; + xkeysym_unicode_map[0x06A5] = 0x0455; + xkeysym_unicode_map[0x06A6] = 0x0456; + xkeysym_unicode_map[0x06A7] = 0x0457; + xkeysym_unicode_map[0x06A8] = 0x0458; + xkeysym_unicode_map[0x06A9] = 0x0459; + xkeysym_unicode_map[0x06AA] = 0x045A; + xkeysym_unicode_map[0x06AB] = 0x045B; + xkeysym_unicode_map[0x06AC] = 0x045C; + xkeysym_unicode_map[0x06AE] = 0x045E; + xkeysym_unicode_map[0x06AF] = 0x045F; + xkeysym_unicode_map[0x06B0] = 0x2116; + xkeysym_unicode_map[0x06B1] = 0x0402; + xkeysym_unicode_map[0x06B2] = 0x0403; + xkeysym_unicode_map[0x06B3] = 0x0401; + xkeysym_unicode_map[0x06B4] = 0x0404; + xkeysym_unicode_map[0x06B5] = 0x0405; + xkeysym_unicode_map[0x06B6] = 0x0406; + xkeysym_unicode_map[0x06B7] = 0x0407; + xkeysym_unicode_map[0x06B8] = 0x0408; + xkeysym_unicode_map[0x06B9] = 0x0409; + xkeysym_unicode_map[0x06BA] = 0x040A; + xkeysym_unicode_map[0x06BB] = 0x040B; + xkeysym_unicode_map[0x06BC] = 0x040C; + xkeysym_unicode_map[0x06BE] = 0x040E; + xkeysym_unicode_map[0x06BF] = 0x040F; + xkeysym_unicode_map[0x06C0] = 0x044E; + xkeysym_unicode_map[0x06C1] = 0x0430; + xkeysym_unicode_map[0x06C2] = 0x0431; + xkeysym_unicode_map[0x06C3] = 0x0446; + xkeysym_unicode_map[0x06C4] = 0x0434; + xkeysym_unicode_map[0x06C5] = 0x0435; + xkeysym_unicode_map[0x06C6] = 0x0444; + xkeysym_unicode_map[0x06C7] = 0x0433; + xkeysym_unicode_map[0x06C8] = 0x0445; + xkeysym_unicode_map[0x06C9] = 0x0438; + xkeysym_unicode_map[0x06CA] = 0x0439; + xkeysym_unicode_map[0x06CB] = 0x043A; + xkeysym_unicode_map[0x06CC] = 0x043B; + xkeysym_unicode_map[0x06CD] = 0x043C; + xkeysym_unicode_map[0x06CE] = 0x043D; + xkeysym_unicode_map[0x06CF] = 0x043E; + xkeysym_unicode_map[0x06D0] = 0x043F; + xkeysym_unicode_map[0x06D1] = 0x044F; + xkeysym_unicode_map[0x06D2] = 0x0440; + xkeysym_unicode_map[0x06D3] = 0x0441; + xkeysym_unicode_map[0x06D4] = 0x0442; + xkeysym_unicode_map[0x06D5] = 0x0443; + xkeysym_unicode_map[0x06D6] = 0x0436; + xkeysym_unicode_map[0x06D7] = 0x0432; + xkeysym_unicode_map[0x06D8] = 0x044C; + xkeysym_unicode_map[0x06D9] = 0x044B; + xkeysym_unicode_map[0x06DA] = 0x0437; + xkeysym_unicode_map[0x06DB] = 0x0448; + xkeysym_unicode_map[0x06DC] = 0x044D; + xkeysym_unicode_map[0x06DD] = 0x0449; + xkeysym_unicode_map[0x06DE] = 0x0447; + xkeysym_unicode_map[0x06DF] = 0x044A; + xkeysym_unicode_map[0x06E0] = 0x042E; + xkeysym_unicode_map[0x06E1] = 0x0410; + xkeysym_unicode_map[0x06E2] = 0x0411; + xkeysym_unicode_map[0x06E3] = 0x0426; + xkeysym_unicode_map[0x06E4] = 0x0414; + xkeysym_unicode_map[0x06E5] = 0x0415; + xkeysym_unicode_map[0x06E6] = 0x0424; + xkeysym_unicode_map[0x06E7] = 0x0413; + xkeysym_unicode_map[0x06E8] = 0x0425; + xkeysym_unicode_map[0x06E9] = 0x0418; + xkeysym_unicode_map[0x06EA] = 0x0419; + xkeysym_unicode_map[0x06EB] = 0x041A; + xkeysym_unicode_map[0x06EC] = 0x041B; + xkeysym_unicode_map[0x06ED] = 0x041C; + xkeysym_unicode_map[0x06EE] = 0x041D; + xkeysym_unicode_map[0x06EF] = 0x041E; + xkeysym_unicode_map[0x06F0] = 0x041F; + xkeysym_unicode_map[0x06F1] = 0x042F; + xkeysym_unicode_map[0x06F2] = 0x0420; + xkeysym_unicode_map[0x06F3] = 0x0421; + xkeysym_unicode_map[0x06F4] = 0x0422; + xkeysym_unicode_map[0x06F5] = 0x0423; + xkeysym_unicode_map[0x06F6] = 0x0416; + xkeysym_unicode_map[0x06F7] = 0x0412; + xkeysym_unicode_map[0x06F8] = 0x042C; + xkeysym_unicode_map[0x06F9] = 0x042B; + xkeysym_unicode_map[0x06FA] = 0x0417; + xkeysym_unicode_map[0x06FB] = 0x0428; + xkeysym_unicode_map[0x06FC] = 0x042D; + xkeysym_unicode_map[0x06FD] = 0x0429; + xkeysym_unicode_map[0x06FE] = 0x0427; + xkeysym_unicode_map[0x06FF] = 0x042A; + xkeysym_unicode_map[0x07A1] = 0x0386; + xkeysym_unicode_map[0x07A2] = 0x0388; + xkeysym_unicode_map[0x07A3] = 0x0389; + xkeysym_unicode_map[0x07A4] = 0x038A; + xkeysym_unicode_map[0x07A5] = 0x03AA; + xkeysym_unicode_map[0x07A7] = 0x038C; + xkeysym_unicode_map[0x07A8] = 0x038E; + xkeysym_unicode_map[0x07A9] = 0x03AB; + xkeysym_unicode_map[0x07AB] = 0x038F; + xkeysym_unicode_map[0x07AE] = 0x0385; + xkeysym_unicode_map[0x07AF] = 0x2015; + xkeysym_unicode_map[0x07B1] = 0x03AC; + xkeysym_unicode_map[0x07B2] = 0x03AD; + xkeysym_unicode_map[0x07B3] = 0x03AE; + xkeysym_unicode_map[0x07B4] = 0x03AF; + xkeysym_unicode_map[0x07B5] = 0x03CA; + xkeysym_unicode_map[0x07B6] = 0x0390; + xkeysym_unicode_map[0x07B7] = 0x03CC; + xkeysym_unicode_map[0x07B8] = 0x03CD; + xkeysym_unicode_map[0x07B9] = 0x03CB; + xkeysym_unicode_map[0x07BA] = 0x03B0; + xkeysym_unicode_map[0x07BB] = 0x03CE; + xkeysym_unicode_map[0x07C1] = 0x0391; + xkeysym_unicode_map[0x07C2] = 0x0392; + xkeysym_unicode_map[0x07C3] = 0x0393; + xkeysym_unicode_map[0x07C4] = 0x0394; + xkeysym_unicode_map[0x07C5] = 0x0395; + xkeysym_unicode_map[0x07C6] = 0x0396; + xkeysym_unicode_map[0x07C7] = 0x0397; + xkeysym_unicode_map[0x07C8] = 0x0398; + xkeysym_unicode_map[0x07C9] = 0x0399; + xkeysym_unicode_map[0x07CA] = 0x039A; + xkeysym_unicode_map[0x07CB] = 0x039B; + xkeysym_unicode_map[0x07CC] = 0x039C; + xkeysym_unicode_map[0x07CD] = 0x039D; + xkeysym_unicode_map[0x07CE] = 0x039E; + xkeysym_unicode_map[0x07CF] = 0x039F; + xkeysym_unicode_map[0x07D0] = 0x03A0; + xkeysym_unicode_map[0x07D1] = 0x03A1; + xkeysym_unicode_map[0x07D2] = 0x03A3; + xkeysym_unicode_map[0x07D4] = 0x03A4; + xkeysym_unicode_map[0x07D5] = 0x03A5; + xkeysym_unicode_map[0x07D6] = 0x03A6; + xkeysym_unicode_map[0x07D7] = 0x03A7; + xkeysym_unicode_map[0x07D8] = 0x03A8; + xkeysym_unicode_map[0x07D9] = 0x03A9; + xkeysym_unicode_map[0x07E1] = 0x03B1; + xkeysym_unicode_map[0x07E2] = 0x03B2; + xkeysym_unicode_map[0x07E3] = 0x03B3; + xkeysym_unicode_map[0x07E4] = 0x03B4; + xkeysym_unicode_map[0x07E5] = 0x03B5; + xkeysym_unicode_map[0x07E6] = 0x03B6; + xkeysym_unicode_map[0x07E7] = 0x03B7; + xkeysym_unicode_map[0x07E8] = 0x03B8; + xkeysym_unicode_map[0x07E9] = 0x03B9; + xkeysym_unicode_map[0x07EA] = 0x03BA; + xkeysym_unicode_map[0x07EB] = 0x03BB; + xkeysym_unicode_map[0x07EC] = 0x03BC; + xkeysym_unicode_map[0x07ED] = 0x03BD; + xkeysym_unicode_map[0x07EE] = 0x03BE; + xkeysym_unicode_map[0x07EF] = 0x03BF; + xkeysym_unicode_map[0x07F0] = 0x03C0; + xkeysym_unicode_map[0x07F1] = 0x03C1; + xkeysym_unicode_map[0x07F2] = 0x03C3; + xkeysym_unicode_map[0x07F3] = 0x03C2; + xkeysym_unicode_map[0x07F4] = 0x03C4; + xkeysym_unicode_map[0x07F5] = 0x03C5; + xkeysym_unicode_map[0x07F6] = 0x03C6; + xkeysym_unicode_map[0x07F7] = 0x03C7; + xkeysym_unicode_map[0x07F8] = 0x03C8; + xkeysym_unicode_map[0x07F9] = 0x03C9; + xkeysym_unicode_map[0x08A1] = 0x23B7; + xkeysym_unicode_map[0x08A2] = 0x250C; + xkeysym_unicode_map[0x08A3] = 0x2500; + xkeysym_unicode_map[0x08A4] = 0x2320; + xkeysym_unicode_map[0x08A5] = 0x2321; + xkeysym_unicode_map[0x08A6] = 0x2502; + xkeysym_unicode_map[0x08A7] = 0x23A1; + xkeysym_unicode_map[0x08A8] = 0x23A3; + xkeysym_unicode_map[0x08A9] = 0x23A4; + xkeysym_unicode_map[0x08AA] = 0x23A6; + xkeysym_unicode_map[0x08AB] = 0x239B; + xkeysym_unicode_map[0x08AC] = 0x239D; + xkeysym_unicode_map[0x08AD] = 0x239E; + xkeysym_unicode_map[0x08AE] = 0x23A0; + xkeysym_unicode_map[0x08AF] = 0x23A8; + xkeysym_unicode_map[0x08B0] = 0x23AC; + xkeysym_unicode_map[0x08BC] = 0x2264; + xkeysym_unicode_map[0x08BD] = 0x2260; + xkeysym_unicode_map[0x08BE] = 0x2265; + xkeysym_unicode_map[0x08BF] = 0x222B; + xkeysym_unicode_map[0x08C0] = 0x2234; + xkeysym_unicode_map[0x08C1] = 0x221D; + xkeysym_unicode_map[0x08C2] = 0x221E; + xkeysym_unicode_map[0x08C5] = 0x2207; + xkeysym_unicode_map[0x08C8] = 0x223C; + xkeysym_unicode_map[0x08C9] = 0x2243; + xkeysym_unicode_map[0x08CD] = 0x21D4; + xkeysym_unicode_map[0x08CE] = 0x21D2; + xkeysym_unicode_map[0x08CF] = 0x2261; + xkeysym_unicode_map[0x08D6] = 0x221A; + xkeysym_unicode_map[0x08DA] = 0x2282; + xkeysym_unicode_map[0x08DB] = 0x2283; + xkeysym_unicode_map[0x08DC] = 0x2229; + xkeysym_unicode_map[0x08DD] = 0x222A; + xkeysym_unicode_map[0x08DE] = 0x2227; + xkeysym_unicode_map[0x08DF] = 0x2228; + xkeysym_unicode_map[0x08EF] = 0x2202; + xkeysym_unicode_map[0x08F6] = 0x0192; + xkeysym_unicode_map[0x08FB] = 0x2190; + xkeysym_unicode_map[0x08FC] = 0x2191; + xkeysym_unicode_map[0x08FD] = 0x2192; + xkeysym_unicode_map[0x08FE] = 0x2193; + xkeysym_unicode_map[0x09E0] = 0x25C6; + xkeysym_unicode_map[0x09E1] = 0x2592; + xkeysym_unicode_map[0x09E2] = 0x2409; + xkeysym_unicode_map[0x09E3] = 0x240C; + xkeysym_unicode_map[0x09E4] = 0x240D; + xkeysym_unicode_map[0x09E5] = 0x240A; + xkeysym_unicode_map[0x09E8] = 0x2424; + xkeysym_unicode_map[0x09E9] = 0x240B; + xkeysym_unicode_map[0x09EA] = 0x2518; + xkeysym_unicode_map[0x09EB] = 0x2510; + xkeysym_unicode_map[0x09EC] = 0x250C; + xkeysym_unicode_map[0x09ED] = 0x2514; + xkeysym_unicode_map[0x09EE] = 0x253C; + xkeysym_unicode_map[0x09EF] = 0x23BA; + xkeysym_unicode_map[0x09F0] = 0x23BB; + xkeysym_unicode_map[0x09F1] = 0x2500; + xkeysym_unicode_map[0x09F2] = 0x23BC; + xkeysym_unicode_map[0x09F3] = 0x23BD; + xkeysym_unicode_map[0x09F4] = 0x251C; + xkeysym_unicode_map[0x09F5] = 0x2524; + xkeysym_unicode_map[0x09F6] = 0x2534; + xkeysym_unicode_map[0x09F7] = 0x252C; + xkeysym_unicode_map[0x09F8] = 0x2502; + xkeysym_unicode_map[0x0AA1] = 0x2003; + xkeysym_unicode_map[0x0AA2] = 0x2002; + xkeysym_unicode_map[0x0AA3] = 0x2004; + xkeysym_unicode_map[0x0AA4] = 0x2005; + xkeysym_unicode_map[0x0AA5] = 0x2007; + xkeysym_unicode_map[0x0AA6] = 0x2008; + xkeysym_unicode_map[0x0AA7] = 0x2009; + xkeysym_unicode_map[0x0AA8] = 0x200A; + xkeysym_unicode_map[0x0AA9] = 0x2014; + xkeysym_unicode_map[0x0AAA] = 0x2013; + xkeysym_unicode_map[0x0AAE] = 0x2026; + xkeysym_unicode_map[0x0AAF] = 0x2025; + xkeysym_unicode_map[0x0AB0] = 0x2153; + xkeysym_unicode_map[0x0AB1] = 0x2154; + xkeysym_unicode_map[0x0AB2] = 0x2155; + xkeysym_unicode_map[0x0AB3] = 0x2156; + xkeysym_unicode_map[0x0AB4] = 0x2157; + xkeysym_unicode_map[0x0AB5] = 0x2158; + xkeysym_unicode_map[0x0AB6] = 0x2159; + xkeysym_unicode_map[0x0AB7] = 0x215A; + xkeysym_unicode_map[0x0AB8] = 0x2105; + xkeysym_unicode_map[0x0ABB] = 0x2012; + xkeysym_unicode_map[0x0ABC] = 0x2329; + xkeysym_unicode_map[0x0ABE] = 0x232A; + xkeysym_unicode_map[0x0AC3] = 0x215B; + xkeysym_unicode_map[0x0AC4] = 0x215C; + xkeysym_unicode_map[0x0AC5] = 0x215D; + xkeysym_unicode_map[0x0AC6] = 0x215E; + xkeysym_unicode_map[0x0AC9] = 0x2122; + xkeysym_unicode_map[0x0ACA] = 0x2613; + xkeysym_unicode_map[0x0ACC] = 0x25C1; + xkeysym_unicode_map[0x0ACD] = 0x25B7; + xkeysym_unicode_map[0x0ACE] = 0x25CB; + xkeysym_unicode_map[0x0ACF] = 0x25AF; + xkeysym_unicode_map[0x0AD0] = 0x2018; + xkeysym_unicode_map[0x0AD1] = 0x2019; + xkeysym_unicode_map[0x0AD2] = 0x201C; + xkeysym_unicode_map[0x0AD3] = 0x201D; + xkeysym_unicode_map[0x0AD4] = 0x211E; + xkeysym_unicode_map[0x0AD6] = 0x2032; + xkeysym_unicode_map[0x0AD7] = 0x2033; + xkeysym_unicode_map[0x0AD9] = 0x271D; + xkeysym_unicode_map[0x0ADB] = 0x25AC; + xkeysym_unicode_map[0x0ADC] = 0x25C0; + xkeysym_unicode_map[0x0ADD] = 0x25B6; + xkeysym_unicode_map[0x0ADE] = 0x25CF; + xkeysym_unicode_map[0x0ADF] = 0x25AE; + xkeysym_unicode_map[0x0AE0] = 0x25E6; + xkeysym_unicode_map[0x0AE1] = 0x25AB; + xkeysym_unicode_map[0x0AE2] = 0x25AD; + xkeysym_unicode_map[0x0AE3] = 0x25B3; + xkeysym_unicode_map[0x0AE4] = 0x25BD; + xkeysym_unicode_map[0x0AE5] = 0x2606; + xkeysym_unicode_map[0x0AE6] = 0x2022; + xkeysym_unicode_map[0x0AE7] = 0x25AA; + xkeysym_unicode_map[0x0AE8] = 0x25B2; + xkeysym_unicode_map[0x0AE9] = 0x25BC; + xkeysym_unicode_map[0x0AEA] = 0x261C; + xkeysym_unicode_map[0x0AEB] = 0x261E; + xkeysym_unicode_map[0x0AEC] = 0x2663; + xkeysym_unicode_map[0x0AED] = 0x2666; + xkeysym_unicode_map[0x0AEE] = 0x2665; + xkeysym_unicode_map[0x0AF0] = 0x2720; + xkeysym_unicode_map[0x0AF1] = 0x2020; + xkeysym_unicode_map[0x0AF2] = 0x2021; + xkeysym_unicode_map[0x0AF3] = 0x2713; + xkeysym_unicode_map[0x0AF4] = 0x2717; + xkeysym_unicode_map[0x0AF5] = 0x266F; + xkeysym_unicode_map[0x0AF6] = 0x266D; + xkeysym_unicode_map[0x0AF7] = 0x2642; + xkeysym_unicode_map[0x0AF8] = 0x2640; + xkeysym_unicode_map[0x0AF9] = 0x260E; + xkeysym_unicode_map[0x0AFA] = 0x2315; + xkeysym_unicode_map[0x0AFB] = 0x2117; + xkeysym_unicode_map[0x0AFC] = 0x2038; + xkeysym_unicode_map[0x0AFD] = 0x201A; + xkeysym_unicode_map[0x0AFE] = 0x201E; + xkeysym_unicode_map[0x0BA3] = 0x003C; + xkeysym_unicode_map[0x0BA6] = 0x003E; + xkeysym_unicode_map[0x0BA8] = 0x2228; + xkeysym_unicode_map[0x0BA9] = 0x2227; + xkeysym_unicode_map[0x0BC0] = 0x00AF; + xkeysym_unicode_map[0x0BC2] = 0x22A5; + xkeysym_unicode_map[0x0BC3] = 0x2229; + xkeysym_unicode_map[0x0BC4] = 0x230A; + xkeysym_unicode_map[0x0BC6] = 0x005F; + xkeysym_unicode_map[0x0BCA] = 0x2218; + xkeysym_unicode_map[0x0BCC] = 0x2395; + xkeysym_unicode_map[0x0BCE] = 0x22A4; + xkeysym_unicode_map[0x0BCF] = 0x25CB; + xkeysym_unicode_map[0x0BD3] = 0x2308; + xkeysym_unicode_map[0x0BD6] = 0x222A; + xkeysym_unicode_map[0x0BD8] = 0x2283; + xkeysym_unicode_map[0x0BDA] = 0x2282; + xkeysym_unicode_map[0x0BDC] = 0x22A2; + xkeysym_unicode_map[0x0BFC] = 0x22A3; + xkeysym_unicode_map[0x0CDF] = 0x2017; + xkeysym_unicode_map[0x0CE0] = 0x05D0; + xkeysym_unicode_map[0x0CE1] = 0x05D1; + xkeysym_unicode_map[0x0CE2] = 0x05D2; + xkeysym_unicode_map[0x0CE3] = 0x05D3; + xkeysym_unicode_map[0x0CE4] = 0x05D4; + xkeysym_unicode_map[0x0CE5] = 0x05D5; + xkeysym_unicode_map[0x0CE6] = 0x05D6; + xkeysym_unicode_map[0x0CE7] = 0x05D7; + xkeysym_unicode_map[0x0CE8] = 0x05D8; + xkeysym_unicode_map[0x0CE9] = 0x05D9; + xkeysym_unicode_map[0x0CEA] = 0x05DA; + xkeysym_unicode_map[0x0CEB] = 0x05DB; + xkeysym_unicode_map[0x0CEC] = 0x05DC; + xkeysym_unicode_map[0x0CED] = 0x05DD; + xkeysym_unicode_map[0x0CEE] = 0x05DE; + xkeysym_unicode_map[0x0CEF] = 0x05DF; + xkeysym_unicode_map[0x0CF0] = 0x05E0; + xkeysym_unicode_map[0x0CF1] = 0x05E1; + xkeysym_unicode_map[0x0CF2] = 0x05E2; + xkeysym_unicode_map[0x0CF3] = 0x05E3; + xkeysym_unicode_map[0x0CF4] = 0x05E4; + xkeysym_unicode_map[0x0CF5] = 0x05E5; + xkeysym_unicode_map[0x0CF6] = 0x05E6; + xkeysym_unicode_map[0x0CF7] = 0x05E7; + xkeysym_unicode_map[0x0CF8] = 0x05E8; + xkeysym_unicode_map[0x0CF9] = 0x05E9; + xkeysym_unicode_map[0x0CFA] = 0x05EA; + xkeysym_unicode_map[0x0DA1] = 0x0E01; + xkeysym_unicode_map[0x0DA2] = 0x0E02; + xkeysym_unicode_map[0x0DA3] = 0x0E03; + xkeysym_unicode_map[0x0DA4] = 0x0E04; + xkeysym_unicode_map[0x0DA5] = 0x0E05; + xkeysym_unicode_map[0x0DA6] = 0x0E06; + xkeysym_unicode_map[0x0DA7] = 0x0E07; + xkeysym_unicode_map[0x0DA8] = 0x0E08; + xkeysym_unicode_map[0x0DA9] = 0x0E09; + xkeysym_unicode_map[0x0DAA] = 0x0E0A; + xkeysym_unicode_map[0x0DAB] = 0x0E0B; + xkeysym_unicode_map[0x0DAC] = 0x0E0C; + xkeysym_unicode_map[0x0DAD] = 0x0E0D; + xkeysym_unicode_map[0x0DAE] = 0x0E0E; + xkeysym_unicode_map[0x0DAF] = 0x0E0F; + xkeysym_unicode_map[0x0DB0] = 0x0E10; + xkeysym_unicode_map[0x0DB1] = 0x0E11; + xkeysym_unicode_map[0x0DB2] = 0x0E12; + xkeysym_unicode_map[0x0DB3] = 0x0E13; + xkeysym_unicode_map[0x0DB4] = 0x0E14; + xkeysym_unicode_map[0x0DB5] = 0x0E15; + xkeysym_unicode_map[0x0DB6] = 0x0E16; + xkeysym_unicode_map[0x0DB7] = 0x0E17; + xkeysym_unicode_map[0x0DB8] = 0x0E18; + xkeysym_unicode_map[0x0DB9] = 0x0E19; + xkeysym_unicode_map[0x0DBA] = 0x0E1A; + xkeysym_unicode_map[0x0DBB] = 0x0E1B; + xkeysym_unicode_map[0x0DBC] = 0x0E1C; + xkeysym_unicode_map[0x0DBD] = 0x0E1D; + xkeysym_unicode_map[0x0DBE] = 0x0E1E; + xkeysym_unicode_map[0x0DBF] = 0x0E1F; + xkeysym_unicode_map[0x0DC0] = 0x0E20; + xkeysym_unicode_map[0x0DC1] = 0x0E21; + xkeysym_unicode_map[0x0DC2] = 0x0E22; + xkeysym_unicode_map[0x0DC3] = 0x0E23; + xkeysym_unicode_map[0x0DC4] = 0x0E24; + xkeysym_unicode_map[0x0DC5] = 0x0E25; + xkeysym_unicode_map[0x0DC6] = 0x0E26; + xkeysym_unicode_map[0x0DC7] = 0x0E27; + xkeysym_unicode_map[0x0DC8] = 0x0E28; + xkeysym_unicode_map[0x0DC9] = 0x0E29; + xkeysym_unicode_map[0x0DCA] = 0x0E2A; + xkeysym_unicode_map[0x0DCB] = 0x0E2B; + xkeysym_unicode_map[0x0DCC] = 0x0E2C; + xkeysym_unicode_map[0x0DCD] = 0x0E2D; + xkeysym_unicode_map[0x0DCE] = 0x0E2E; + xkeysym_unicode_map[0x0DCF] = 0x0E2F; + xkeysym_unicode_map[0x0DD0] = 0x0E30; + xkeysym_unicode_map[0x0DD1] = 0x0E31; + xkeysym_unicode_map[0x0DD2] = 0x0E32; + xkeysym_unicode_map[0x0DD3] = 0x0E33; + xkeysym_unicode_map[0x0DD4] = 0x0E34; + xkeysym_unicode_map[0x0DD5] = 0x0E35; + xkeysym_unicode_map[0x0DD6] = 0x0E36; + xkeysym_unicode_map[0x0DD7] = 0x0E37; + xkeysym_unicode_map[0x0DD8] = 0x0E38; + xkeysym_unicode_map[0x0DD9] = 0x0E39; + xkeysym_unicode_map[0x0DDA] = 0x0E3A; + xkeysym_unicode_map[0x0DDF] = 0x0E3F; + xkeysym_unicode_map[0x0DE0] = 0x0E40; + xkeysym_unicode_map[0x0DE1] = 0x0E41; + xkeysym_unicode_map[0x0DE2] = 0x0E42; + xkeysym_unicode_map[0x0DE3] = 0x0E43; + xkeysym_unicode_map[0x0DE4] = 0x0E44; + xkeysym_unicode_map[0x0DE5] = 0x0E45; + xkeysym_unicode_map[0x0DE6] = 0x0E46; + xkeysym_unicode_map[0x0DE7] = 0x0E47; + xkeysym_unicode_map[0x0DE8] = 0x0E48; + xkeysym_unicode_map[0x0DE9] = 0x0E49; + xkeysym_unicode_map[0x0DEA] = 0x0E4A; + xkeysym_unicode_map[0x0DEB] = 0x0E4B; + xkeysym_unicode_map[0x0DEC] = 0x0E4C; + xkeysym_unicode_map[0x0DED] = 0x0E4D; + xkeysym_unicode_map[0x0DF0] = 0x0E50; + xkeysym_unicode_map[0x0DF1] = 0x0E51; + xkeysym_unicode_map[0x0DF2] = 0x0E52; + xkeysym_unicode_map[0x0DF3] = 0x0E53; + xkeysym_unicode_map[0x0DF4] = 0x0E54; + xkeysym_unicode_map[0x0DF5] = 0x0E55; + xkeysym_unicode_map[0x0DF6] = 0x0E56; + xkeysym_unicode_map[0x0DF7] = 0x0E57; + xkeysym_unicode_map[0x0DF8] = 0x0E58; + xkeysym_unicode_map[0x0DF9] = 0x0E59; + xkeysym_unicode_map[0x0EA1] = 0x3131; + xkeysym_unicode_map[0x0EA2] = 0x3132; + xkeysym_unicode_map[0x0EA3] = 0x3133; + xkeysym_unicode_map[0x0EA4] = 0x3134; + xkeysym_unicode_map[0x0EA5] = 0x3135; + xkeysym_unicode_map[0x0EA6] = 0x3136; + xkeysym_unicode_map[0x0EA7] = 0x3137; + xkeysym_unicode_map[0x0EA8] = 0x3138; + xkeysym_unicode_map[0x0EA9] = 0x3139; + xkeysym_unicode_map[0x0EAA] = 0x313A; + xkeysym_unicode_map[0x0EAB] = 0x313B; + xkeysym_unicode_map[0x0EAC] = 0x313C; + xkeysym_unicode_map[0x0EAD] = 0x313D; + xkeysym_unicode_map[0x0EAE] = 0x313E; + xkeysym_unicode_map[0x0EAF] = 0x313F; + xkeysym_unicode_map[0x0EB0] = 0x3140; + xkeysym_unicode_map[0x0EB1] = 0x3141; + xkeysym_unicode_map[0x0EB2] = 0x3142; + xkeysym_unicode_map[0x0EB3] = 0x3143; + xkeysym_unicode_map[0x0EB4] = 0x3144; + xkeysym_unicode_map[0x0EB5] = 0x3145; + xkeysym_unicode_map[0x0EB6] = 0x3146; + xkeysym_unicode_map[0x0EB7] = 0x3147; + xkeysym_unicode_map[0x0EB8] = 0x3148; + xkeysym_unicode_map[0x0EB9] = 0x3149; + xkeysym_unicode_map[0x0EBA] = 0x314A; + xkeysym_unicode_map[0x0EBB] = 0x314B; + xkeysym_unicode_map[0x0EBC] = 0x314C; + xkeysym_unicode_map[0x0EBD] = 0x314D; + xkeysym_unicode_map[0x0EBE] = 0x314E; + xkeysym_unicode_map[0x0EBF] = 0x314F; + xkeysym_unicode_map[0x0EC0] = 0x3150; + xkeysym_unicode_map[0x0EC1] = 0x3151; + xkeysym_unicode_map[0x0EC2] = 0x3152; + xkeysym_unicode_map[0x0EC3] = 0x3153; + xkeysym_unicode_map[0x0EC4] = 0x3154; + xkeysym_unicode_map[0x0EC5] = 0x3155; + xkeysym_unicode_map[0x0EC6] = 0x3156; + xkeysym_unicode_map[0x0EC7] = 0x3157; + xkeysym_unicode_map[0x0EC8] = 0x3158; + xkeysym_unicode_map[0x0EC9] = 0x3159; + xkeysym_unicode_map[0x0ECA] = 0x315A; + xkeysym_unicode_map[0x0ECB] = 0x315B; + xkeysym_unicode_map[0x0ECC] = 0x315C; + xkeysym_unicode_map[0x0ECD] = 0x315D; + xkeysym_unicode_map[0x0ECE] = 0x315E; + xkeysym_unicode_map[0x0ECF] = 0x315F; + xkeysym_unicode_map[0x0ED0] = 0x3160; + xkeysym_unicode_map[0x0ED1] = 0x3161; + xkeysym_unicode_map[0x0ED2] = 0x3162; + xkeysym_unicode_map[0x0ED3] = 0x3163; + xkeysym_unicode_map[0x0ED4] = 0x11A8; + xkeysym_unicode_map[0x0ED5] = 0x11A9; + xkeysym_unicode_map[0x0ED6] = 0x11AA; + xkeysym_unicode_map[0x0ED7] = 0x11AB; + xkeysym_unicode_map[0x0ED8] = 0x11AC; + xkeysym_unicode_map[0x0ED9] = 0x11AD; + xkeysym_unicode_map[0x0EDA] = 0x11AE; + xkeysym_unicode_map[0x0EDB] = 0x11AF; + xkeysym_unicode_map[0x0EDC] = 0x11B0; + xkeysym_unicode_map[0x0EDD] = 0x11B1; + xkeysym_unicode_map[0x0EDE] = 0x11B2; + xkeysym_unicode_map[0x0EDF] = 0x11B3; + xkeysym_unicode_map[0x0EE0] = 0x11B4; + xkeysym_unicode_map[0x0EE1] = 0x11B5; + xkeysym_unicode_map[0x0EE2] = 0x11B6; + xkeysym_unicode_map[0x0EE3] = 0x11B7; + xkeysym_unicode_map[0x0EE4] = 0x11B8; + xkeysym_unicode_map[0x0EE5] = 0x11B9; + xkeysym_unicode_map[0x0EE6] = 0x11BA; + xkeysym_unicode_map[0x0EE7] = 0x11BB; + xkeysym_unicode_map[0x0EE8] = 0x11BC; + xkeysym_unicode_map[0x0EE9] = 0x11BD; + xkeysym_unicode_map[0x0EEA] = 0x11BE; + xkeysym_unicode_map[0x0EEB] = 0x11BF; + xkeysym_unicode_map[0x0EEC] = 0x11C0; + xkeysym_unicode_map[0x0EED] = 0x11C1; + xkeysym_unicode_map[0x0EEE] = 0x11C2; + xkeysym_unicode_map[0x0EEF] = 0x316D; + xkeysym_unicode_map[0x0EF0] = 0x3171; + xkeysym_unicode_map[0x0EF1] = 0x3178; + xkeysym_unicode_map[0x0EF2] = 0x317F; + xkeysym_unicode_map[0x0EF3] = 0x3181; + xkeysym_unicode_map[0x0EF4] = 0x3184; + xkeysym_unicode_map[0x0EF5] = 0x3186; + xkeysym_unicode_map[0x0EF6] = 0x318D; + xkeysym_unicode_map[0x0EF7] = 0x318E; + xkeysym_unicode_map[0x0EF8] = 0x11EB; + xkeysym_unicode_map[0x0EF9] = 0x11F0; + xkeysym_unicode_map[0x0EFA] = 0x11F9; + xkeysym_unicode_map[0x0EFF] = 0x20A9; + xkeysym_unicode_map[0x13A4] = 0x20AC; + xkeysym_unicode_map[0x13BC] = 0x0152; + xkeysym_unicode_map[0x13BD] = 0x0153; + xkeysym_unicode_map[0x13BE] = 0x0178; + xkeysym_unicode_map[0x20AC] = 0x20AC; } -unsigned int KeyMappingX11::get_xlibcode(Key p_keysym) { - unsigned int code = 0; - for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { - if (_scancode_to_keycode[i].keysym == p_keysym) { - code = _scancode_to_keycode[i].keycode; - break; +Key KeyMappingX11::get_keycode(KeySym p_keysym) { + if (p_keysym >= 0x20 && p_keysym < 0x7E) { // ASCII, maps 1-1 + if (p_keysym > 0x60 && p_keysym < 0x7B) { // Lowercase ASCII. + return (Key)(p_keysym - 32); + } else { + return (Key)p_keysym; } } - return code; -} - -Key KeyMappingX11::get_keycode(KeySym p_keysym) { - // kinda bruteforce.. could optimize. - - if (p_keysym < 0x100) { // Latin 1, maps 1-1 - return (Key)p_keysym; + const Key *key = xkeysym_map.getptr(p_keysym); + if (key) { + return *key; } + return Key::NONE; +} - // look for special key - for (int idx = 0; _xkeysym_to_keycode[idx].keysym != 0; idx++) { - if (_xkeysym_to_keycode[idx].keysym == p_keysym) { - return _xkeysym_to_keycode[idx].keycode; - } +Key KeyMappingX11::get_scancode(unsigned int p_code) { + const Key *key = scancode_map.getptr(p_code); + if (key) { + return *key; } return Key::NONE; } -KeySym KeyMappingX11::get_keysym(Key p_code) { - // kinda bruteforce.. could optimize. - - if (p_code < Key::END_LATIN1) { // Latin 1, maps 1-1 - return (KeySym)p_code; - } - - // look for special key - for (int idx = 0; _xkeysym_to_keycode[idx].keysym != 0; idx++) { - if (_xkeysym_to_keycode[idx].keycode == p_code) { - return _xkeysym_to_keycode[idx].keysym; - } +unsigned int KeyMappingX11::get_xlibcode(Key p_keysym) { + const unsigned int *key = scancode_map_inv.getptr(p_keysym); + if (key) { + return *key; } - - return (KeySym)Key::NONE; + return 0x00; } -/***** UNICODE CONVERSION ******/ - -// Tables taken from FOX toolkit - -struct _XTranslateUnicodePair { - KeySym keysym; - unsigned int unicode; -}; - -enum { - _KEYSYM_MAX = 759 -}; - -static _XTranslateUnicodePair _xkeysym_to_unicode[_KEYSYM_MAX] = { - { 0x01A1, 0x0104 }, - { 0x01A2, 0x02D8 }, - { 0x01A3, 0x0141 }, - { 0x01A5, 0x013D }, - { 0x01A6, 0x015A }, - { 0x01A9, 0x0160 }, - { 0x01AA, 0x015E }, - { 0x01AB, 0x0164 }, - { 0x01AC, 0x0179 }, - { 0x01AE, 0x017D }, - { 0x01AF, 0x017B }, - { 0x01B1, 0x0105 }, - { 0x01B2, 0x02DB }, - { 0x01B3, 0x0142 }, - { 0x01B5, 0x013E }, - { 0x01B6, 0x015B }, - { 0x01B7, 0x02C7 }, - { 0x01B9, 0x0161 }, - { 0x01BA, 0x015F }, - { 0x01BB, 0x0165 }, - { 0x01BC, 0x017A }, - { 0x01BD, 0x02DD }, - { 0x01BE, 0x017E }, - { 0x01BF, 0x017C }, - { 0x01C0, 0x0154 }, - { 0x01C3, 0x0102 }, - { 0x01C5, 0x0139 }, - { 0x01C6, 0x0106 }, - { 0x01C8, 0x010C }, - { 0x01CA, 0x0118 }, - { 0x01CC, 0x011A }, - { 0x01CF, 0x010E }, - { 0x01D0, 0x0110 }, - { 0x01D1, 0x0143 }, - { 0x01D2, 0x0147 }, - { 0x01D5, 0x0150 }, - { 0x01D8, 0x0158 }, - { 0x01D9, 0x016E }, - { 0x01DB, 0x0170 }, - { 0x01DE, 0x0162 }, - { 0x01E0, 0x0155 }, - { 0x01E3, 0x0103 }, - { 0x01E5, 0x013A }, - { 0x01E6, 0x0107 }, - { 0x01E8, 0x010D }, - { 0x01EA, 0x0119 }, - { 0x01EC, 0x011B }, - { 0x01EF, 0x010F }, - { 0x01F0, 0x0111 }, - { 0x01F1, 0x0144 }, - { 0x01F2, 0x0148 }, - { 0x01F5, 0x0151 }, - { 0x01F8, 0x0159 }, - { 0x01F9, 0x016F }, - { 0x01FB, 0x0171 }, - { 0x01FE, 0x0163 }, - { 0x01FF, 0x02D9 }, - { 0x02A1, 0x0126 }, - { 0x02A6, 0x0124 }, - { 0x02A9, 0x0130 }, - { 0x02AB, 0x011E }, - { 0x02AC, 0x0134 }, - { 0x02B1, 0x0127 }, - { 0x02B6, 0x0125 }, - { 0x02B9, 0x0131 }, - { 0x02BB, 0x011F }, - { 0x02BC, 0x0135 }, - { 0x02C5, 0x010A }, - { 0x02C6, 0x0108 }, - { 0x02D5, 0x0120 }, - { 0x02D8, 0x011C }, - { 0x02DD, 0x016C }, - { 0x02DE, 0x015C }, - { 0x02E5, 0x010B }, - { 0x02E6, 0x0109 }, - { 0x02F5, 0x0121 }, - { 0x02F8, 0x011D }, - { 0x02FD, 0x016D }, - { 0x02FE, 0x015D }, - { 0x03A2, 0x0138 }, - { 0x03A3, 0x0156 }, - { 0x03A5, 0x0128 }, - { 0x03A6, 0x013B }, - { 0x03AA, 0x0112 }, - { 0x03AB, 0x0122 }, - { 0x03AC, 0x0166 }, - { 0x03B3, 0x0157 }, - { 0x03B5, 0x0129 }, - { 0x03B6, 0x013C }, - { 0x03BA, 0x0113 }, - { 0x03BB, 0x0123 }, - { 0x03BC, 0x0167 }, - { 0x03BD, 0x014A }, - { 0x03BF, 0x014B }, - { 0x03C0, 0x0100 }, - { 0x03C7, 0x012E }, - { 0x03CC, 0x0116 }, - { 0x03CF, 0x012A }, - { 0x03D1, 0x0145 }, - { 0x03D2, 0x014C }, - { 0x03D3, 0x0136 }, - { 0x03D9, 0x0172 }, - { 0x03DD, 0x0168 }, - { 0x03DE, 0x016A }, - { 0x03E0, 0x0101 }, - { 0x03E7, 0x012F }, - { 0x03EC, 0x0117 }, - { 0x03EF, 0x012B }, - { 0x03F1, 0x0146 }, - { 0x03F2, 0x014D }, - { 0x03F3, 0x0137 }, - { 0x03F9, 0x0173 }, - { 0x03FD, 0x0169 }, - { 0x03FE, 0x016B }, - { 0x047E, 0x203E }, - { 0x04A1, 0x3002 }, - { 0x04A2, 0x300C }, - { 0x04A3, 0x300D }, - { 0x04A4, 0x3001 }, - { 0x04A5, 0x30FB }, - { 0x04A6, 0x30F2 }, - { 0x04A7, 0x30A1 }, - { 0x04A8, 0x30A3 }, - { 0x04A9, 0x30A5 }, - { 0x04AA, 0x30A7 }, - { 0x04AB, 0x30A9 }, - { 0x04AC, 0x30E3 }, - { 0x04AD, 0x30E5 }, - { 0x04AE, 0x30E7 }, - { 0x04AF, 0x30C3 }, - { 0x04B0, 0x30FC }, - { 0x04B1, 0x30A2 }, - { 0x04B2, 0x30A4 }, - { 0x04B3, 0x30A6 }, - { 0x04B4, 0x30A8 }, - { 0x04B5, 0x30AA }, - { 0x04B6, 0x30AB }, - { 0x04B7, 0x30AD }, - { 0x04B8, 0x30AF }, - { 0x04B9, 0x30B1 }, - { 0x04BA, 0x30B3 }, - { 0x04BB, 0x30B5 }, - { 0x04BC, 0x30B7 }, - { 0x04BD, 0x30B9 }, - { 0x04BE, 0x30BB }, - { 0x04BF, 0x30BD }, - { 0x04C0, 0x30BF }, - { 0x04C1, 0x30C1 }, - { 0x04C2, 0x30C4 }, - { 0x04C3, 0x30C6 }, - { 0x04C4, 0x30C8 }, - { 0x04C5, 0x30CA }, - { 0x04C6, 0x30CB }, - { 0x04C7, 0x30CC }, - { 0x04C8, 0x30CD }, - { 0x04C9, 0x30CE }, - { 0x04CA, 0x30CF }, - { 0x04CB, 0x30D2 }, - { 0x04CC, 0x30D5 }, - { 0x04CD, 0x30D8 }, - { 0x04CE, 0x30DB }, - { 0x04CF, 0x30DE }, - { 0x04D0, 0x30DF }, - { 0x04D1, 0x30E0 }, - { 0x04D2, 0x30E1 }, - { 0x04D3, 0x30E2 }, - { 0x04D4, 0x30E4 }, - { 0x04D5, 0x30E6 }, - { 0x04D6, 0x30E8 }, - { 0x04D7, 0x30E9 }, - { 0x04D8, 0x30EA }, - { 0x04D9, 0x30EB }, - { 0x04DA, 0x30EC }, - { 0x04DB, 0x30ED }, - { 0x04DC, 0x30EF }, - { 0x04DD, 0x30F3 }, - { 0x04DE, 0x309B }, - { 0x04DF, 0x309C }, - { 0x05AC, 0x060C }, - { 0x05BB, 0x061B }, - { 0x05BF, 0x061F }, - { 0x05C1, 0x0621 }, - { 0x05C2, 0x0622 }, - { 0x05C3, 0x0623 }, - { 0x05C4, 0x0624 }, - { 0x05C5, 0x0625 }, - { 0x05C6, 0x0626 }, - { 0x05C7, 0x0627 }, - { 0x05C8, 0x0628 }, - { 0x05C9, 0x0629 }, - { 0x05CA, 0x062A }, - { 0x05CB, 0x062B }, - { 0x05CC, 0x062C }, - { 0x05CD, 0x062D }, - { 0x05CE, 0x062E }, - { 0x05CF, 0x062F }, - { 0x05D0, 0x0630 }, - { 0x05D1, 0x0631 }, - { 0x05D2, 0x0632 }, - { 0x05D3, 0x0633 }, - { 0x05D4, 0x0634 }, - { 0x05D5, 0x0635 }, - { 0x05D6, 0x0636 }, - { 0x05D7, 0x0637 }, - { 0x05D8, 0x0638 }, - { 0x05D9, 0x0639 }, - { 0x05DA, 0x063A }, - { 0x05E0, 0x0640 }, - { 0x05E1, 0x0641 }, - { 0x05E2, 0x0642 }, - { 0x05E3, 0x0643 }, - { 0x05E4, 0x0644 }, - { 0x05E5, 0x0645 }, - { 0x05E6, 0x0646 }, - { 0x05E7, 0x0647 }, - { 0x05E8, 0x0648 }, - { 0x05E9, 0x0649 }, - { 0x05EA, 0x064A }, - { 0x05EB, 0x064B }, - { 0x05EC, 0x064C }, - { 0x05ED, 0x064D }, - { 0x05EE, 0x064E }, - { 0x05EF, 0x064F }, - { 0x05F0, 0x0650 }, - { 0x05F1, 0x0651 }, - { 0x05F2, 0x0652 }, - { 0x06A1, 0x0452 }, - { 0x06A2, 0x0453 }, - { 0x06A3, 0x0451 }, - { 0x06A4, 0x0454 }, - { 0x06A5, 0x0455 }, - { 0x06A6, 0x0456 }, - { 0x06A7, 0x0457 }, - { 0x06A8, 0x0458 }, - { 0x06A9, 0x0459 }, - { 0x06AA, 0x045A }, - { 0x06AB, 0x045B }, - { 0x06AC, 0x045C }, - { 0x06AE, 0x045E }, - { 0x06AF, 0x045F }, - { 0x06B0, 0x2116 }, - { 0x06B1, 0x0402 }, - { 0x06B2, 0x0403 }, - { 0x06B3, 0x0401 }, - { 0x06B4, 0x0404 }, - { 0x06B5, 0x0405 }, - { 0x06B6, 0x0406 }, - { 0x06B7, 0x0407 }, - { 0x06B8, 0x0408 }, - { 0x06B9, 0x0409 }, - { 0x06BA, 0x040A }, - { 0x06BB, 0x040B }, - { 0x06BC, 0x040C }, - { 0x06BE, 0x040E }, - { 0x06BF, 0x040F }, - { 0x06C0, 0x044E }, - { 0x06C1, 0x0430 }, - { 0x06C2, 0x0431 }, - { 0x06C3, 0x0446 }, - { 0x06C4, 0x0434 }, - { 0x06C5, 0x0435 }, - { 0x06C6, 0x0444 }, - { 0x06C7, 0x0433 }, - { 0x06C8, 0x0445 }, - { 0x06C9, 0x0438 }, - { 0x06CA, 0x0439 }, - { 0x06CB, 0x043A }, - { 0x06CC, 0x043B }, - { 0x06CD, 0x043C }, - { 0x06CE, 0x043D }, - { 0x06CF, 0x043E }, - { 0x06D0, 0x043F }, - { 0x06D1, 0x044F }, - { 0x06D2, 0x0440 }, - { 0x06D3, 0x0441 }, - { 0x06D4, 0x0442 }, - { 0x06D5, 0x0443 }, - { 0x06D6, 0x0436 }, - { 0x06D7, 0x0432 }, - { 0x06D8, 0x044C }, - { 0x06D9, 0x044B }, - { 0x06DA, 0x0437 }, - { 0x06DB, 0x0448 }, - { 0x06DC, 0x044D }, - { 0x06DD, 0x0449 }, - { 0x06DE, 0x0447 }, - { 0x06DF, 0x044A }, - { 0x06E0, 0x042E }, - { 0x06E1, 0x0410 }, - { 0x06E2, 0x0411 }, - { 0x06E3, 0x0426 }, - { 0x06E4, 0x0414 }, - { 0x06E5, 0x0415 }, - { 0x06E6, 0x0424 }, - { 0x06E7, 0x0413 }, - { 0x06E8, 0x0425 }, - { 0x06E9, 0x0418 }, - { 0x06EA, 0x0419 }, - { 0x06EB, 0x041A }, - { 0x06EC, 0x041B }, - { 0x06ED, 0x041C }, - { 0x06EE, 0x041D }, - { 0x06EF, 0x041E }, - { 0x06F0, 0x041F }, - { 0x06F1, 0x042F }, - { 0x06F2, 0x0420 }, - { 0x06F3, 0x0421 }, - { 0x06F4, 0x0422 }, - { 0x06F5, 0x0423 }, - { 0x06F6, 0x0416 }, - { 0x06F7, 0x0412 }, - { 0x06F8, 0x042C }, - { 0x06F9, 0x042B }, - { 0x06FA, 0x0417 }, - { 0x06FB, 0x0428 }, - { 0x06FC, 0x042D }, - { 0x06FD, 0x0429 }, - { 0x06FE, 0x0427 }, - { 0x06FF, 0x042A }, - { 0x07A1, 0x0386 }, - { 0x07A2, 0x0388 }, - { 0x07A3, 0x0389 }, - { 0x07A4, 0x038A }, - { 0x07A5, 0x03AA }, - { 0x07A7, 0x038C }, - { 0x07A8, 0x038E }, - { 0x07A9, 0x03AB }, - { 0x07AB, 0x038F }, - { 0x07AE, 0x0385 }, - { 0x07AF, 0x2015 }, - { 0x07B1, 0x03AC }, - { 0x07B2, 0x03AD }, - { 0x07B3, 0x03AE }, - { 0x07B4, 0x03AF }, - { 0x07B5, 0x03CA }, - { 0x07B6, 0x0390 }, - { 0x07B7, 0x03CC }, - { 0x07B8, 0x03CD }, - { 0x07B9, 0x03CB }, - { 0x07BA, 0x03B0 }, - { 0x07BB, 0x03CE }, - { 0x07C1, 0x0391 }, - { 0x07C2, 0x0392 }, - { 0x07C3, 0x0393 }, - { 0x07C4, 0x0394 }, - { 0x07C5, 0x0395 }, - { 0x07C6, 0x0396 }, - { 0x07C7, 0x0397 }, - { 0x07C8, 0x0398 }, - { 0x07C9, 0x0399 }, - { 0x07CA, 0x039A }, - { 0x07CB, 0x039B }, - { 0x07CC, 0x039C }, - { 0x07CD, 0x039D }, - { 0x07CE, 0x039E }, - { 0x07CF, 0x039F }, - { 0x07D0, 0x03A0 }, - { 0x07D1, 0x03A1 }, - { 0x07D2, 0x03A3 }, - { 0x07D4, 0x03A4 }, - { 0x07D5, 0x03A5 }, - { 0x07D6, 0x03A6 }, - { 0x07D7, 0x03A7 }, - { 0x07D8, 0x03A8 }, - { 0x07D9, 0x03A9 }, - { 0x07E1, 0x03B1 }, - { 0x07E2, 0x03B2 }, - { 0x07E3, 0x03B3 }, - { 0x07E4, 0x03B4 }, - { 0x07E5, 0x03B5 }, - { 0x07E6, 0x03B6 }, - { 0x07E7, 0x03B7 }, - { 0x07E8, 0x03B8 }, - { 0x07E9, 0x03B9 }, - { 0x07EA, 0x03BA }, - { 0x07EB, 0x03BB }, - { 0x07EC, 0x03BC }, - { 0x07ED, 0x03BD }, - { 0x07EE, 0x03BE }, - { 0x07EF, 0x03BF }, - { 0x07F0, 0x03C0 }, - { 0x07F1, 0x03C1 }, - { 0x07F2, 0x03C3 }, - { 0x07F3, 0x03C2 }, - { 0x07F4, 0x03C4 }, - { 0x07F5, 0x03C5 }, - { 0x07F6, 0x03C6 }, - { 0x07F7, 0x03C7 }, - { 0x07F8, 0x03C8 }, - { 0x07F9, 0x03C9 }, - { 0x08A1, 0x23B7 }, - { 0x08A2, 0x250C }, - { 0x08A3, 0x2500 }, - { 0x08A4, 0x2320 }, - { 0x08A5, 0x2321 }, - { 0x08A6, 0x2502 }, - { 0x08A7, 0x23A1 }, - { 0x08A8, 0x23A3 }, - { 0x08A9, 0x23A4 }, - { 0x08AA, 0x23A6 }, - { 0x08AB, 0x239B }, - { 0x08AC, 0x239D }, - { 0x08AD, 0x239E }, - { 0x08AE, 0x23A0 }, - { 0x08AF, 0x23A8 }, - { 0x08B0, 0x23AC }, - { 0x08BC, 0x2264 }, - { 0x08BD, 0x2260 }, - { 0x08BE, 0x2265 }, - { 0x08BF, 0x222B }, - { 0x08C0, 0x2234 }, - { 0x08C1, 0x221D }, - { 0x08C2, 0x221E }, - { 0x08C5, 0x2207 }, - { 0x08C8, 0x223C }, - { 0x08C9, 0x2243 }, - { 0x08CD, 0x21D4 }, - { 0x08CE, 0x21D2 }, - { 0x08CF, 0x2261 }, - { 0x08D6, 0x221A }, - { 0x08DA, 0x2282 }, - { 0x08DB, 0x2283 }, - { 0x08DC, 0x2229 }, - { 0x08DD, 0x222A }, - { 0x08DE, 0x2227 }, - { 0x08DF, 0x2228 }, - { 0x08EF, 0x2202 }, - { 0x08F6, 0x0192 }, - { 0x08FB, 0x2190 }, - { 0x08FC, 0x2191 }, - { 0x08FD, 0x2192 }, - { 0x08FE, 0x2193 }, - { 0x09E0, 0x25C6 }, - { 0x09E1, 0x2592 }, - { 0x09E2, 0x2409 }, - { 0x09E3, 0x240C }, - { 0x09E4, 0x240D }, - { 0x09E5, 0x240A }, - { 0x09E8, 0x2424 }, - { 0x09E9, 0x240B }, - { 0x09EA, 0x2518 }, - { 0x09EB, 0x2510 }, - { 0x09EC, 0x250C }, - { 0x09ED, 0x2514 }, - { 0x09EE, 0x253C }, - { 0x09EF, 0x23BA }, - { 0x09F0, 0x23BB }, - { 0x09F1, 0x2500 }, - { 0x09F2, 0x23BC }, - { 0x09F3, 0x23BD }, - { 0x09F4, 0x251C }, - { 0x09F5, 0x2524 }, - { 0x09F6, 0x2534 }, - { 0x09F7, 0x252C }, - { 0x09F8, 0x2502 }, - { 0x0AA1, 0x2003 }, - { 0x0AA2, 0x2002 }, - { 0x0AA3, 0x2004 }, - { 0x0AA4, 0x2005 }, - { 0x0AA5, 0x2007 }, - { 0x0AA6, 0x2008 }, - { 0x0AA7, 0x2009 }, - { 0x0AA8, 0x200A }, - { 0x0AA9, 0x2014 }, - { 0x0AAA, 0x2013 }, - { 0x0AAE, 0x2026 }, - { 0x0AAF, 0x2025 }, - { 0x0AB0, 0x2153 }, - { 0x0AB1, 0x2154 }, - { 0x0AB2, 0x2155 }, - { 0x0AB3, 0x2156 }, - { 0x0AB4, 0x2157 }, - { 0x0AB5, 0x2158 }, - { 0x0AB6, 0x2159 }, - { 0x0AB7, 0x215A }, - { 0x0AB8, 0x2105 }, - { 0x0ABB, 0x2012 }, - { 0x0ABC, 0x2329 }, - { 0x0ABE, 0x232A }, - { 0x0AC3, 0x215B }, - { 0x0AC4, 0x215C }, - { 0x0AC5, 0x215D }, - { 0x0AC6, 0x215E }, - { 0x0AC9, 0x2122 }, - { 0x0ACA, 0x2613 }, - { 0x0ACC, 0x25C1 }, - { 0x0ACD, 0x25B7 }, - { 0x0ACE, 0x25CB }, - { 0x0ACF, 0x25AF }, - { 0x0AD0, 0x2018 }, - { 0x0AD1, 0x2019 }, - { 0x0AD2, 0x201C }, - { 0x0AD3, 0x201D }, - { 0x0AD4, 0x211E }, - { 0x0AD6, 0x2032 }, - { 0x0AD7, 0x2033 }, - { 0x0AD9, 0x271D }, - { 0x0ADB, 0x25AC }, - { 0x0ADC, 0x25C0 }, - { 0x0ADD, 0x25B6 }, - { 0x0ADE, 0x25CF }, - { 0x0ADF, 0x25AE }, - { 0x0AE0, 0x25E6 }, - { 0x0AE1, 0x25AB }, - { 0x0AE2, 0x25AD }, - { 0x0AE3, 0x25B3 }, - { 0x0AE4, 0x25BD }, - { 0x0AE5, 0x2606 }, - { 0x0AE6, 0x2022 }, - { 0x0AE7, 0x25AA }, - { 0x0AE8, 0x25B2 }, - { 0x0AE9, 0x25BC }, - { 0x0AEA, 0x261C }, - { 0x0AEB, 0x261E }, - { 0x0AEC, 0x2663 }, - { 0x0AED, 0x2666 }, - { 0x0AEE, 0x2665 }, - { 0x0AF0, 0x2720 }, - { 0x0AF1, 0x2020 }, - { 0x0AF2, 0x2021 }, - { 0x0AF3, 0x2713 }, - { 0x0AF4, 0x2717 }, - { 0x0AF5, 0x266F }, - { 0x0AF6, 0x266D }, - { 0x0AF7, 0x2642 }, - { 0x0AF8, 0x2640 }, - { 0x0AF9, 0x260E }, - { 0x0AFA, 0x2315 }, - { 0x0AFB, 0x2117 }, - { 0x0AFC, 0x2038 }, - { 0x0AFD, 0x201A }, - { 0x0AFE, 0x201E }, - { 0x0BA3, 0x003C }, - { 0x0BA6, 0x003E }, - { 0x0BA8, 0x2228 }, - { 0x0BA9, 0x2227 }, - { 0x0BC0, 0x00AF }, - { 0x0BC2, 0x22A5 }, - { 0x0BC3, 0x2229 }, - { 0x0BC4, 0x230A }, - { 0x0BC6, 0x005F }, - { 0x0BCA, 0x2218 }, - { 0x0BCC, 0x2395 }, - { 0x0BCE, 0x22A4 }, - { 0x0BCF, 0x25CB }, - { 0x0BD3, 0x2308 }, - { 0x0BD6, 0x222A }, - { 0x0BD8, 0x2283 }, - { 0x0BDA, 0x2282 }, - { 0x0BDC, 0x22A2 }, - { 0x0BFC, 0x22A3 }, - { 0x0CDF, 0x2017 }, - { 0x0CE0, 0x05D0 }, - { 0x0CE1, 0x05D1 }, - { 0x0CE2, 0x05D2 }, - { 0x0CE3, 0x05D3 }, - { 0x0CE4, 0x05D4 }, - { 0x0CE5, 0x05D5 }, - { 0x0CE6, 0x05D6 }, - { 0x0CE7, 0x05D7 }, - { 0x0CE8, 0x05D8 }, - { 0x0CE9, 0x05D9 }, - { 0x0CEA, 0x05DA }, - { 0x0CEB, 0x05DB }, - { 0x0CEC, 0x05DC }, - { 0x0CED, 0x05DD }, - { 0x0CEE, 0x05DE }, - { 0x0CEF, 0x05DF }, - { 0x0CF0, 0x05E0 }, - { 0x0CF1, 0x05E1 }, - { 0x0CF2, 0x05E2 }, - { 0x0CF3, 0x05E3 }, - { 0x0CF4, 0x05E4 }, - { 0x0CF5, 0x05E5 }, - { 0x0CF6, 0x05E6 }, - { 0x0CF7, 0x05E7 }, - { 0x0CF8, 0x05E8 }, - { 0x0CF9, 0x05E9 }, - { 0x0CFA, 0x05EA }, - { 0x0DA1, 0x0E01 }, - { 0x0DA2, 0x0E02 }, - { 0x0DA3, 0x0E03 }, - { 0x0DA4, 0x0E04 }, - { 0x0DA5, 0x0E05 }, - { 0x0DA6, 0x0E06 }, - { 0x0DA7, 0x0E07 }, - { 0x0DA8, 0x0E08 }, - { 0x0DA9, 0x0E09 }, - { 0x0DAA, 0x0E0A }, - { 0x0DAB, 0x0E0B }, - { 0x0DAC, 0x0E0C }, - { 0x0DAD, 0x0E0D }, - { 0x0DAE, 0x0E0E }, - { 0x0DAF, 0x0E0F }, - { 0x0DB0, 0x0E10 }, - { 0x0DB1, 0x0E11 }, - { 0x0DB2, 0x0E12 }, - { 0x0DB3, 0x0E13 }, - { 0x0DB4, 0x0E14 }, - { 0x0DB5, 0x0E15 }, - { 0x0DB6, 0x0E16 }, - { 0x0DB7, 0x0E17 }, - { 0x0DB8, 0x0E18 }, - { 0x0DB9, 0x0E19 }, - { 0x0DBA, 0x0E1A }, - { 0x0DBB, 0x0E1B }, - { 0x0DBC, 0x0E1C }, - { 0x0DBD, 0x0E1D }, - { 0x0DBE, 0x0E1E }, - { 0x0DBF, 0x0E1F }, - { 0x0DC0, 0x0E20 }, - { 0x0DC1, 0x0E21 }, - { 0x0DC2, 0x0E22 }, - { 0x0DC3, 0x0E23 }, - { 0x0DC4, 0x0E24 }, - { 0x0DC5, 0x0E25 }, - { 0x0DC6, 0x0E26 }, - { 0x0DC7, 0x0E27 }, - { 0x0DC8, 0x0E28 }, - { 0x0DC9, 0x0E29 }, - { 0x0DCA, 0x0E2A }, - { 0x0DCB, 0x0E2B }, - { 0x0DCC, 0x0E2C }, - { 0x0DCD, 0x0E2D }, - { 0x0DCE, 0x0E2E }, - { 0x0DCF, 0x0E2F }, - { 0x0DD0, 0x0E30 }, - { 0x0DD1, 0x0E31 }, - { 0x0DD2, 0x0E32 }, - { 0x0DD3, 0x0E33 }, - { 0x0DD4, 0x0E34 }, - { 0x0DD5, 0x0E35 }, - { 0x0DD6, 0x0E36 }, - { 0x0DD7, 0x0E37 }, - { 0x0DD8, 0x0E38 }, - { 0x0DD9, 0x0E39 }, - { 0x0DDA, 0x0E3A }, - { 0x0DDF, 0x0E3F }, - { 0x0DE0, 0x0E40 }, - { 0x0DE1, 0x0E41 }, - { 0x0DE2, 0x0E42 }, - { 0x0DE3, 0x0E43 }, - { 0x0DE4, 0x0E44 }, - { 0x0DE5, 0x0E45 }, - { 0x0DE6, 0x0E46 }, - { 0x0DE7, 0x0E47 }, - { 0x0DE8, 0x0E48 }, - { 0x0DE9, 0x0E49 }, - { 0x0DEA, 0x0E4A }, - { 0x0DEB, 0x0E4B }, - { 0x0DEC, 0x0E4C }, - { 0x0DED, 0x0E4D }, - { 0x0DF0, 0x0E50 }, - { 0x0DF1, 0x0E51 }, - { 0x0DF2, 0x0E52 }, - { 0x0DF3, 0x0E53 }, - { 0x0DF4, 0x0E54 }, - { 0x0DF5, 0x0E55 }, - { 0x0DF6, 0x0E56 }, - { 0x0DF7, 0x0E57 }, - { 0x0DF8, 0x0E58 }, - { 0x0DF9, 0x0E59 }, - { 0x0EA1, 0x3131 }, - { 0x0EA2, 0x3132 }, - { 0x0EA3, 0x3133 }, - { 0x0EA4, 0x3134 }, - { 0x0EA5, 0x3135 }, - { 0x0EA6, 0x3136 }, - { 0x0EA7, 0x3137 }, - { 0x0EA8, 0x3138 }, - { 0x0EA9, 0x3139 }, - { 0x0EAA, 0x313A }, - { 0x0EAB, 0x313B }, - { 0x0EAC, 0x313C }, - { 0x0EAD, 0x313D }, - { 0x0EAE, 0x313E }, - { 0x0EAF, 0x313F }, - { 0x0EB0, 0x3140 }, - { 0x0EB1, 0x3141 }, - { 0x0EB2, 0x3142 }, - { 0x0EB3, 0x3143 }, - { 0x0EB4, 0x3144 }, - { 0x0EB5, 0x3145 }, - { 0x0EB6, 0x3146 }, - { 0x0EB7, 0x3147 }, - { 0x0EB8, 0x3148 }, - { 0x0EB9, 0x3149 }, - { 0x0EBA, 0x314A }, - { 0x0EBB, 0x314B }, - { 0x0EBC, 0x314C }, - { 0x0EBD, 0x314D }, - { 0x0EBE, 0x314E }, - { 0x0EBF, 0x314F }, - { 0x0EC0, 0x3150 }, - { 0x0EC1, 0x3151 }, - { 0x0EC2, 0x3152 }, - { 0x0EC3, 0x3153 }, - { 0x0EC4, 0x3154 }, - { 0x0EC5, 0x3155 }, - { 0x0EC6, 0x3156 }, - { 0x0EC7, 0x3157 }, - { 0x0EC8, 0x3158 }, - { 0x0EC9, 0x3159 }, - { 0x0ECA, 0x315A }, - { 0x0ECB, 0x315B }, - { 0x0ECC, 0x315C }, - { 0x0ECD, 0x315D }, - { 0x0ECE, 0x315E }, - { 0x0ECF, 0x315F }, - { 0x0ED0, 0x3160 }, - { 0x0ED1, 0x3161 }, - { 0x0ED2, 0x3162 }, - { 0x0ED3, 0x3163 }, - { 0x0ED4, 0x11A8 }, - { 0x0ED5, 0x11A9 }, - { 0x0ED6, 0x11AA }, - { 0x0ED7, 0x11AB }, - { 0x0ED8, 0x11AC }, - { 0x0ED9, 0x11AD }, - { 0x0EDA, 0x11AE }, - { 0x0EDB, 0x11AF }, - { 0x0EDC, 0x11B0 }, - { 0x0EDD, 0x11B1 }, - { 0x0EDE, 0x11B2 }, - { 0x0EDF, 0x11B3 }, - { 0x0EE0, 0x11B4 }, - { 0x0EE1, 0x11B5 }, - { 0x0EE2, 0x11B6 }, - { 0x0EE3, 0x11B7 }, - { 0x0EE4, 0x11B8 }, - { 0x0EE5, 0x11B9 }, - { 0x0EE6, 0x11BA }, - { 0x0EE7, 0x11BB }, - { 0x0EE8, 0x11BC }, - { 0x0EE9, 0x11BD }, - { 0x0EEA, 0x11BE }, - { 0x0EEB, 0x11BF }, - { 0x0EEC, 0x11C0 }, - { 0x0EED, 0x11C1 }, - { 0x0EEE, 0x11C2 }, - { 0x0EEF, 0x316D }, - { 0x0EF0, 0x3171 }, - { 0x0EF1, 0x3178 }, - { 0x0EF2, 0x317F }, - { 0x0EF3, 0x3181 }, - { 0x0EF4, 0x3184 }, - { 0x0EF5, 0x3186 }, - { 0x0EF6, 0x318D }, - { 0x0EF7, 0x318E }, - { 0x0EF8, 0x11EB }, - { 0x0EF9, 0x11F0 }, - { 0x0EFA, 0x11F9 }, - { 0x0EFF, 0x20A9 }, - { 0x13A4, 0x20AC }, - { 0x13BC, 0x0152 }, - { 0x13BD, 0x0153 }, - { 0x13BE, 0x0178 }, - { 0x20AC, 0x20AC }, -}; - -unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) { - /* Latin-1 */ - if (p_keysym >= 0x20 && p_keysym <= 0x7e) { +char32_t KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) { + // Latin-1 + if (p_keysym >= 0x20 && p_keysym <= 0x7E) { return p_keysym; } - if (p_keysym >= 0xa0 && p_keysym <= 0xff) { + if (p_keysym >= 0xA0 && p_keysym <= 0xFF) { return p_keysym; } - // keypad to latin1 is easy - if (p_keysym >= 0xffaa && p_keysym <= 0xffb9) { - return p_keysym - 0xff80; - } - /* Unicode (may be present)*/ - - if ((p_keysym & 0xff000000) == 0x01000000) { - return p_keysym & 0x00ffffff; + // Keypad to Latin-1. + if (p_keysym >= 0xFFAA && p_keysym <= 0xFFB9) { + return p_keysym - 0xFF80; } - int middle, low = 0, high = _KEYSYM_MAX - 1; - do { - middle = (high + low) / 2; - if (_xkeysym_to_unicode[middle].keysym == p_keysym) { - return _xkeysym_to_unicode[middle].unicode; - } - if (_xkeysym_to_unicode[middle].keysym <= p_keysym) { - low = middle + 1; - } else { - high = middle - 1; - } - } while (high >= low); - - return 0; -} - -struct _XTranslateUnicodePairReverse { - unsigned int unicode; - KeySym keysym; -}; - -enum { - _UNICODE_MAX = 750 -}; - -static _XTranslateUnicodePairReverse _unicode_to_xkeysym[_UNICODE_MAX] = { - { 0x0ABD, 0x002E }, - { 0x0BA3, 0x003C }, - { 0x0BA6, 0x003E }, - { 0x0BC6, 0x005F }, - { 0x0BC0, 0x00AF }, - { 0x03C0, 0x0100 }, - { 0x03E0, 0x0101 }, - { 0x01C3, 0x0102 }, - { 0x01E3, 0x0103 }, - { 0x01A1, 0x0104 }, - { 0x01B1, 0x0105 }, - { 0x01C6, 0x0106 }, - { 0x01E6, 0x0107 }, - { 0x02C6, 0x0108 }, - { 0x02E6, 0x0109 }, - { 0x02C5, 0x010A }, - { 0x02E5, 0x010B }, - { 0x01C8, 0x010C }, - { 0x01E8, 0x010D }, - { 0x01CF, 0x010E }, - { 0x01EF, 0x010F }, - { 0x01D0, 0x0110 }, - { 0x01F0, 0x0111 }, - { 0x03AA, 0x0112 }, - { 0x03BA, 0x0113 }, - { 0x03CC, 0x0116 }, - { 0x03EC, 0x0117 }, - { 0x01CA, 0x0118 }, - { 0x01EA, 0x0119 }, - { 0x01CC, 0x011A }, - { 0x01EC, 0x011B }, - { 0x02D8, 0x011C }, - { 0x02F8, 0x011D }, - { 0x02AB, 0x011E }, - { 0x02BB, 0x011F }, - { 0x02D5, 0x0120 }, - { 0x02F5, 0x0121 }, - { 0x03AB, 0x0122 }, - { 0x03BB, 0x0123 }, - { 0x02A6, 0x0124 }, - { 0x02B6, 0x0125 }, - { 0x02A1, 0x0126 }, - { 0x02B1, 0x0127 }, - { 0x03A5, 0x0128 }, - { 0x03B5, 0x0129 }, - { 0x03CF, 0x012A }, - { 0x03EF, 0x012B }, - { 0x03C7, 0x012E }, - { 0x03E7, 0x012F }, - { 0x02A9, 0x0130 }, - { 0x02B9, 0x0131 }, - { 0x02AC, 0x0134 }, - { 0x02BC, 0x0135 }, - { 0x03D3, 0x0136 }, - { 0x03F3, 0x0137 }, - { 0x03A2, 0x0138 }, - { 0x01C5, 0x0139 }, - { 0x01E5, 0x013A }, - { 0x03A6, 0x013B }, - { 0x03B6, 0x013C }, - { 0x01A5, 0x013D }, - { 0x01B5, 0x013E }, - { 0x01A3, 0x0141 }, - { 0x01B3, 0x0142 }, - { 0x01D1, 0x0143 }, - { 0x01F1, 0x0144 }, - { 0x03D1, 0x0145 }, - { 0x03F1, 0x0146 }, - { 0x01D2, 0x0147 }, - { 0x01F2, 0x0148 }, - { 0x03BD, 0x014A }, - { 0x03BF, 0x014B }, - { 0x03D2, 0x014C }, - { 0x03F2, 0x014D }, - { 0x01D5, 0x0150 }, - { 0x01F5, 0x0151 }, - { 0x13BC, 0x0152 }, - { 0x13BD, 0x0153 }, - { 0x01C0, 0x0154 }, - { 0x01E0, 0x0155 }, - { 0x03A3, 0x0156 }, - { 0x03B3, 0x0157 }, - { 0x01D8, 0x0158 }, - { 0x01F8, 0x0159 }, - { 0x01A6, 0x015A }, - { 0x01B6, 0x015B }, - { 0x02DE, 0x015C }, - { 0x02FE, 0x015D }, - { 0x01AA, 0x015E }, - { 0x01BA, 0x015F }, - { 0x01A9, 0x0160 }, - { 0x01B9, 0x0161 }, - { 0x01DE, 0x0162 }, - { 0x01FE, 0x0163 }, - { 0x01AB, 0x0164 }, - { 0x01BB, 0x0165 }, - { 0x03AC, 0x0166 }, - { 0x03BC, 0x0167 }, - { 0x03DD, 0x0168 }, - { 0x03FD, 0x0169 }, - { 0x03DE, 0x016A }, - { 0x03FE, 0x016B }, - { 0x02DD, 0x016C }, - { 0x02FD, 0x016D }, - { 0x01D9, 0x016E }, - { 0x01F9, 0x016F }, - { 0x01DB, 0x0170 }, - { 0x01FB, 0x0171 }, - { 0x03D9, 0x0172 }, - { 0x03F9, 0x0173 }, - { 0x13BE, 0x0178 }, - { 0x01AC, 0x0179 }, - { 0x01BC, 0x017A }, - { 0x01AF, 0x017B }, - { 0x01BF, 0x017C }, - { 0x01AE, 0x017D }, - { 0x01BE, 0x017E }, - { 0x08F6, 0x0192 }, - { 0x01B7, 0x02C7 }, - { 0x01A2, 0x02D8 }, - { 0x01FF, 0x02D9 }, - { 0x01B2, 0x02DB }, - { 0x01BD, 0x02DD }, - { 0x07AE, 0x0385 }, - { 0x07A1, 0x0386 }, - { 0x07A2, 0x0388 }, - { 0x07A3, 0x0389 }, - { 0x07A4, 0x038A }, - { 0x07A7, 0x038C }, - { 0x07A8, 0x038E }, - { 0x07AB, 0x038F }, - { 0x07B6, 0x0390 }, - { 0x07C1, 0x0391 }, - { 0x07C2, 0x0392 }, - { 0x07C3, 0x0393 }, - { 0x07C4, 0x0394 }, - { 0x07C5, 0x0395 }, - { 0x07C6, 0x0396 }, - { 0x07C7, 0x0397 }, - { 0x07C8, 0x0398 }, - { 0x07C9, 0x0399 }, - { 0x07CA, 0x039A }, - { 0x07CB, 0x039B }, - { 0x07CC, 0x039C }, - { 0x07CD, 0x039D }, - { 0x07CE, 0x039E }, - { 0x07CF, 0x039F }, - { 0x07D0, 0x03A0 }, - { 0x07D1, 0x03A1 }, - { 0x07D2, 0x03A3 }, - { 0x07D4, 0x03A4 }, - { 0x07D5, 0x03A5 }, - { 0x07D6, 0x03A6 }, - { 0x07D7, 0x03A7 }, - { 0x07D8, 0x03A8 }, - { 0x07D9, 0x03A9 }, - { 0x07A5, 0x03AA }, - { 0x07A9, 0x03AB }, - { 0x07B1, 0x03AC }, - { 0x07B2, 0x03AD }, - { 0x07B3, 0x03AE }, - { 0x07B4, 0x03AF }, - { 0x07BA, 0x03B0 }, - { 0x07E1, 0x03B1 }, - { 0x07E2, 0x03B2 }, - { 0x07E3, 0x03B3 }, - { 0x07E4, 0x03B4 }, - { 0x07E5, 0x03B5 }, - { 0x07E6, 0x03B6 }, - { 0x07E7, 0x03B7 }, - { 0x07E8, 0x03B8 }, - { 0x07E9, 0x03B9 }, - { 0x07EA, 0x03BA }, - { 0x07EB, 0x03BB }, - { 0x07EC, 0x03BC }, - { 0x07ED, 0x03BD }, - { 0x07EE, 0x03BE }, - { 0x07EF, 0x03BF }, - { 0x07F0, 0x03C0 }, - { 0x07F1, 0x03C1 }, - { 0x07F3, 0x03C2 }, - { 0x07F2, 0x03C3 }, - { 0x07F4, 0x03C4 }, - { 0x07F5, 0x03C5 }, - { 0x07F6, 0x03C6 }, - { 0x07F7, 0x03C7 }, - { 0x07F8, 0x03C8 }, - { 0x07F9, 0x03C9 }, - { 0x07B5, 0x03CA }, - { 0x07B9, 0x03CB }, - { 0x07B7, 0x03CC }, - { 0x07B8, 0x03CD }, - { 0x07BB, 0x03CE }, - { 0x06B3, 0x0401 }, - { 0x06B1, 0x0402 }, - { 0x06B2, 0x0403 }, - { 0x06B4, 0x0404 }, - { 0x06B5, 0x0405 }, - { 0x06B6, 0x0406 }, - { 0x06B7, 0x0407 }, - { 0x06B8, 0x0408 }, - { 0x06B9, 0x0409 }, - { 0x06BA, 0x040A }, - { 0x06BB, 0x040B }, - { 0x06BC, 0x040C }, - { 0x06BE, 0x040E }, - { 0x06BF, 0x040F }, - { 0x06E1, 0x0410 }, - { 0x06E2, 0x0411 }, - { 0x06F7, 0x0412 }, - { 0x06E7, 0x0413 }, - { 0x06E4, 0x0414 }, - { 0x06E5, 0x0415 }, - { 0x06F6, 0x0416 }, - { 0x06FA, 0x0417 }, - { 0x06E9, 0x0418 }, - { 0x06EA, 0x0419 }, - { 0x06EB, 0x041A }, - { 0x06EC, 0x041B }, - { 0x06ED, 0x041C }, - { 0x06EE, 0x041D }, - { 0x06EF, 0x041E }, - { 0x06F0, 0x041F }, - { 0x06F2, 0x0420 }, - { 0x06F3, 0x0421 }, - { 0x06F4, 0x0422 }, - { 0x06F5, 0x0423 }, - { 0x06E6, 0x0424 }, - { 0x06E8, 0x0425 }, - { 0x06E3, 0x0426 }, - { 0x06FE, 0x0427 }, - { 0x06FB, 0x0428 }, - { 0x06FD, 0x0429 }, - { 0x06FF, 0x042A }, - { 0x06F9, 0x042B }, - { 0x06F8, 0x042C }, - { 0x06FC, 0x042D }, - { 0x06E0, 0x042E }, - { 0x06F1, 0x042F }, - { 0x06C1, 0x0430 }, - { 0x06C2, 0x0431 }, - { 0x06D7, 0x0432 }, - { 0x06C7, 0x0433 }, - { 0x06C4, 0x0434 }, - { 0x06C5, 0x0435 }, - { 0x06D6, 0x0436 }, - { 0x06DA, 0x0437 }, - { 0x06C9, 0x0438 }, - { 0x06CA, 0x0439 }, - { 0x06CB, 0x043A }, - { 0x06CC, 0x043B }, - { 0x06CD, 0x043C }, - { 0x06CE, 0x043D }, - { 0x06CF, 0x043E }, - { 0x06D0, 0x043F }, - { 0x06D2, 0x0440 }, - { 0x06D3, 0x0441 }, - { 0x06D4, 0x0442 }, - { 0x06D5, 0x0443 }, - { 0x06C6, 0x0444 }, - { 0x06C8, 0x0445 }, - { 0x06C3, 0x0446 }, - { 0x06DE, 0x0447 }, - { 0x06DB, 0x0448 }, - { 0x06DD, 0x0449 }, - { 0x06DF, 0x044A }, - { 0x06D9, 0x044B }, - { 0x06D8, 0x044C }, - { 0x06DC, 0x044D }, - { 0x06C0, 0x044E }, - { 0x06D1, 0x044F }, - { 0x06A3, 0x0451 }, - { 0x06A1, 0x0452 }, - { 0x06A2, 0x0453 }, - { 0x06A4, 0x0454 }, - { 0x06A5, 0x0455 }, - { 0x06A6, 0x0456 }, - { 0x06A7, 0x0457 }, - { 0x06A8, 0x0458 }, - { 0x06A9, 0x0459 }, - { 0x06AA, 0x045A }, - { 0x06AB, 0x045B }, - { 0x06AC, 0x045C }, - { 0x06AE, 0x045E }, - { 0x06AF, 0x045F }, - { 0x0CE0, 0x05D0 }, - { 0x0CE1, 0x05D1 }, - { 0x0CE2, 0x05D2 }, - { 0x0CE3, 0x05D3 }, - { 0x0CE4, 0x05D4 }, - { 0x0CE5, 0x05D5 }, - { 0x0CE6, 0x05D6 }, - { 0x0CE7, 0x05D7 }, - { 0x0CE8, 0x05D8 }, - { 0x0CE9, 0x05D9 }, - { 0x0CEA, 0x05DA }, - { 0x0CEB, 0x05DB }, - { 0x0CEC, 0x05DC }, - { 0x0CED, 0x05DD }, - { 0x0CEE, 0x05DE }, - { 0x0CEF, 0x05DF }, - { 0x0CF0, 0x05E0 }, - { 0x0CF1, 0x05E1 }, - { 0x0CF2, 0x05E2 }, - { 0x0CF3, 0x05E3 }, - { 0x0CF4, 0x05E4 }, - { 0x0CF5, 0x05E5 }, - { 0x0CF6, 0x05E6 }, - { 0x0CF7, 0x05E7 }, - { 0x0CF8, 0x05E8 }, - { 0x0CF9, 0x05E9 }, - { 0x0CFA, 0x05EA }, - { 0x05AC, 0x060C }, - { 0x05BB, 0x061B }, - { 0x05BF, 0x061F }, - { 0x05C1, 0x0621 }, - { 0x05C2, 0x0622 }, - { 0x05C3, 0x0623 }, - { 0x05C4, 0x0624 }, - { 0x05C5, 0x0625 }, - { 0x05C6, 0x0626 }, - { 0x05C7, 0x0627 }, - { 0x05C8, 0x0628 }, - { 0x05C9, 0x0629 }, - { 0x05CA, 0x062A }, - { 0x05CB, 0x062B }, - { 0x05CC, 0x062C }, - { 0x05CD, 0x062D }, - { 0x05CE, 0x062E }, - { 0x05CF, 0x062F }, - { 0x05D0, 0x0630 }, - { 0x05D1, 0x0631 }, - { 0x05D2, 0x0632 }, - { 0x05D3, 0x0633 }, - { 0x05D4, 0x0634 }, - { 0x05D5, 0x0635 }, - { 0x05D6, 0x0636 }, - { 0x05D7, 0x0637 }, - { 0x05D8, 0x0638 }, - { 0x05D9, 0x0639 }, - { 0x05DA, 0x063A }, - { 0x05E0, 0x0640 }, - { 0x05E1, 0x0641 }, - { 0x05E2, 0x0642 }, - { 0x05E3, 0x0643 }, - { 0x05E4, 0x0644 }, - { 0x05E5, 0x0645 }, - { 0x05E6, 0x0646 }, - { 0x05E7, 0x0647 }, - { 0x05E8, 0x0648 }, - { 0x05E9, 0x0649 }, - { 0x05EA, 0x064A }, - { 0x05EB, 0x064B }, - { 0x05EC, 0x064C }, - { 0x05ED, 0x064D }, - { 0x05EE, 0x064E }, - { 0x05EF, 0x064F }, - { 0x05F0, 0x0650 }, - { 0x05F1, 0x0651 }, - { 0x05F2, 0x0652 }, - { 0x0DA1, 0x0E01 }, - { 0x0DA2, 0x0E02 }, - { 0x0DA3, 0x0E03 }, - { 0x0DA4, 0x0E04 }, - { 0x0DA5, 0x0E05 }, - { 0x0DA6, 0x0E06 }, - { 0x0DA7, 0x0E07 }, - { 0x0DA8, 0x0E08 }, - { 0x0DA9, 0x0E09 }, - { 0x0DAA, 0x0E0A }, - { 0x0DAB, 0x0E0B }, - { 0x0DAC, 0x0E0C }, - { 0x0DAD, 0x0E0D }, - { 0x0DAE, 0x0E0E }, - { 0x0DAF, 0x0E0F }, - { 0x0DB0, 0x0E10 }, - { 0x0DB1, 0x0E11 }, - { 0x0DB2, 0x0E12 }, - { 0x0DB3, 0x0E13 }, - { 0x0DB4, 0x0E14 }, - { 0x0DB5, 0x0E15 }, - { 0x0DB6, 0x0E16 }, - { 0x0DB7, 0x0E17 }, - { 0x0DB8, 0x0E18 }, - { 0x0DB9, 0x0E19 }, - { 0x0DBA, 0x0E1A }, - { 0x0DBB, 0x0E1B }, - { 0x0DBC, 0x0E1C }, - { 0x0DBD, 0x0E1D }, - { 0x0DBE, 0x0E1E }, - { 0x0DBF, 0x0E1F }, - { 0x0DC0, 0x0E20 }, - { 0x0DC1, 0x0E21 }, - { 0x0DC2, 0x0E22 }, - { 0x0DC3, 0x0E23 }, - { 0x0DC4, 0x0E24 }, - { 0x0DC5, 0x0E25 }, - { 0x0DC6, 0x0E26 }, - { 0x0DC7, 0x0E27 }, - { 0x0DC8, 0x0E28 }, - { 0x0DC9, 0x0E29 }, - { 0x0DCA, 0x0E2A }, - { 0x0DCB, 0x0E2B }, - { 0x0DCC, 0x0E2C }, - { 0x0DCD, 0x0E2D }, - { 0x0DCE, 0x0E2E }, - { 0x0DCF, 0x0E2F }, - { 0x0DD0, 0x0E30 }, - { 0x0DD1, 0x0E31 }, - { 0x0DD2, 0x0E32 }, - { 0x0DD3, 0x0E33 }, - { 0x0DD4, 0x0E34 }, - { 0x0DD5, 0x0E35 }, - { 0x0DD6, 0x0E36 }, - { 0x0DD7, 0x0E37 }, - { 0x0DD8, 0x0E38 }, - { 0x0DD9, 0x0E39 }, - { 0x0DDA, 0x0E3A }, - { 0x0DDF, 0x0E3F }, - { 0x0DE0, 0x0E40 }, - { 0x0DE1, 0x0E41 }, - { 0x0DE2, 0x0E42 }, - { 0x0DE3, 0x0E43 }, - { 0x0DE4, 0x0E44 }, - { 0x0DE5, 0x0E45 }, - { 0x0DE6, 0x0E46 }, - { 0x0DE7, 0x0E47 }, - { 0x0DE8, 0x0E48 }, - { 0x0DE9, 0x0E49 }, - { 0x0DEA, 0x0E4A }, - { 0x0DEB, 0x0E4B }, - { 0x0DEC, 0x0E4C }, - { 0x0DED, 0x0E4D }, - { 0x0DF0, 0x0E50 }, - { 0x0DF1, 0x0E51 }, - { 0x0DF2, 0x0E52 }, - { 0x0DF3, 0x0E53 }, - { 0x0DF4, 0x0E54 }, - { 0x0DF5, 0x0E55 }, - { 0x0DF6, 0x0E56 }, - { 0x0DF7, 0x0E57 }, - { 0x0DF8, 0x0E58 }, - { 0x0DF9, 0x0E59 }, - { 0x0ED4, 0x11A8 }, - { 0x0ED5, 0x11A9 }, - { 0x0ED6, 0x11AA }, - { 0x0ED7, 0x11AB }, - { 0x0ED8, 0x11AC }, - { 0x0ED9, 0x11AD }, - { 0x0EDA, 0x11AE }, - { 0x0EDB, 0x11AF }, - { 0x0EDC, 0x11B0 }, - { 0x0EDD, 0x11B1 }, - { 0x0EDE, 0x11B2 }, - { 0x0EDF, 0x11B3 }, - { 0x0EE0, 0x11B4 }, - { 0x0EE1, 0x11B5 }, - { 0x0EE2, 0x11B6 }, - { 0x0EE3, 0x11B7 }, - { 0x0EE4, 0x11B8 }, - { 0x0EE5, 0x11B9 }, - { 0x0EE6, 0x11BA }, - { 0x0EE7, 0x11BB }, - { 0x0EE8, 0x11BC }, - { 0x0EE9, 0x11BD }, - { 0x0EEA, 0x11BE }, - { 0x0EEB, 0x11BF }, - { 0x0EEC, 0x11C0 }, - { 0x0EED, 0x11C1 }, - { 0x0EEE, 0x11C2 }, - { 0x0EF8, 0x11EB }, - { 0x0EFA, 0x11F9 }, - { 0x0AA2, 0x2002 }, - { 0x0AA1, 0x2003 }, - { 0x0AA3, 0x2004 }, - { 0x0AA4, 0x2005 }, - { 0x0AA5, 0x2007 }, - { 0x0AA6, 0x2008 }, - { 0x0AA7, 0x2009 }, - { 0x0AA8, 0x200A }, - { 0x0ABB, 0x2012 }, - { 0x0AAA, 0x2013 }, - { 0x0AA9, 0x2014 }, - { 0x07AF, 0x2015 }, - { 0x0CDF, 0x2017 }, - { 0x0AD0, 0x2018 }, - { 0x0AD1, 0x2019 }, - { 0x0AFD, 0x201A }, - { 0x0AD2, 0x201C }, - { 0x0AD3, 0x201D }, - { 0x0AFE, 0x201E }, - { 0x0AF1, 0x2020 }, - { 0x0AF2, 0x2021 }, - { 0x0AE6, 0x2022 }, - { 0x0AAE, 0x2026 }, - { 0x0AD6, 0x2032 }, - { 0x0AD7, 0x2033 }, - { 0x0AFC, 0x2038 }, - { 0x047E, 0x203E }, - { 0x20A0, 0x20A0 }, - { 0x20A1, 0x20A1 }, - { 0x20A2, 0x20A2 }, - { 0x20A3, 0x20A3 }, - { 0x20A4, 0x20A4 }, - { 0x20A5, 0x20A5 }, - { 0x20A6, 0x20A6 }, - { 0x20A7, 0x20A7 }, - { 0x20A8, 0x20A8 }, - { 0x0EFF, 0x20A9 }, - { 0x20A9, 0x20A9 }, - { 0x20AA, 0x20AA }, - { 0x20AB, 0x20AB }, - { 0x20AC, 0x20AC }, - { 0x0AB8, 0x2105 }, - { 0x06B0, 0x2116 }, - { 0x0AFB, 0x2117 }, - { 0x0AD4, 0x211E }, - { 0x0AC9, 0x2122 }, - { 0x0AB0, 0x2153 }, - { 0x0AB1, 0x2154 }, - { 0x0AB2, 0x2155 }, - { 0x0AB3, 0x2156 }, - { 0x0AB4, 0x2157 }, - { 0x0AB5, 0x2158 }, - { 0x0AB6, 0x2159 }, - { 0x0AB7, 0x215A }, - { 0x0AC3, 0x215B }, - { 0x0AC4, 0x215C }, - { 0x0AC5, 0x215D }, - { 0x0AC6, 0x215E }, - { 0x08FB, 0x2190 }, - { 0x08FC, 0x2191 }, - { 0x08FD, 0x2192 }, - { 0x08FE, 0x2193 }, - { 0x08CE, 0x21D2 }, - { 0x08CD, 0x21D4 }, - { 0x08EF, 0x2202 }, - { 0x08C5, 0x2207 }, - { 0x0BCA, 0x2218 }, - { 0x08D6, 0x221A }, - { 0x08C1, 0x221D }, - { 0x08C2, 0x221E }, - { 0x08DE, 0x2227 }, - { 0x0BA9, 0x2227 }, - { 0x08DF, 0x2228 }, - { 0x0BA8, 0x2228 }, - { 0x08DC, 0x2229 }, - { 0x0BC3, 0x2229 }, - { 0x08DD, 0x222A }, - { 0x0BD6, 0x222A }, - { 0x08BF, 0x222B }, - { 0x08C0, 0x2234 }, - { 0x08C8, 0x2245 }, - { 0x08BD, 0x2260 }, - { 0x08CF, 0x2261 }, - { 0x08BC, 0x2264 }, - { 0x08BE, 0x2265 }, - { 0x08DA, 0x2282 }, - { 0x0BDA, 0x2282 }, - { 0x08DB, 0x2283 }, - { 0x0BD8, 0x2283 }, - { 0x0BFC, 0x22A2 }, - { 0x0BDC, 0x22A3 }, - { 0x0BC2, 0x22A4 }, - { 0x0BCE, 0x22A5 }, - { 0x0BD3, 0x2308 }, - { 0x0BC4, 0x230A }, - { 0x0AFA, 0x2315 }, - { 0x08A4, 0x2320 }, - { 0x08A5, 0x2321 }, - { 0x0ABC, 0x2329 }, - { 0x0ABE, 0x232A }, - { 0x0BCC, 0x2395 }, - { 0x09E2, 0x2409 }, - { 0x09E5, 0x240A }, - { 0x09E9, 0x240B }, - { 0x09E3, 0x240C }, - { 0x09E4, 0x240D }, - { 0x09DF, 0x2422 }, - { 0x09E8, 0x2424 }, - { 0x09F1, 0x2500 }, - { 0x08A6, 0x2502 }, - { 0x09F8, 0x2502 }, - { 0x09EC, 0x250C }, - { 0x09EB, 0x2510 }, - { 0x09ED, 0x2514 }, - { 0x09EA, 0x2518 }, - { 0x09F4, 0x251C }, - { 0x09F5, 0x2524 }, - { 0x09F7, 0x252C }, - { 0x09F6, 0x2534 }, - { 0x09EE, 0x253C }, - { 0x09E1, 0x2592 }, - { 0x0ADF, 0x25A0 }, - { 0x0ACF, 0x25A1 }, - { 0x0AE7, 0x25AA }, - { 0x0AE1, 0x25AB }, - { 0x0ADB, 0x25AC }, - { 0x0AE2, 0x25AD }, - { 0x0AE8, 0x25B2 }, - { 0x0AE3, 0x25B3 }, - { 0x0ADD, 0x25B6 }, - { 0x0ACD, 0x25B7 }, - { 0x0AE9, 0x25BC }, - { 0x0AE4, 0x25BD }, - { 0x0ADC, 0x25C0 }, - { 0x0ACC, 0x25C1 }, - { 0x09E0, 0x25C6 }, - { 0x0ACE, 0x25CB }, - { 0x0BCF, 0x25CB }, - { 0x0ADE, 0x25CF }, - { 0x0AE0, 0x25E6 }, - { 0x0AE5, 0x2606 }, - { 0x0AF9, 0x260E }, - { 0x0ACA, 0x2613 }, - { 0x0AEA, 0x261C }, - { 0x0AEB, 0x261E }, - { 0x0AF8, 0x2640 }, - { 0x0AF7, 0x2642 }, - { 0x0AEC, 0x2663 }, - { 0x0AEE, 0x2665 }, - { 0x0AED, 0x2666 }, - { 0x0AF6, 0x266D }, - { 0x0AF5, 0x266F }, - { 0x0AF3, 0x2713 }, - { 0x0AF4, 0x2717 }, - { 0x0AD9, 0x271D }, - { 0x0AF0, 0x2720 }, - { 0x04A4, 0x3001 }, - { 0x04A1, 0x3002 }, - { 0x04A2, 0x300C }, - { 0x04A3, 0x300D }, - { 0x04DE, 0x309B }, - { 0x04DF, 0x309C }, - { 0x04A7, 0x30A1 }, - { 0x04B1, 0x30A2 }, - { 0x04A8, 0x30A3 }, - { 0x04B2, 0x30A4 }, - { 0x04A9, 0x30A5 }, - { 0x04B3, 0x30A6 }, - { 0x04AA, 0x30A7 }, - { 0x04B4, 0x30A8 }, - { 0x04AB, 0x30A9 }, - { 0x04B5, 0x30AA }, - { 0x04B6, 0x30AB }, - { 0x04B7, 0x30AD }, - { 0x04B8, 0x30AF }, - { 0x04B9, 0x30B1 }, - { 0x04BA, 0x30B3 }, - { 0x04BB, 0x30B5 }, - { 0x04BC, 0x30B7 }, - { 0x04BD, 0x30B9 }, - { 0x04BE, 0x30BB }, - { 0x04BF, 0x30BD }, - { 0x04C0, 0x30BF }, - { 0x04C1, 0x30C1 }, - { 0x04AF, 0x30C3 }, - { 0x04C2, 0x30C4 }, - { 0x04C3, 0x30C6 }, - { 0x04C4, 0x30C8 }, - { 0x04C5, 0x30CA }, - { 0x04C6, 0x30CB }, - { 0x04C7, 0x30CC }, - { 0x04C8, 0x30CD }, - { 0x04C9, 0x30CE }, - { 0x04CA, 0x30CF }, - { 0x04CB, 0x30D2 }, - { 0x04CC, 0x30D5 }, - { 0x04CD, 0x30D8 }, - { 0x04CE, 0x30DB }, - { 0x04CF, 0x30DE }, - { 0x04D0, 0x30DF }, - { 0x04D1, 0x30E0 }, - { 0x04D2, 0x30E1 }, - { 0x04D3, 0x30E2 }, - { 0x04AC, 0x30E3 }, - { 0x04D4, 0x30E4 }, - { 0x04AD, 0x30E5 }, - { 0x04D5, 0x30E6 }, - { 0x04AE, 0x30E7 }, - { 0x04D6, 0x30E8 }, - { 0x04D7, 0x30E9 }, - { 0x04D8, 0x30EA }, - { 0x04D9, 0x30EB }, - { 0x04DA, 0x30EC }, - { 0x04DB, 0x30ED }, - { 0x04DC, 0x30EF }, - { 0x04A6, 0x30F2 }, - { 0x04DD, 0x30F3 }, - { 0x04A5, 0x30FB }, - { 0x04B0, 0x30FC }, - { 0x0EA1, 0x3131 }, - { 0x0EA2, 0x3132 }, - { 0x0EA3, 0x3133 }, - { 0x0EA4, 0x3134 }, - { 0x0EA5, 0x3135 }, - { 0x0EA6, 0x3136 }, - { 0x0EA7, 0x3137 }, - { 0x0EA8, 0x3138 }, - { 0x0EA9, 0x3139 }, - { 0x0EAA, 0x313A }, - { 0x0EAB, 0x313B }, - { 0x0EAC, 0x313C }, - { 0x0EAD, 0x313D }, - { 0x0EAE, 0x313E }, - { 0x0EAF, 0x313F }, - { 0x0EB0, 0x3140 }, - { 0x0EB1, 0x3141 }, - { 0x0EB2, 0x3142 }, - { 0x0EB3, 0x3143 }, - { 0x0EB4, 0x3144 }, - { 0x0EB5, 0x3145 }, - { 0x0EB6, 0x3146 }, - { 0x0EB7, 0x3147 }, - { 0x0EB8, 0x3148 }, - { 0x0EB9, 0x3149 }, - { 0x0EBA, 0x314A }, - { 0x0EBB, 0x314B }, - { 0x0EBC, 0x314C }, - { 0x0EBD, 0x314D }, - { 0x0EBE, 0x314E }, - { 0x0EBF, 0x314F }, - { 0x0EC0, 0x3150 }, - { 0x0EC1, 0x3151 }, - { 0x0EC2, 0x3152 }, - { 0x0EC3, 0x3153 }, - { 0x0EC4, 0x3154 }, - { 0x0EC5, 0x3155 }, - { 0x0EC6, 0x3156 }, - { 0x0EC7, 0x3157 }, - { 0x0EC8, 0x3158 }, - { 0x0EC9, 0x3159 }, - { 0x0ECA, 0x315A }, - { 0x0ECB, 0x315B }, - { 0x0ECC, 0x315C }, - { 0x0ECD, 0x315D }, - { 0x0ECE, 0x315E }, - { 0x0ECF, 0x315F }, - { 0x0ED0, 0x3160 }, - { 0x0ED1, 0x3161 }, - { 0x0ED2, 0x3162 }, - { 0x0ED3, 0x3163 }, - { 0x0EEF, 0x316D }, - { 0x0EF0, 0x3171 }, - { 0x0EF1, 0x3178 }, - { 0x0EF2, 0x317F }, - { 0x0EF4, 0x3184 }, - { 0x0EF5, 0x3186 }, - { 0x0EF6, 0x318D }, - { 0x0EF7, 0x318E } -}; - -KeySym KeyMappingX11::get_keysym_from_unicode(unsigned int p_unicode) { - /* Latin 1 */ - - if (p_unicode >= 0x20 && p_unicode <= 0x7e) { - return p_unicode; + // Unicode (may be present). + if ((p_keysym & 0xFF000000) == 0x01000000) { + return p_keysym & 0x00FFFFFF; } - if (p_unicode >= 0xa0 && p_unicode <= 0xff) { - return p_unicode; + const char32_t *c = xkeysym_unicode_map.getptr(p_keysym); + if (c) { + return *c; } - - int middle, low = 0, high = _UNICODE_MAX - 1; - do { - middle = (high + low) / 2; - if (_unicode_to_xkeysym[middle].keysym == p_unicode) { - return _unicode_to_xkeysym[middle].keysym; - } - if (_unicode_to_xkeysym[middle].keysym <= p_unicode) { - low = middle + 1; - } else { - high = middle - 1; - } - } while (high >= low); - - // if not found, let's hope X understands it as unicode - return p_unicode | 0x01000000; + return 0; } diff --git a/platform/linuxbsd/x11/key_mapping_x11.h b/platform/linuxbsd/x11/key_mapping_x11.h index 2b411e21d2..48beefff4c 100644 --- a/platform/linuxbsd/x11/key_mapping_x11.h +++ b/platform/linuxbsd/x11/key_mapping_x11.h @@ -39,17 +39,30 @@ #include <X11/keysymdef.h> #include "core/os/keyboard.h" +#include "core/templates/hash_map.h" class KeyMappingX11 { + struct HashMapHasherKeys { + static _FORCE_INLINE_ uint32_t hash(const Key p_key) { return hash_fmix32(static_cast<uint32_t>(p_key)); } + static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); } + static _FORCE_INLINE_ uint32_t hash(const unsigned p_key) { return hash_fmix32(p_key); } + static _FORCE_INLINE_ uint32_t hash(const KeySym p_key) { return hash_fmix32(p_key); } + }; + + static inline HashMap<KeySym, Key, HashMapHasherKeys> xkeysym_map; + static inline HashMap<unsigned int, Key, HashMapHasherKeys> scancode_map; + static inline HashMap<Key, unsigned int, HashMapHasherKeys> scancode_map_inv; + static inline HashMap<KeySym, char32_t, HashMapHasherKeys> xkeysym_unicode_map; + KeyMappingX11() {} public: + static void initialize(); + static Key get_keycode(KeySym p_keysym); static unsigned int get_xlibcode(Key p_keysym); static Key get_scancode(unsigned int p_code); - static KeySym get_keysym(Key p_code); - static unsigned int get_unicode_from_keysym(KeySym p_keysym); - static KeySym get_keysym_from_unicode(unsigned int p_unicode); + static char32_t get_unicode_from_keysym(KeySym p_keysym); }; #endif // KEY_MAPPING_X11_H |