From 118935c9068bd70b2ecd834922264069272857c3 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Fri, 15 Mar 2013 16:15:06 +0100 Subject: [PATCH 01/16] genunifont: remove useless status message No reason to clutter build output with this debug message. Drop it. Signed-off-by: David Herrmann --- src/genunifont.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/genunifont.c b/src/genunifont.c index f98640e..ca464ea 100644 --- a/src/genunifont.c +++ b/src/genunifont.c @@ -237,7 +237,6 @@ int main(int argc, char **argv) goto err_out; } - fprintf(stderr, "genunifont: parsing input %s\n", argv[2]); in = fopen(argv[2], "rb"); if (!in) { fprintf(stderr, "genunifont: cannot open %s: %m\n", -- 2.7.4 From 8050a28beb37d1e90d6cc5d542b6eac6a222a17a Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 16 Mar 2013 14:12:16 +0100 Subject: [PATCH 02/16] 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 From 7083e7dbc505ee8ee2ceb2280e46869466396688 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 16 Mar 2013 14:14:01 +0100 Subject: [PATCH 03/16] build: strip \r from shaders \r is rarely used and probably always escaped in strings so we can safely erase it together with \n to reduce its size. Signed-off-by: David Herrmann --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 5478d0c..f82e0a1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -155,12 +155,12 @@ src/%.bin.lo: src/%.bin # ^/*.*$ Start of multi-line comment # ^ *.*$ Multi-line comment body # ^[ \t]* Indentation whitespace -# \n Newlines +# [\r\n] Newlines # CLEANFILES += src/*.vert.bin src/*.frag.bin SHADER_SED = -e 's/^\/\*.*$$//' -e 's/^ \*.*$$//' -e 's/^[ \t]*//' -SHADER_TR = -d "\n" +SHADER_TR = -d "\r\n" src/%.vert.bin: $(top_srcdir)/src/%.vert $(AM_V_at)$(SED) $(SHADER_SED) "$<" | tr $(SHADER_TR) >"$@" -- 2.7.4 From 37eae950f019903db2556e2c617d34aa69a34e7a Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 16 Mar 2013 14:27:26 +0100 Subject: [PATCH 04/16] uterm: input: use shl_llog instead of shl_log We should use library-logging in uterm to avoid cluttering stderr for applications. Hence, use llog instead of log directly. Signed-off-by: David Herrmann --- src/kmscon_seat.c | 3 ++- src/uterm_input.c | 47 +++++++++++++++++++++++----------------- src/uterm_input.h | 12 ++++++++++- src/uterm_input_internal.h | 5 ++++- src/uterm_input_uxkb.c | 53 +++++++++++++++++++++++++++------------------- tests/test_input.c | 2 +- tests/test_vt.c | 3 ++- 7 files changed, 78 insertions(+), 47 deletions(-) diff --git a/src/kmscon_seat.c b/src/kmscon_seat.c index 2bde083..9f5f664 100644 --- a/src/kmscon_seat.c +++ b/src/kmscon_seat.c @@ -716,7 +716,8 @@ int kmscon_seat_new(struct kmscon_seat **out, seat->conf->xkb_options, keymap, seat->conf->xkb_repeat_delay, - seat->conf->xkb_repeat_rate); + seat->conf->xkb_repeat_rate, + log_llog, NULL); free(keymap); if (ret) diff --git a/src/uterm_input.c b/src/uterm_input.c index c248ee8..6fcbc4b 100644 --- a/src/uterm_input.c +++ b/src/uterm_input.c @@ -39,12 +39,12 @@ #include "eloop.h" #include "shl_dlist.h" #include "shl_hook.h" -#include "shl_log.h" +#include "shl_llog.h" #include "shl_misc.h" #include "uterm_input.h" #include "uterm_input_internal.h" -#define LOG_SUBSYSTEM "input" +#define LLOG_SUBSYSTEM "uterm_input" /* How many longs are needed to hold \n bits. */ #define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT) @@ -70,7 +70,7 @@ static void input_data_dev(struct ev_fd *fd, int mask, void *data) int i; if (mask & (EV_HUP | EV_ERR)) { - log_debug("EOF on %s", dev->node); + llog_debug(dev->input, "EOF on %s", dev->node); input_free_dev(dev); return; } @@ -81,14 +81,15 @@ static void input_data_dev(struct ev_fd *fd, int mask, void *data) if (len < 0) { if (errno == EWOULDBLOCK) break; - log_warn("reading from %s failed (%d): %m", - dev->node, errno); + llog_warn(dev->input, "reading from %s failed (%d): %m", + dev->node, errno); input_free_dev(dev); } else if (len == 0) { - log_debug("EOF on %s", dev->node); + llog_debug(dev->input, "EOF on %s", dev->node); input_free_dev(dev); } else if (len % sizeof(*ev)) { - log_warn("invalid input_event on %s", dev->node); + llog_warn(dev->input, "invalid input_event on %s", + dev->node); } else { n = len / sizeof(*ev); for (i = 0; i < n; i++) @@ -107,7 +108,8 @@ static int input_wake_up_dev(struct uterm_input_dev *dev) dev->rfd = open(dev->node, O_CLOEXEC | O_NONBLOCK | O_RDWR); if (dev->rfd < 0) { - log_warn("cannot open device %s (%d): %m", dev->node, errno); + llog_warn(dev->input, "cannot open device %s (%d): %m", + dev->node, errno); return -EFAULT; } @@ -182,7 +184,7 @@ static void input_new_dev(struct uterm_input *input, goto err_kbd; } - log_debug("new device %s", node); + llog_debug(input, "new device %s", node); shl_dlist_link(&input->devices, &dev->list); return; @@ -204,7 +206,7 @@ err_free: static void input_free_dev(struct uterm_input_dev *dev) { - log_debug("free device %s", dev->node); + llog_debug(dev->input, "free device %s", dev->node); input_sleep_dev(dev); shl_dlist_unlink(&dev->list); uxkb_dev_destroy(dev); @@ -225,7 +227,9 @@ int uterm_input_new(struct uterm_input **out, const char *options, const char *keymap, unsigned int repeat_delay, - unsigned int repeat_rate) + unsigned int repeat_rate, + uterm_input_log_t log, + void *log_data) { struct uterm_input *input; int ret; @@ -247,6 +251,8 @@ int uterm_input_new(struct uterm_input **out, return -ENOMEM; memset(input, 0, sizeof(*input)); input->ref = 1; + input->llog = log; + input->llog_data = log_data; input->eloop = eloop; input->repeat_delay = repeat_delay; input->repeat_rate = repeat_rate; @@ -260,7 +266,7 @@ int uterm_input_new(struct uterm_input **out, if (ret) goto err_hook; - log_debug("new object %p", input); + llog_debug(input, "new object %p", input); ev_eloop_ref(input->eloop); *out = input; return 0; @@ -289,7 +295,7 @@ void uterm_input_unref(struct uterm_input *input) if (!input || !input->ref || --input->ref) return; - log_debug("free object %p", input); + llog_debug(input, "free object %p", input); while (input->devices.next != &input->devices) { dev = shl_dlist_entry(input->devices.next, @@ -309,7 +315,8 @@ void uterm_input_unref(struct uterm_input *input) * We go over the possible capabilities and return a mask of enum * uterm_input_device_capability's. */ -static unsigned int probe_device_capabilities(const char *node) +static unsigned int probe_device_capabilities(struct uterm_input *input, + const char *node) { int i, fd, ret; unsigned int capabilities = 0; @@ -351,8 +358,8 @@ static unsigned int probe_device_capabilities(const char *node) return capabilities; err_ioctl: - log_warn("cannot probe capabilities of device %s (%d): %m", - node, errno); + llog_warn(input, "cannot probe capabilities of device %s (%d): %m", + node, errno); close(fd); return 0; } @@ -365,9 +372,9 @@ void uterm_input_add_dev(struct uterm_input *input, const char *node) if (!input || !node) return; - capabilities = probe_device_capabilities(node); + capabilities = probe_device_capabilities(input, node); if (!(capabilities & UTERM_DEVICE_HAS_KEYS)) { - log_debug("ignoring non-useful device %s", node); + llog_debug(input, "ignoring non-useful device %s", node); return; } @@ -429,7 +436,7 @@ void uterm_input_sleep(struct uterm_input *input) if (input->awake != 0) return; - log_debug("going to sleep"); + llog_debug(input, "going to sleep"); shl_dlist_for_each(iter, &input->devices) { dev = shl_dlist_entry(iter, @@ -453,7 +460,7 @@ void uterm_input_wake_up(struct uterm_input *input) if (input->awake != 1) return; - log_debug("wakeing up"); + llog_debug(input, "wakeing up"); shl_dlist_for_each_safe(iter, tmp, &input->devices) { dev = shl_dlist_entry(iter, diff --git a/src/uterm_input.h b/src/uterm_input.h index 43faccc..1d5d1f0 100644 --- a/src/uterm_input.h +++ b/src/uterm_input.h @@ -40,6 +40,15 @@ struct uterm_input; +typedef void (*uterm_input_log_t) (void *data, + const char *file, + int line, + const char *func, + const char *subs, + unsigned int sev, + const char *format, + va_list args); + /* keep in sync with shl_xkb_mods */ enum uterm_input_modifier { UTERM_SHIFT_MASK = (1 << 0), @@ -72,7 +81,8 @@ typedef void (*uterm_input_cb) (struct uterm_input *input, int uterm_input_new(struct uterm_input **out, struct ev_eloop *eloop, const char *model, const char *layout, const char *variant, const char *options, const char *keymap, - unsigned int repeat_delay, unsigned int repeat_rate); + unsigned int repeat_delay, unsigned int repeat_rate, + uterm_input_log_t log, void *log_data); void uterm_input_ref(struct uterm_input *input); void uterm_input_unref(struct uterm_input *input); diff --git a/src/uterm_input_internal.h b/src/uterm_input_internal.h index 6491d33..04e6cc9 100644 --- a/src/uterm_input_internal.h +++ b/src/uterm_input_internal.h @@ -1,7 +1,7 @@ /* * uterm - Linux User-Space Terminal * - * Copyright (c) 2011-2012 David Herrmann + * Copyright (c) 2011-2013 David Herrmann * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files @@ -35,6 +35,7 @@ #include #include "eloop.h" #include "shl_dlist.h" +#include "shl_llog.h" #include "shl_misc.h" #include "uterm_input.h" @@ -65,6 +66,8 @@ struct uterm_input_dev { struct uterm_input { unsigned long ref; + llog_submit_t llog; + void *llog_data; struct ev_eloop *eloop; int awake; unsigned int repeat_rate; diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c index 14d9937..af6bd05 100644 --- a/src/uterm_input_uxkb.c +++ b/src/uterm_input_uxkb.c @@ -33,12 +33,12 @@ #include #include #include "shl_hook.h" -#include "shl_log.h" +#include "shl_llog.h" #include "shl_misc.h" #include "uterm_input.h" #include "uterm_input_internal.h" -#define LOG_SUBSYSTEM "input_uxkb" +#define LLOG_SUBSYSTEM "uterm_input_uxkb" extern const char _binary_src_uterm_input_fallback_xkb_bin_start[]; extern const char _binary_src_uterm_input_fallback_xkb_bin_end[]; @@ -64,7 +64,7 @@ int uxkb_desc_init(struct uterm_input *input, input->ctx = xkb_context_new(0); if (!input->ctx) { - log_error("cannot create XKB context"); + llog_error(input, "cannot create XKB context"); return -ENOMEM; } @@ -73,17 +73,18 @@ int uxkb_desc_init(struct uterm_input *input, input->keymap = xkb_keymap_new_from_string(input->ctx, keymap, XKB_KEYMAP_FORMAT_TEXT_V1, 0); if (input->keymap) { - log_debug("new keyboard description from memory"); + llog_debug(input, + "new keyboard description from memory"); return 0; } - log_warn("cannot parse keymap, reverting to rmlvo"); + llog_warn(input, "cannot parse keymap, reverting to rmlvo"); } input->keymap = xkb_keymap_new_from_names(input->ctx, &rmlvo, 0); if (!input->keymap) { - log_warn("failed to create keymap (%s, %s, %s, %s), " - "reverting to default system keymap", + llog_warn(input, "failed to create keymap (%s, %s, %s, %s), " + "reverting to default system keymap", model, layout, variant, options); rmlvo.model = ""; @@ -94,22 +95,23 @@ 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 default keymap, " - "reverting to built-in fallback"); + llog_warn(input, "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"); + llog_error(input, + "cannot create fallback keymap"); ret = -EFAULT; goto err_ctx; } } - log_debug("new fallback keyboard description"); + llog_debug(input, "new fallback keyboard description"); } else { - log_debug("new keyboard description (%s, %s, %s, %s)", - model, layout, variant, options); + llog_debug(input, "new keyboard description (%s, %s, %s, %s)", + model, layout, variant, options); } return 0; @@ -144,7 +146,7 @@ int uxkb_dev_init(struct uterm_input_dev *dev) dev->state = xkb_state_new(dev->input->keymap); if (!dev->state) { - log_error("cannot create XKB state"); + llog_error(dev->input, "cannot create XKB state"); ret = -ENOMEM; goto err_timer; } @@ -197,7 +199,8 @@ static void uxkb_dev_update_keyboard_leds(struct uterm_input_dev *dev) ret = write(dev->rfd, events, sizeof(events)); if (ret != sizeof(events)) - log_warning("cannot update LED state (%d): %m", errno); + llog_warning(dev->input, "cannot update LED state (%d): %m", + errno); } static inline int uxkb_dev_resize_event(struct uterm_input_dev *dev, size_t s) @@ -208,7 +211,8 @@ static inline int uxkb_dev_resize_event(struct uterm_input_dev *dev, size_t s) tmp = realloc(dev->event.keysyms, sizeof(uint32_t) * s); if (!tmp) { - log_warning("cannot reallocate keysym buffer"); + llog_warning(dev->input, + "cannot reallocate keysym buffer"); return -ENOKEY; } dev->event.keysyms = tmp; @@ -216,7 +220,8 @@ static inline int uxkb_dev_resize_event(struct uterm_input_dev *dev, size_t s) tmp = realloc(dev->event.codepoints, sizeof(uint32_t) * s); if (!tmp) { - log_warning("cannot reallocate codepoints buffer"); + llog_warning(dev->input, + "cannot reallocate codepoints buffer"); return -ENOKEY; } dev->event.codepoints = tmp; @@ -224,7 +229,8 @@ static inline int uxkb_dev_resize_event(struct uterm_input_dev *dev, size_t s) tmp = realloc(dev->repeat_event.keysyms, sizeof(uint32_t) * s); if (!tmp) { - log_warning("cannot reallocate keysym buffer"); + llog_warning(dev->input, + "cannot reallocate keysym buffer"); return -ENOKEY; } dev->repeat_event.keysyms = tmp; @@ -232,7 +238,8 @@ static inline int uxkb_dev_resize_event(struct uterm_input_dev *dev, size_t s) tmp = realloc(dev->repeat_event.codepoints, sizeof(uint32_t) * s); if (!tmp) { - log_warning("cannot reallocate codepoints buffer"); + llog_warning(dev->input, + "cannot reallocate codepoints buffer"); return -ENOKEY; } dev->repeat_event.codepoints = tmp; @@ -392,7 +399,8 @@ void uxkb_dev_sleep(struct uterm_input_dev *dev) ioctl(dev->rfd, EVIOCGKEY(sizeof(dev->key_state_bits)), dev->key_state_bits); if (errno) - log_warn("failed to save keyboard state (%d): %m", errno); + llog_warn(dev->input, "failed to save keyboard state (%d): %m", + errno); } void uxkb_dev_wake_up(struct uterm_input_dev *dev) @@ -407,8 +415,9 @@ void uxkb_dev_wake_up(struct uterm_input_dev *dev) errno = 0; ioctl(dev->rfd, EVIOCGKEY(sizeof(cur_bits)), cur_bits); if (errno) { - log_warn("failed to get current keyboard state (%d): %m", - errno); + llog_warn(dev->input, + "failed to get current keyboard state (%d): %m", + errno); return; } diff --git a/tests/test_input.c b/tests/test_input.c index 7dc06c7..6f0f31c 100644 --- a/tests/test_input.c +++ b/tests/test_input.c @@ -131,7 +131,7 @@ static void monitor_event(struct uterm_monitor *mon, input_conf.xkb_variant, input_conf.xkb_options, keymap, - 0, 0); + 0, 0, log_llog, NULL); if (ret) return; ret = uterm_input_register_cb(input, input_arrived, NULL); diff --git a/tests/test_vt.c b/tests/test_vt.c index 26c5ed6..d9a7666 100644 --- a/tests/test_vt.c +++ b/tests/test_vt.c @@ -113,7 +113,8 @@ int main(int argc, char **argv) if (ret) goto err_exit; - ret = uterm_input_new(&input, eloop, "", "", "", "", "", 0, 0); + ret = uterm_input_new(&input, eloop, "", "", "", "", "", 0, 0, + log_llog, NULL); if (ret) goto err_vtm; -- 2.7.4 From 7e095d9db3674af91496838c0f3739dbf8ebc60a Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 16 Mar 2013 16:03:30 +0100 Subject: [PATCH 05/16] shl: log: don't use strerror() strerror() is not re-entrant safe so we should use %m instead. Signed-off-by: David Herrmann --- src/shl_log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shl_log.c b/src/shl_log.c index 5b726a4..5318710 100644 --- a/src/shl_log.c +++ b/src/shl_log.c @@ -320,8 +320,8 @@ int log_set_file(const char *file) if (file) { f = fopen(file, "a"); if (!f) { - log_err("cannot change log-file to %s (%d): %s", - file, errno, strerror(errno)); + log_err("cannot change log-file to %s (%d): %m", + file, errno); return -EFAULT; } } else { -- 2.7.4 From 4bcf5073022c2cefffb0bb51f95f1564e7e447be Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 16 Mar 2013 16:06:54 +0100 Subject: [PATCH 06/16] shl: log: check for trailing newlines If the format string contains a trailing newline, we now skip writing our own. We also skip the fn+file information as it would be written on the next line. Trailing newlines occur only when forwarding messages from other libraries. In this case we don't need the fn+file information, anyway. Signed-off-by: David Herrmann --- src/shl_log.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/shl_log.c b/src/shl_log.c index 5318710..9acae87 100644 --- a/src/shl_log.c +++ b/src/shl_log.c @@ -386,6 +386,8 @@ static void log__submit(const char *file, const char *prefix = NULL; FILE *out; long long sec, usec; + bool nl; + size_t len; if (log__omit(file, line, func, config, subs, sev)) return; @@ -414,19 +416,20 @@ static void log__submit(const char *file, fprintf(out, "[%.4lld.%.6lld] ", sec, usec); } + len = strlen(format); + nl = format[len - 1] == '\n'; + + if (!func) + func = ""; + if (!file) + file = ""; + if (line < 0) + line = 0; + vfprintf(out, format, args); - if (sev == LOG_DEBUG) { - if (!func) - func = ""; - if (!file) - file = ""; - if (line < 0) - line = 0; + if (!nl) fprintf(out, " (%s() in %s:%d)\n", func, file, line); - } else { - fprintf(out, "\n"); - } } static void log__format(const char *file, -- 2.7.4 From a11d71a987e4be099d87c21b31e7fa9f24eaa6ca Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 16 Mar 2013 16:08:32 +0100 Subject: [PATCH 07/16] uterm: input: forward xkbcommon log messages Instead of letting xkbcommon write to stderr, we now forward these messages via the llog handler. Signed-off-by: David Herrmann --- src/uterm_input_uxkb.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c index af6bd05..925c755 100644 --- a/src/uterm_input_uxkb.c +++ b/src/uterm_input_uxkb.c @@ -38,11 +38,48 @@ #include "uterm_input.h" #include "uterm_input_internal.h" -#define LLOG_SUBSYSTEM "uterm_input_uxkb" +#define LLOG_SUBSYSTEM "uterm_uxkb" extern const char _binary_src_uterm_input_fallback_xkb_bin_start[]; extern const char _binary_src_uterm_input_fallback_xkb_bin_end[]; +static void uxkb_log(struct xkb_context *context, enum xkb_log_level level, + const char *format, va_list args) +{ + struct uterm_input *input; + unsigned int sev; + + input = xkb_context_get_user_data(context); + if (!input->llog) + return; + + switch (level) { + case XKB_LOG_LEVEL_CRITICAL: + sev = LLOG_CRITICAL; + break; + case XKB_LOG_LEVEL_ERROR: + sev = LLOG_ERROR; + break; + case XKB_LOG_LEVEL_WARNING: + sev = LLOG_WARNING; + break; + case XKB_LOG_LEVEL_INFO: + sev = LLOG_INFO; + break; + case XKB_LOG_LEVEL_DEBUG: + /* fallthrough */ + default: + sev = LLOG_DEBUG; + break; + } + + input->llog(input->llog_data, + LLOG_DEFAULT, + sev, + format, + args); +} + int uxkb_desc_init(struct uterm_input *input, const char *model, const char *layout, @@ -68,6 +105,12 @@ int uxkb_desc_init(struct uterm_input *input, return -ENOMEM; } + /* Set logging function. You can use XKB_LOG_VERBOSITY and XKB_LOG_LEVEL + * to change the xkbcommon logger. That's why we don't touch the + * verbosity and level here. */ + xkb_context_set_user_data(input->ctx, input); + xkb_context_set_log_fn(input->ctx, uxkb_log); + /* If a complete keymap file was given, first try that. */ if (keymap && *keymap) { input->keymap = xkb_keymap_new_from_string(input->ctx, -- 2.7.4 From 9b944add91926d0cb8f21ee30f6393df8452e1c3 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 4 Nov 2013 08:05:28 +0100 Subject: [PATCH 08/16] uterm: drm: set VIDEO_HOTPLUG on wakeup Be more verbose during wake-up and set VIDEO_HOTPLUG so we force the hotplug-check. I don't know why it worked until now, but we definitely need to force it as we have no idea what display-status changed. Signed-off-by: David Herrmann --- src/uterm_drm_shared.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/uterm_drm_shared.c b/src/uterm_drm_shared.c index 75830f3..e3b7d8d 100644 --- a/src/uterm_drm_shared.c +++ b/src/uterm_drm_shared.c @@ -658,6 +658,8 @@ int uterm_drm_video_hotplug(struct uterm_video *video, if (!video_is_awake(video) || !video_need_hotplug(video)) return 0; + log_debug("testing DRM hotplug status"); + res = drmModeGetResources(vdrm->fd); if (!res) { log_err("cannot retrieve drm resources"); @@ -728,7 +730,7 @@ int uterm_drm_video_wake_up(struct uterm_video *video) return -EACCES; } - video->flags |= VIDEO_AWAKE; + video->flags |= VIDEO_AWAKE | VIDEO_HOTPLUG; ret = uterm_drm_video_hotplug(video, true); if (ret) { drmDropMaster(vdrm->fd); -- 2.7.4 From 48bf4bd58f72b0c6a274b286513bc7905d3c1e80 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 4 Nov 2013 08:07:43 +0100 Subject: [PATCH 09/16] uterm: drm: force immediate modeset during wakeup We need to call drmModeSetCrtc during wakeup to prepare for page-flips. An immediate modeset is needed, otherwise we cannot be sure the FB/Crtc configuration is still the same. Force an immediate DRM modeset on wakeup to reset the screen. Signed-off-by: David Herrmann --- src/uterm_drm_shared.c | 26 +++++++++++++++++--------- src/uterm_drm_shared_internal.h | 3 ++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/uterm_drm_shared.c b/src/uterm_drm_shared.c index e3b7d8d..8d1e1be 100644 --- a/src/uterm_drm_shared.c +++ b/src/uterm_drm_shared.c @@ -645,7 +645,7 @@ err_unref: } int uterm_drm_video_hotplug(struct uterm_video *video, - bool read_dpms) + bool read_dpms, bool modeset) { struct uterm_drm_video *vdrm = video->data; drmModeRes *res; @@ -689,15 +689,23 @@ int uterm_drm_video_hotplug(struct uterm_video *video, continue; disp->flags |= DISPLAY_AVAILABLE; - if (!read_dpms || !display_is_online(disp)) + if (!display_is_online(disp)) break; - dpms = uterm_drm_get_dpms(vdrm->fd, conn); - if (dpms != disp->dpms) { - log_debug("DPMS state for display %p changed", - disp); - uterm_drm_display_set_dpms(disp, disp->dpms); + if (read_dpms) { + dpms = uterm_drm_get_dpms(vdrm->fd, conn); + if (dpms != disp->dpms) { + log_debug("DPMS state for display %p changed", + disp); + uterm_drm_display_set_dpms(disp, disp->dpms); + } } + + if (modeset) { + log_debug("re-activate display %p", disp); + uterm_display_swap(disp, true); + } + break; } @@ -731,7 +739,7 @@ int uterm_drm_video_wake_up(struct uterm_video *video) } video->flags |= VIDEO_AWAKE | VIDEO_HOTPLUG; - ret = uterm_drm_video_hotplug(video, true); + ret = uterm_drm_video_hotplug(video, true, true); if (ret) { drmDropMaster(vdrm->fd); return ret; @@ -752,7 +760,7 @@ void uterm_drm_video_sleep(struct uterm_video *video) int uterm_drm_video_poll(struct uterm_video *video) { video->flags |= VIDEO_HOTPLUG; - return uterm_drm_video_hotplug(video, false); + return uterm_drm_video_hotplug(video, false, false); } /* Waits for events on DRM fd for \mtimeout milliseconds and returns 0 if the diff --git a/src/uterm_drm_shared_internal.h b/src/uterm_drm_shared_internal.h index c2191e6..56a56ff 100644 --- a/src/uterm_drm_shared_internal.h +++ b/src/uterm_drm_shared_internal.h @@ -108,7 +108,8 @@ int uterm_drm_video_init(struct uterm_video *video, const char *node, void uterm_drm_video_destroy(struct uterm_video *video); int uterm_drm_video_find_crtc(struct uterm_video *video, drmModeRes *res, drmModeEncoder *enc); -int uterm_drm_video_hotplug(struct uterm_video *video, bool read_dpms); +int uterm_drm_video_hotplug(struct uterm_video *video, bool read_dpms, + bool modeset); int uterm_drm_video_wake_up(struct uterm_video *video); void uterm_drm_video_sleep(struct uterm_video *video); int uterm_drm_video_poll(struct uterm_video *video); -- 2.7.4 From 3b6fb0f75f50621eff2d6c1dfb5d9a0ce0f9216d Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 4 Nov 2013 19:37:05 +0100 Subject: [PATCH 10/16] uterm: drm: activate context before swapping Lets be safe here and activate the context before performing the buffer-swap. Drivers might be inconsistent and require this in case the background process changed the DRM state. Signed-off-by: David Herrmann --- src/uterm_drm_shared.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uterm_drm_shared.c b/src/uterm_drm_shared.c index 8d1e1be..ec486ab 100644 --- a/src/uterm_drm_shared.c +++ b/src/uterm_drm_shared.c @@ -703,6 +703,7 @@ int uterm_drm_video_hotplug(struct uterm_video *video, if (modeset) { log_debug("re-activate display %p", disp); + uterm_display_use(disp, NULL); uterm_display_swap(disp, true); } -- 2.7.4 From e507a14113eab3c2c4c34a977b237f505080bd2a Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 22 Apr 2014 08:36:50 +0200 Subject: [PATCH 11/16] build: don't build shl_gl if GLES is disabled We required GL headers for shl_gl.h. Even though the linker strips all the GL dependencies if it's disabled during compilation, we still require it as build-time dependency. Avoid that by not including shl_gl in any non-GL builds. Signed-off-by: David Herrmann --- Makefile.am | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index f82e0a1..be2dc30 100644 --- a/Makefile.am +++ b/Makefile.am @@ -214,9 +214,7 @@ libshl_la_SOURCES = \ src/shl_hook.h \ src/shl_misc.h \ src/shl_register.h \ - src/shl_flagset.h \ - src/shl_gl.h \ - src/shl_gl_math.c + src/shl_flagset.h libshl_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ $(XKBCOMMON_CFLAGS) \ @@ -229,7 +227,7 @@ libshl_la_LIBADD = \ $(XKBCOMMON_LIBS) if BUILD_HAVE_GLES2 -libshl_la_SOURCES += src/shl_gl_shader.c +libshl_la_SOURCES += src/shl_gl.h src/shl_gl_shader.c src/shl_gl_math.c libshl_la_CPPFLAGS += $(GLES2_CFLAGS) libshl_la_LIBADD += $(GLES2_LIBS) endif -- 2.7.4 From 012be880fcb34d5c206bfbc9b00cd36e013aa2eb Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Thu, 15 May 2014 18:15:29 +0800 Subject: [PATCH 12/16] build: add libtsm to bbulk and gltex text_bbulk.c and text_gltex.c contain text.h which depend on libtsm. Without adding tsm flags to compile option, bbulk and gltex can't be compiled. Signed-off-by: Xiong Zhang Signed-off-by: David Herrmann --- Makefile.am | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index be2dc30..8f97c06 100644 --- a/Makefile.am +++ b/Makefile.am @@ -415,7 +415,12 @@ mod_bbulk_la_SOURCES = \ src/kmscon_module_interface.h \ src/text_bbulk.c \ src/kmscon_mod_bbulk.c -mod_bbulk_la_LIBADD = libshl.la +mod_bbulk_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(TSM_CFLAGS) +mod_bbulk_la_LIBADD = \ + $(TSM_LIBS) \ + libshl.la mod_bbulk_la_LDFLAGS = \ $(AM_LDFLAGS) \ -module \ @@ -431,9 +436,11 @@ mod_gltex_la_SOURCES = \ src/kmscon_mod_gltex.c mod_gltex_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ + $(TSM_CFLAGS) \ $(GLES2_CFLAGS) mod_gltex_la_LIBADD = \ $(GLES2_LIBS) \ + $(TSM_LIBS) \ libshl.la \ src/text_gltex_atlas.vert.bin.lo \ src/text_gltex_atlas.frag.bin.lo -- 2.7.4 From 41e76d11dff6dd9bc08bf829751f9634f32cdd38 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 24 May 2014 21:19:33 +0200 Subject: [PATCH 13/16] shl: handle pathconf() errors It can return -1 (feature not supported, denied by a security module, etc.), resulting in wrong allocation later on. Signed-off-by: Lubomir Rintel (remove superfluous errno-checks) Signed-off-by: David Herrmann --- src/kmscon_module.c | 2 +- src/shl_misc.h | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/kmscon_module.c b/src/kmscon_module.c index 2bf0576..f480914 100644 --- a/src/kmscon_module.c +++ b/src/kmscon_module.c @@ -181,7 +181,7 @@ void kmscon_load_modules(void) { int ret; DIR *ent; - struct dirent *buf, *de; + struct dirent *buf = NULL, *de; char *file; struct kmscon_module *mod; diff --git a/src/shl_misc.h b/src/shl_misc.h index d90fd22..f4a6d90 100644 --- a/src/shl_misc.h +++ b/src/shl_misc.h @@ -52,9 +52,13 @@ static inline int shl_dirent(const char *path, struct dirent **ent) { size_t len; struct dirent *tmp; + long name_max; - len = offsetof(struct dirent, d_name) + - pathconf(path, _PC_NAME_MAX) + 1; + name_max = pathconf(path, _PC_NAME_MAX); + if (name_max < 0) + return -errno; + + len = offsetof(struct dirent, d_name) + name_max + 1; tmp = malloc(len); if (!tmp) return -ENOMEM; -- 2.7.4 From 074792020c9cec199959d4f5c39f3ef21318c031 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 25 May 2014 11:54:55 +0200 Subject: [PATCH 14/16] Partly revert "shl: handle pathconf() errors" This partly reverts commit 41e76d11dff6dd9bc08bf829751f9634f32cdd38. I removed the "superfluous" errno-handling, which in fact is needed. Turns out pathconf() might leave errno unchanged. Reported-by: Lubomir Rintel Signed-off-by: David Herrmann --- src/kmscon_module.c | 2 +- src/shl_misc.h | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/kmscon_module.c b/src/kmscon_module.c index f480914..2bf0576 100644 --- a/src/kmscon_module.c +++ b/src/kmscon_module.c @@ -181,7 +181,7 @@ void kmscon_load_modules(void) { int ret; DIR *ent; - struct dirent *buf = NULL, *de; + struct dirent *buf, *de; char *file; struct kmscon_module *mod; diff --git a/src/shl_misc.h b/src/shl_misc.h index f4a6d90..fc37d9d 100644 --- a/src/shl_misc.h +++ b/src/shl_misc.h @@ -54,9 +54,15 @@ static inline int shl_dirent(const char *path, struct dirent **ent) struct dirent *tmp; long name_max; + /* errno may be left unchanged, see pathconf(3p) */ + errno = 0; name_max = pathconf(path, _PC_NAME_MAX); - if (name_max < 0) - return -errno; + if (name_max < 0) { + if (errno) + return -errno; + else + return -EINVAL; + } len = offsetof(struct dirent, d_name) + name_max + 1; tmp = malloc(len); -- 2.7.4 From bb9a72455822ebc8f4773a6bcb047b85aa2ce2d5 Mon Sep 17 00:00:00 2001 From: Quanxian Wang Date: Fri, 6 Jun 2014 10:45:58 +0800 Subject: [PATCH 15/16] Add packaging Change-Id: I86b94d4d53132d765ed8cde56e52bc9aae71a213 Signed-off-by: Quanxian Wang --- packaging/kmscon.manifest | 5 ++++ packaging/kmscon.spec | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 packaging/kmscon.manifest create mode 100644 packaging/kmscon.spec diff --git a/packaging/kmscon.manifest b/packaging/kmscon.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/packaging/kmscon.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/kmscon.spec b/packaging/kmscon.spec new file mode 100644 index 0000000..b3b1a49 --- /dev/null +++ b/packaging/kmscon.spec @@ -0,0 +1,66 @@ +Name: kmscon +Version: 8.0 +Release: 0 +Summary: KMS/DRM based System Console +License: MIT +Group: Graphics & UI Framework/Wayland Window System +Url: http://www.freedesktop.org/wiki/Software/kmscon + +#Git-Clone: git://people.freedesktop.org/~dvdhrm/kmscon +#Git-Web: http://cgit.freedesktop.org/~dvdhrm/kmscon +Source0: %name-%version.tar.xz +Source1001: kmscon.manifest +BuildRequires: autoconf >= 2.64, automake >= 1.11 +BuildRequires: expat-devel +BuildRequires: libjpeg-devel +BuildRequires: libtool >= 2.2 +BuildRequires: libvpx-devel +BuildRequires: pam-devel +BuildRequires: pkgconfig +BuildRequires: xz +BuildRequires: pkgconfig(libtsm) +BuildRequires: pkgconfig(libudev) >= 136 +BuildRequires: pkgconfig(libdrm) >= 2.4.30 +BuildRequires: pkgconfig(egl) >= 7.10 +BuildRequires: pkgconfig(glesv2) +BuildRequires: pkgconfig(gbm) +BuildRequires: pkgconfig(xkbcommon) >= 0.3.0 +BuildRequires: kernel-headers +BuildRequires: pkgconfig(pangocairo) + +%description +kmscon is a system console for linux. It doesn't depend on any +graphic-server on your system(like X.org), but instead provides a raw +console layer that can be used independently. It can replace the linux +kernel console entirely but was designed to work well side-by-side. + +%prep +%setup -q +cp %{SOURCE1001} . + +%build +%autogen +make %{?_smp_mflags} + +%install +%make_install + +%define _unitdir_system /usr/lib/systemd/system +install -d %{buildroot}%{_unitdir_system} +install -m 644 docs/kmscon.service %{buildroot}%{_unitdir_system} +install -m 644 docs/kmsconvt@.service %{buildroot}%{_unitdir_system} + +%define _unit_config /etc/systemd/system +install -d %{buildroot}%{_unit_config} +ln -s %{_unitdir_system}/kmsconvt@.service %{buildroot}%{_unit_config}/autovt@.service + +%files +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license COPYING +%_bindir/%{name} +%_libdir/%{name}/ +%{_unitdir_system}/ +%{_unit_config}/autovt@.service + +%changelog -- 2.7.4 From 7e2ece50168cc273abbf68a1a0f3e7740c5e25e1 Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Tue, 27 May 2014 09:52:51 +0800 Subject: [PATCH 16/16] Modify it to adjust Tizen IVI enviroment Change-Id: I95db0a486a294a18244a24dd158688b6089a4254 Signed-off-by: Xiong Zhang --- docs/kmsconvt@.service | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/kmsconvt@.service b/docs/kmsconvt@.service index 7b64823..a759f6d 100644 --- a/docs/kmsconvt@.service +++ b/docs/kmsconvt@.service @@ -29,7 +29,6 @@ Description=KMS System Console on %I Documentation=man:kmscon(1) After=systemd-user-sessions.service -After=plymouth-quit-wait.service Before=getty.target Conflicts=getty@%i.service OnFailure=getty@%i.service @@ -37,7 +36,7 @@ IgnoreOnIsolate=yes ConditionPathExists=/dev/tty0 [Service] -ExecStart=/usr/bin/kmscon "--vt=%I" --seats=seat0 --no-switchvt +ExecStart=/usr/bin/kmscon "--vt=%I" --seats=seat0 --no-switchvt --hwaccel UtmpIdentifier=%I TTYPath=/dev/%I TTYReset=yes -- 2.7.4