From 8050a28beb37d1e90d6cc5d542b6eac6a222a17a Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 16 Mar 2013 14:12:16 +0100 Subject: [PATCH] uterm: input: add built-in keymap fallback This adds a small US-keymap to the uterm library which is loaded if we cannot find a suitable system default keymap. This allows using the keymap if no XKB keymaps are installed. Thanks to Ran Benita for the minimal US keymap. Signed-off-by: David Herrmann --- .gitignore | 1 + Makefile.am | 25 +- src/uterm_input_fallback.xkb | 636 +++++++++++++++++++++++++++++++++++++++++++ src/uterm_input_uxkb.c | 28 +- 4 files changed, 683 insertions(+), 7 deletions(-) create mode 100644 src/uterm_input_fallback.xkb diff --git a/.gitignore b/.gitignore index 428737a..717dac7 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ docs/man/*.5 docs/man/*.7 src/*.vert.bin src/*.frag.bin +src/*.xkb.bin diff --git a/Makefile.am b/Makefile.am index ee84429..5478d0c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -169,6 +169,28 @@ src/%.frag.bin: $(top_srcdir)/src/%.frag $(AM_V_at)$(SED) $(SHADER_SED) "$<" | tr $(SHADER_TR) >"$@" # +# XKB Fallback Converter +# We use a static built-in XKB fallback keymap. To avoid huge memory consumption +# we remove useless lines/characters first. +# We also append an ASCII 0 character so it can be used as regular C-string. +# +# Following regexp are used to remove characters/lines: +# *= * Whitespace around assignments +# *, * Whitespace around commatas +# *[][{}()] * Whitespace around braces +# ^[ \t]* Indentation whitespace +# [\r\n] Newlines +# + +CLEANFILES += src/*.xkb.bin +XKB_SED = -e 's/^[ \t]*//' -e 's/ *\([,=]\) */\1/g' -e 's/ *\([][{}()]\) */\1/g' +XKB_TR = -d "\r\n" + +src/%.xkb.bin: $(top_srcdir)/src/%.xkb + $(AM_V_at)$(SED) $(XKB_SED) "$<" | tr $(XKB_TR) >"$@" + $(AM_V_at)echo -ne "\x00" >>"$@" + +# # SHL - Static Helper Library # The SHL subsystem contains several small code pieces used all over kmscon and # other applications. @@ -262,7 +284,8 @@ libuterm_la_LIBADD = \ $(UDEV_LIBS) \ $(XKBCOMMON_LIBS) \ libeloop.la \ - libshl.la + libshl.la \ + src/uterm_input_fallback.xkb.bin.lo libuterm_la_LDFLAGS = \ $(AM_LDFLAGS) diff --git a/src/uterm_input_fallback.xkb b/src/uterm_input_fallback.xkb new file mode 100644 index 0000000..dc386df --- /dev/null +++ b/src/uterm_input_fallback.xkb @@ -0,0 +1,636 @@ +xkb_keymap { +xkb_keycodes { + = 9; + = 10; + = 11; + = 12; + = 13; + = 14; + = 15; + = 16; + = 17; + = 18; + = 19; + = 20; + = 21; + = 22; + = 23; + = 24; + = 25; + = 26; + = 27; + = 28; + = 29; + = 30; + = 31; + = 32; + = 33; + = 34; + = 35; + = 36; + = 37; + = 38; + = 39; + = 40; + = 41; + = 42; + = 43; + = 44; + = 45; + = 46; + = 47; + = 48; + = 49; + = 50; + = 51; + = 52; + = 53; + = 54; + = 55; + = 56; + = 57; + = 58; + = 59; + = 60; + = 61; + = 62; + = 63; + = 64; + = 65; + = 66; + = 67; + = 68; + = 69; + = 70; + = 71; + = 72; + = 73; + = 74; + = 75; + = 76; + = 77; + = 78; + = 79; + = 80; + = 81; + = 82; + = 83; + = 84; + = 85; + = 86; + = 87; + = 88; + = 89; + = 90; + = 91; + = 92; + = 94; + = 95; + = 96; + = 98; + = 99; + = 100; + = 101; + = 102; + = 104; + = 105; + = 106; + = 107; + = 108; + = 109; + = 110; + = 111; + = 112; + = 113; + = 114; + = 115; + = 116; + = 117; + = 118; + = 119; + = 121; + = 122; + = 123; + = 124; + = 125; + = 126; + = 127; + = 128; + = 129; + = 130; + = 131; + = 133; + = 134; + = 135; + = 136; + = 137; + = 138; + = 139; + = 140; + = 141; + = 142; + = 143; + = 144; + = 145; + = 146; + = 147; + = 148; + = 150; + = 151; + = 152; + = 153; + = 155; + = 156; + = 157; + = 158; + = 159; + = 160; + = 162; + = 163; + = 164; + = 165; + = 166; + = 167; + = 169; + = 170; + = 171; + = 172; + = 173; + = 174; + = 175; + = 176; + = 177; + = 179; + = 180; + = 181; + = 182; + = 185; + = 186; + = 187; + = 188; + = 189; + = 190; + = 191; + = 192; + = 193; + = 194; + = 195; + = 196; + = 199; + = 200; + = 201; + = 203; + = 204; + = 205; + = 206; + = 207; + = 208; + = 209; + = 210; + = 211; + = 212; + = 213; + = 214; + = 215; + = 216; + = 218; + = 220; + = 223; + = 224; + = 225; + = 226; + = 227; + = 228; + = 229; + = 231; + = 232; + = 233; + = 234; + = 235; + = 236; + = 237; + = 238; + = 239; + = 240; + = 241; + = 242; + = 243; + = 244; + = 245; + = 246; + indicator 1 = "Caps Lock"; + indicator 2 = "Num Lock"; + indicator 3 = "Scroll Lock"; +}; + +xkb_types { + virtual_modifiers NumLock,Alt,LevelThree,ScrollLock,AltGr,Meta,Super,Hyper; + type "ONE_LEVEL" { + modifiers= none; + level_name[Level1]= "Any"; + }; + type "TWO_LEVEL" { + modifiers= Shift; + map[Shift]= Level2; + level_name[Level1]= "Base"; + level_name[Level2]= "Shift"; + }; + type "ALPHABETIC" { + modifiers= Shift+Lock; + map[Shift]= Level2; + map[Lock]= Level2; + level_name[Level1]= "Base"; + level_name[Level2]= "Caps"; + }; + type "SHIFT+ALT" { + modifiers= Shift+Alt; + map[Shift+Alt]= Level2; + level_name[Level1]= "Base"; + level_name[Level2]= "Shift+Alt"; + }; + type "PC_CONTROL_LEVEL2" { + modifiers= Control; + map[Control]= Level2; + level_name[Level1]= "Base"; + level_name[Level2]= "Control"; + }; + type "PC_ALT_LEVEL2" { + modifiers= Alt; + map[Alt]= Level2; + level_name[Level1]= "Base"; + level_name[Level2]= "Alt"; + }; + type "CTRL+ALT" { + modifiers= Shift+Control+Alt+LevelThree; + map[Shift]= Level2; + preserve[Shift]= Shift; + map[LevelThree]= Level3; + map[Shift+LevelThree]= Level4; + preserve[Shift+LevelThree]= Shift; + map[Control+Alt]= Level5; + level_name[Level1]= "Base"; + level_name[Level2]= "Shift"; + level_name[Level3]= "Alt Base"; + level_name[Level4]= "Shift Alt"; + level_name[Level5]= "Ctrl+Alt"; + }; + type "FOUR_LEVEL" { + modifiers= Shift+LevelThree; + map[Shift]= Level2; + map[LevelThree]= Level3; + map[Shift+LevelThree]= Level4; + level_name[Level1]= "Base"; + level_name[Level2]= "Shift"; + level_name[Level3]= "Alt Base"; + level_name[Level4]= "Shift Alt"; + }; + type "KEYPAD" { + modifiers= Shift+NumLock; + map[Shift]= Level2; + map[NumLock]= Level2; + level_name[Level1]= "Base"; + level_name[Level2]= "Number"; + }; +}; + +xkb_compatibility { + virtual_modifiers NumLock,Alt,LevelThree,ScrollLock,AltGr,Meta,Super,Hyper; + interpret.useModMapMods= AnyLevel; + interpret.repeat= False; + interpret ISO_Level3_Shift+AnyOf(all) { + virtualModifier= LevelThree; + useModMapMods=level1; + action= SetMods(modifiers=LevelThree,clearLocks); + }; + interpret Num_Lock+AnyOf(all) { + virtualModifier= NumLock; + action= LockMods(modifiers=NumLock); + }; + interpret Alt_L+AnyOf(all) { + virtualModifier= Alt; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Alt_R+AnyOf(all) { + virtualModifier= Alt; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Meta_L+AnyOf(all) { + virtualModifier= Meta; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Meta_R+AnyOf(all) { + virtualModifier= Meta; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Super_L+AnyOf(all) { + virtualModifier= Super; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Super_R+AnyOf(all) { + virtualModifier= Super; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Hyper_L+AnyOf(all) { + virtualModifier= Hyper; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Hyper_R+AnyOf(all) { + virtualModifier= Hyper; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Scroll_Lock+AnyOf(all) { + virtualModifier= ScrollLock; + action= LockMods(modifiers=modMapMods); + }; + interpret Mode_switch+AnyOfOrNone(all) { + virtualModifier= AltGr; + useModMapMods=level1; + action= SetGroup(group=+1); + }; + interpret Alt_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Alt,clearLocks); + }; + interpret Alt_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Alt,clearLocks); + }; + interpret Meta_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Meta,clearLocks); + }; + interpret Meta_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Meta,clearLocks); + }; + interpret Super_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Super,clearLocks); + }; + interpret Super_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Super,clearLocks); + }; + interpret Hyper_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Hyper,clearLocks); + }; + interpret Hyper_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Hyper,clearLocks); + }; + interpret Shift_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Shift,clearLocks); + }; + interpret Caps_Lock+AnyOfOrNone(all) { + action= LockMods(modifiers=Lock); + }; + interpret Any+Exactly(Lock) { + action= LockMods(modifiers=Lock); + }; + interpret Any+AnyOf(all) { + action= SetMods(modifiers=modMapMods,clearLocks); + }; + indicator "Caps Lock" { + whichModState= locked; + modifiers= Lock; + }; + indicator "Num Lock" { + whichModState= locked; + modifiers= NumLock; + }; + indicator "Scroll Lock" { + whichModState= locked; + modifiers= ScrollLock; + }; +}; + +xkb_symbols { + name[group1]="English (US)"; + key { [ Escape ] }; + key { [ 1, exclam ] }; + key { [ 2, at ] }; + key { [ 3, numbersign ] }; + key { [ 4, dollar ] }; + key { [ 5, percent ] }; + key { [ 6, asciicircum ] }; + key { [ 7, ampersand ] }; + key { [ 8, asterisk ] }; + key { [ 9, parenleft ] }; + key { [ 0, parenright ] }; + key { [ minus, underscore ] }; + key { [ equal, plus ] }; + key { [ BackSpace, BackSpace ] }; + key { [ Tab, ISO_Left_Tab ] }; + key { [ q, Q ] }; + key { [ w, W ] }; + key { [ e, E ] }; + key { [ r, R ] }; + key { [ t, T ] }; + key { [ y, Y ] }; + key { [ u, U ] }; + key { [ i, I ] }; + key { [ o, O ] }; + key { [ p, P ] }; + key { [ bracketleft, braceleft ] }; + key { [ bracketright, braceright ] }; + key { [ Return ] }; + key { [ Control_L ] }; + key { [ a, A ] }; + key { [ s, S ] }; + key { [ d, D ] }; + key { [ f, F ] }; + key { [ g, G ] }; + key { [ h, H ] }; + key { [ j, J ] }; + key { [ k, K ] }; + key { [ l, L ] }; + key { [ semicolon, colon ] }; + key { [ apostrophe, quotedbl ] }; + key { [ grave, asciitilde ] }; + key { [ Shift_L ] }; + key { [ backslash, bar ] }; + key { [ z, Z ] }; + key { [ x, X ] }; + key { [ c, C ] }; + key { [ v, V ] }; + key { [ b, B ] }; + key { [ n, N ] }; + key { [ m, M ] }; + key { [ comma, less ] }; + key { [ period, greater ] }; + key { [ slash, question ] }; + key { [ Shift_R ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ KP_Multiply, KP_Multiply, KP_Multiply, KP_Multiply, XF86ClearGrab ] }; + key { [ Alt_L, Meta_L ] }; + key { [ space ] }; + key { [ Caps_Lock ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F1, F1, F1, F1, XF86Switch_VT_1 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F2, F2, F2, F2, XF86Switch_VT_2 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F3, F3, F3, F3, XF86Switch_VT_3 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F4, F4, F4, F4, XF86Switch_VT_4 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F5, F5, F5, F5, XF86Switch_VT_5 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F6, F6, F6, F6, XF86Switch_VT_6 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F7, F7, F7, F7, XF86Switch_VT_7 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F8, F8, F8, F8, XF86Switch_VT_8 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F9, F9, F9, F9, XF86Switch_VT_9 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F10, F10, F10, F10, XF86Switch_VT_10 ] }; + key { [ Num_Lock ] }; + key { [ Scroll_Lock ] }; + key { [ KP_Home, KP_7 ] }; + key { [ KP_Up, KP_8 ] }; + key { [ KP_Prior, KP_9 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ KP_Subtract, KP_Subtract, KP_Subtract, KP_Subtract, XF86Prev_VMode ] }; + key { [ KP_Left, KP_4 ] }; + key { [ KP_Begin, KP_5 ] }; + key { [ KP_Right, KP_6 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ KP_Add, KP_Add, KP_Add, KP_Add, XF86Next_VMode ] }; + key { [ KP_End, KP_1 ] }; + key { [ KP_Down, KP_2 ] }; + key { [ KP_Next, KP_3 ] }; + key { [ KP_Insert, KP_0 ] }; + key { [ KP_Delete, KP_Decimal ] }; + key { [ ISO_Level3_Shift ] }; + key { [ less, greater, bar, brokenbar ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F11, F11, F11, F11, XF86Switch_VT_11 ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ F12, F12, F12, F12, XF86Switch_VT_12 ] }; + key { [ Katakana ] }; + key { [ Hiragana ] }; + key { [ Henkan_Mode ] }; + key { [ Hiragana_Katakana ] }; + key { [ Muhenkan ] }; + key { [ KP_Enter ] }; + key { [ Control_R ] }; + key { type= "CTRL+ALT", symbols[Group1]= [ KP_Divide, KP_Divide, KP_Divide, KP_Divide, XF86Ungrab ] }; + key { type= "PC_ALT_LEVEL2", symbols[Group1]= [ Print, Sys_Req ] }; + key { type= "TWO_LEVEL", symbols[Group1]= [ Alt_R, Meta_R ] }; + key { [ Linefeed ] }; + key { [ Home ] }; + key { [ Up ] }; + key { [ Prior ] }; + key { [ Left ] }; + key { [ Right ] }; + key { [ End ] }; + key { [ Down ] }; + key { [ Next ] }; + key { [ Insert ] }; + key { [ Delete ] }; + key { [ XF86AudioMute ] }; + key { [ XF86AudioLowerVolume ] }; + key { [ XF86AudioRaiseVolume ] }; + key { [ XF86PowerOff ] }; + key { [ KP_Equal ] }; + key { [ plusminus ] }; + key { type= "PC_CONTROL_LEVEL2", symbols[Group1]= [ Pause, Break ] }; + key { [ XF86LaunchA ] }; + key { [ KP_Decimal, KP_Decimal ] }; + key { [ Hangul ] }; + key { [ Hangul_Hanja ] }; + key { [ Super_L ] }; + key { [ Super_R ] }; + key { [ Menu ] }; + key { [ Cancel ] }; + key { [ Redo ] }; + key { [ SunProps ] }; + key { [ Undo ] }; + key { [ SunFront ] }; + key { [ XF86Copy ] }; + key { [ XF86Open ] }; + key { [ XF86Paste ] }; + key { [ Find ] }; + key { [ XF86Cut ] }; + key { [ Help ] }; + key { [ XF86MenuKB ] }; + key { [ XF86Calculator ] }; + key { [ XF86Sleep ] }; + key { [ XF86WakeUp ] }; + key { [ XF86Explorer ] }; + key { [ XF86Send ] }; + key { [ XF86Xfer ] }; + key { [ XF86Launch1 ] }; + key { [ XF86Launch2 ] }; + key { [ XF86WWW ] }; + key { [ XF86DOS ] }; + key { [ XF86ScreenSaver ] }; + key { [ XF86RotateWindows ] }; + key { [ XF86Mail ] }; + key { [ XF86Favorites ] }; + key { [ XF86MyComputer ] }; + key { [ XF86Back ] }; + key { [ XF86Forward ] }; + key { [ XF86Eject ] }; + key { [ XF86Eject, XF86Eject ] }; + key { [ XF86AudioNext ] }; + key { [ XF86AudioPlay, XF86AudioPause ] }; + key { [ XF86AudioPrev ] }; + key { [ XF86AudioStop, XF86Eject ] }; + key { [ XF86AudioRecord ] }; + key { [ XF86AudioRewind ] }; + key { [ XF86Phone ] }; + key { [ XF86Tools ] }; + key { [ XF86HomePage ] }; + key { [ XF86Reload ] }; + key { [ XF86Close ] }; + key { [ XF86ScrollUp ] }; + key { [ XF86ScrollDown ] }; + key { [ parenleft ] }; + key { [ parenright ] }; + key { [ XF86New ] }; + key { [ Redo ] }; + key { [ XF86Tools ] }; + key { [ XF86Launch5 ] }; + key { [ XF86Launch6 ] }; + key { [ XF86Launch7 ] }; + key { [ XF86Launch8 ] }; + key { [ XF86Launch9 ] }; + key { [ XF86TouchpadToggle ] }; + key { [ XF86TouchpadOn ] }; + key { [ XF86TouchpadOff ] }; + key { [ Mode_switch ] }; + key { [ NoSymbol, Alt_L ] }; + key { [ NoSymbol, Meta_L ] }; + key { [ NoSymbol, Super_L ] }; + key { [ NoSymbol, Hyper_L ] }; + key { [ XF86AudioPlay ] }; + key { [ XF86AudioPause ] }; + key { [ XF86Launch3 ] }; + key { [ XF86Launch4 ] }; + key { [ XF86LaunchB ] }; + key { [ XF86Suspend ] }; + key { [ XF86Close ] }; + key { [ XF86AudioPlay ] }; + key { [ XF86AudioForward ] }; + key { [ Print ] }; + key { [ XF86WebCam ] }; + key { [ XF86Mail ] }; + key { [ XF86Messenger ] }; + key { [ XF86Search ] }; + key { [ XF86Go ] }; + key { [ XF86Finance ] }; + key { [ XF86Game ] }; + key { [ XF86Shop ] }; + key { [ Cancel ] }; + key { [ XF86MonBrightnessDown ] }; + key { [ XF86MonBrightnessUp ] }; + key { [ XF86AudioMedia ] }; + key { [ XF86Display ] }; + key { [ XF86KbdLightOnOff ] }; + key { [ XF86KbdBrightnessDown ] }; + key { [ XF86KbdBrightnessUp ] }; + key { [ XF86Send ] }; + key { [ XF86Reply ] }; + key { [ XF86MailForward ] }; + key { [ XF86Save ] }; + key { [ XF86Documents ] }; + key { [ XF86Battery ] }; + key { [ XF86Bluetooth ] }; + key { [ XF86WLAN ] }; + modifier_map Control { }; + modifier_map Shift { }; + modifier_map Shift { }; + modifier_map Mod1 { }; + modifier_map Lock { }; + modifier_map Mod2 { }; + modifier_map Mod5 { }; + modifier_map Control { }; + modifier_map Mod1 { }; + modifier_map Mod4 { }; + modifier_map Mod4 { }; + modifier_map Mod5 { }; + modifier_map Mod1 { }; + modifier_map Mod4 { }; + modifier_map Mod4 { }; +}; +}; diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c index 8ba4abc..14d9937 100644 --- a/src/uterm_input_uxkb.c +++ b/src/uterm_input_uxkb.c @@ -2,7 +2,7 @@ * uterm - Linux User-Space Terminal * * Copyright (c) 2011 Ran Benita - * Copyright (c) 2012 David Herrmann + * Copyright (c) 2012-2013 David Herrmann * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files @@ -40,6 +40,9 @@ #define LOG_SUBSYSTEM "input_uxkb" +extern const char _binary_src_uterm_input_fallback_xkb_bin_start[]; +extern const char _binary_src_uterm_input_fallback_xkb_bin_end[]; + int uxkb_desc_init(struct uterm_input *input, const char *model, const char *layout, @@ -55,6 +58,9 @@ int uxkb_desc_init(struct uterm_input *input, .variant = variant, .options = options, }; + const char *fallback; + + fallback = _binary_src_uterm_input_fallback_xkb_bin_start; input->ctx = xkb_context_new(0); if (!input->ctx) { @@ -88,14 +94,24 @@ int uxkb_desc_init(struct uterm_input *input, input->keymap = xkb_keymap_new_from_names(input->ctx, &rmlvo, 0); if (!input->keymap) { - log_warn("failed to create XKB keymap"); - ret = -EFAULT; - goto err_ctx; + log_warn("failed to create XKB default keymap, " + "reverting to built-in fallback"); + + input->keymap = xkb_keymap_new_from_string(input->ctx, + fallback, XKB_KEYMAP_FORMAT_TEXT_V1, 0); + if (!input->keymap) { + log_error("cannot create fallback keymap"); + ret = -EFAULT; + goto err_ctx; + } } + + log_debug("new fallback keyboard description"); + } else { + log_debug("new keyboard description (%s, %s, %s, %s)", + model, layout, variant, options); } - log_debug("new keyboard description (%s, %s, %s, %s)", - model, layout, variant, options); return 0; err_ctx: -- 2.7.4