diff --git a/genmap4systemd.sh b/genmap4systemd.sh new file mode 100644 index 0000000..7b3d11b --- /dev/null +++ b/genmap4systemd.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Generate entries for systemd's /usr/share/systemd/kbd-model-map + +if [ $# -eq 0 ]; then + pushd /usr/share/kbd/keymaps/xkb > /dev/null || exit 1 +else + pushd > /dev/null $1 || exit 1 +fi + +echo "# generated from xkb generated keymaps (basic layouts *without* variant)" +for i in $(ls *.map.gz|grep -v "-"); do + consolelayout=$(echo $i|sed 's/.map.gz//g') + layout=$consolelayout + variant="-" + printf '%s' "$consolelayout" + printf "\t\t\t" + printf '%s' "$layout" + printf '\t' + printf 'microsoftpro\t\t' + printf '%s' "$variant" + printf '\t\t' + printf 'terminate:ctrl_alt_bksp\n' +done | sort -u + +echo "# generated from xkb generated keymaps (layouts *with* variant)" +for i in $(ls *-*.map.gz); do + consolelayout=$(echo $i|sed 's/.map.gz//g') + conlen=$(echo "$consolelayout" |wc -m) + conlen=$((conlen - 1)) + + layout=$(echo $i|cut -d "-" -f 1) + + variant=$(echo $i|cut -d "-" -f 2,3,4,5,6,7,8,9,10|cut -d "." -f1) + varlen=$(echo $variant|wc -m) + varlen=$((varlen -1)) + + printf '%s' "$consolelayout" + if [ $conlen -lt 8 ]; then + printf "\t\t\t" + elif [ $conlen -lt 16 ]; then + printf "\t\t" + elif [ $conlen -lt 24 ]; then + printf "\t" + else + printf ' ' + fi + printf '%s' "$layout" + printf '\t' + if [ "$layout" == "br" ]; then + printf 'abnt2\t\t' + elif [ "$layout" == "jp" ]; then + printf 'jp106\t\t' + else + printf 'microsoftpro\t\t' + fi + printf '%s' "$variant" + if [ $varlen -lt 8 ]; then + printf "\t\t" + elif [ $varlen -lt 16 ]; then + printf "\t" + else + printf ' ' + fi + printf 'terminate:ctrl_alt_bksp\n' + +done | sort -u + +popd > /dev/null + diff --git a/kbd-1.15.5-loadkeys-search-path.patch b/kbd-1.15.5-loadkeys-search-path.patch new file mode 100644 index 0000000..8ab4dfd --- /dev/null +++ b/kbd-1.15.5-loadkeys-search-path.patch @@ -0,0 +1,24 @@ +diff -up kbd-2.0.1/src/loadkeys.c.orig kbd-2.0.1/src/loadkeys.c +--- kbd-2.0.1/src/loadkeys.c.orig 2013-11-27 12:56:57.846069007 +0100 ++++ kbd-2.0.1/src/loadkeys.c 2013-11-27 12:58:03.877302345 +0100 +@@ -26,7 +26,7 @@ + #include "keymap.h" + + static const char *progname = NULL; +-static const char *const dirpath1[] = { "", DATADIR "/" KEYMAPDIR "/**", KERNDIR "/", 0 }; ++static const char *const dirpath1[] = { "", DATADIR "/" KEYMAPDIR "/**", DATADIR "/" XKBKEYMAPDIR "/", DATADIR "/" LEGACYKEYMAPDIR "/**", KERNDIR "/", 0 }; + static const char *const suffixes[] = { "", ".kmap", ".map", 0 }; + + static void __attribute__ ((noreturn)) +diff -up kbd-2.0.1/src/paths.h.orig kbd-2.0.1/src/paths.h +--- kbd-2.0.1/src/paths.h.orig 2013-11-27 12:58:10.662326108 +0100 ++++ kbd-2.0.1/src/paths.h 2013-11-27 12:58:32.566403015 +0100 +@@ -5,6 +5,8 @@ + * The following five subdirectories are defined: + */ + #define KEYMAPDIR "keymaps" ++#define XKBKEYMAPDIR "keymaps/xkb" ++#define LEGACYKEYMAPDIR "keymaps/legacy" + #define UNIMAPDIR "unimaps" + #define TRANSDIR "consoletrans" + #define VIDEOMODEDIR "videomodes" diff --git a/kbd.changes b/kbd.changes index db2d1a8..5b5b828 100644 --- a/kbd.changes +++ b/kbd.changes @@ -1,3 +1,31 @@ +------------------------------------------------------------------- +Mon Aug 10 11:53:48 UTC 2015 - sndirsch@suse.com + +- genmap4systemd.sh: use 'abnt2' model for 'br' layouts, 'jp106' + model for 'jp' layouts and 'microsoftpro' for anything else + (instead of 'pc105' before) (FATE#318426) + +------------------------------------------------------------------- +Tue Jul 21 10:05:35 UTC 2015 - sndirsch@suse.com + +- added genmap4systemd.sh tool, which generates entries for + systemd's /usr/share/systemd/kbd-model-map table from + xkeyboard-config converted keymaps; entries are written to + /usr/share/systemd/kbd-model-map.xkb-generated, so these can + easily be added to /usr/share/systemd/kbd-model-map by systemd + package (FATE#318426) + +------------------------------------------------------------------- +Fri Jul 17 12:54:27 UTC 2015 - sndirsch@suse.com + +- Include xkb layouts from xkeyboard-config converted to console + keymaps, (FATE#318426) + * Rename Finnish xkb converted layout + * Add xkb and legacy keymaps subdirs to loadkyes search path, + remove symlinks, Don't convert layouts that can't input ASCII, + * Original keymaps moved to legacy dir, created symlinks to xkb + keymaps + ------------------------------------------------------------------- Thu Apr 2 18:36:23 UTC 2015 - crrodriguez@opensuse.org diff --git a/kbd.spec b/kbd.spec index 6315137..ccf0245 100644 --- a/kbd.spec +++ b/kbd.spec @@ -42,6 +42,8 @@ Source13: guess_encoding.pl Source14: kbd.pl Source42: convert-kbd-mac.sed Source43: repack_kbd.sh +Source44: xml2lst.pl +Source45: genmap4systemd.sh Patch0: kbd-1.15.2-prtscr_no_sigquit.patch Patch2: kbd-1.15.2-unicode_scripts.patch Patch3: kbd-1.15.2-docu-X11R6-xorg.patch @@ -53,6 +55,9 @@ Patch9: kbd-2.0.2-comment-typo-qwerty.patch Patch10: kbd-2.0.2-doshell-reference.patch Patch11: kbd-2.0.2-euro-unicode.patch Patch12: kbd-2.0.2-fix-bashisms.patch +# Patch13: adds xkb and legacy keymaps subdirs to loadkyes search path +# (openSUSE FATE#318355, sle FATE#318426) +Patch13: kbd-1.15.5-loadkeys-search-path.patch BuildRequires: automake BuildRequires: bison @@ -63,7 +68,13 @@ BuildRequires: pam-devel BuildRequires: pkg-config BuildRequires: suse-module-tools BuildRequires: xz + +BuildRequires: console-setup +BuildRequires: xkeyboard-config + Requires(pre): %fillup_prereq +# Temporarily require -legacy +Requires: %{name}-legacy = %{version}-%{release} BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -82,10 +93,23 @@ Authors: Andries Brouwer Alexey Gladkov +%package legacy +Summary: Legacy data for kbd package +Group: System/Console +BuildArch: noarch + +%description legacy +The %{name}-legacy package contains original keymaps for kbd package. +Please note that %{name}-legacy is not helpful without kbd. + + + %define kbd /usr/share/kbd %prep %setup -q -a 1 -a 2 -n kbd-%{version} +cp -fp %{SOURCE44} . +cp -fp %{SOURCE45} . %patch0 -p1 %patch2 %patch3 @@ -97,6 +121,7 @@ Authors: %patch10 %patch11 %patch12 -p1 +%patch13 -p1 %build for i in `find data/keymaps/mac -type f` ; do @@ -286,6 +311,40 @@ ln -s %{_bindir}/resizecons %{buildroot}/bin ln -s %{_bindir}/resizecons %{buildroot}/bin %endif #EndUsrMerge + +# Move original keymaps to legacy directory +mkdir -p $RPM_BUILD_ROOT/%{kbd}/keymaps/legacy +mv $RPM_BUILD_ROOT/%{kbd}/keymaps/{amiga,atari,i386,include,mac,ppc,sun} $RPM_BUILD_ROOT/%{kbd}/keymaps/legacy + +# Convert X keyboard layouts to console keymaps +mkdir -p $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb +perl xml2lst.pl < /usr/share/X11/xkb/rules/base.xml > layouts-variants.lst +while read line; do + XKBLAYOUT=`echo "$line" | cut -d " " -f 1` + echo "$XKBLAYOUT" >> layouts-list.lst + XKBVARIANT=`echo "$line" | cut -d " " -f 2` + ckbcomp "$XKBLAYOUT" "$XKBVARIANT" | gzip > $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/"$XKBLAYOUT"-"$XKBVARIANT".map.gz +done < layouts-variants.lst + +# Convert X keyboard layouts (plain, no variant) +cat layouts-list.lst | sort -u >> layouts-list-uniq.lst +while read line; do + ckbcomp "$line" | gzip > $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/"$line".map.gz +done < layouts-list-uniq.lst + +# wipe converted layouts which cannot input ASCII (rh#1031848) +zgrep -L "U+0041" $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/* | xargs rm -f + +# Rename the converted default fi (kotoistus) layout (rh#1117891) +gunzip $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi.map.gz +mv $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi.map $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi-kotoistus.map +gzip $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb/fi-kotoistus.map + +# Generate entries for systemd's /usr/share/systemd/kbd-model-map +mkdir -p $RPM_BUILD_ROOT/usr/share/systemd +sh ./genmap4systemd.sh $RPM_BUILD_ROOT/%{kbd}/keymaps/xkb \ + > $RPM_BUILD_ROOT/usr/share/systemd/kbd-model-map.xkb-generated + %find_lang %{name} %post @@ -307,6 +366,7 @@ ln -s %{_bindir}/resizecons %{buildroot}/bin %{_localstatedir}/adm/fillup-templates/sysconfig.console %{_localstatedir}/adm/fillup-templates/sysconfig.keyboard %{kbd} +%exclude %{kbd}/keymaps/legacy #UsrMerge /sbin/fbtest /bin/chvt @@ -423,5 +483,10 @@ ln -s %{_bindir}/resizecons %{buildroot}/bin %doc %{_mandir}/man8/setvesablank.8.gz %doc %{_mandir}/man8/setvtrgb.8.gz %doc %{_mandir}/man8/vcstime.8.gz +%dir /usr/share/systemd +/usr/share/systemd/kbd-model-map.xkb-generated + +%files legacy +%{kbd}/keymaps/legacy %changelog diff --git a/xml2lst.pl b/xml2lst.pl new file mode 100644 index 0000000..78191f3 --- /dev/null +++ b/xml2lst.pl @@ -0,0 +1,231 @@ +#!/usr/bin/perl + +# converts the .xml file to the old format .lst file +# +# Usage: +# +# perl xml2lst.pl < filename.xml > filename.lst +# +# author Ivan Pascal +# modified by Vitezslav Crhonek + +$doc = new_document( 0, ''); +parse('', $doc); + +($reg) = node_by_name($doc, '/xkbConfigRegistry'); +@models = node_by_name($reg, 'modelList/model/configItem'); +@layouts = node_by_name($reg, 'layoutList/layout/configItem'); +@options = node_by_name($reg, 'optionList/group/configItem'); + +for $i (@layouts) { + ($name) = node_by_name($i, 'name'); + @variants = node_by_name($i, '../variantList/variant/configItem'); + for $v (@variants) { + ($variant) = node_by_name($v, 'name'); + printf("%s %s\n", text_child($name), text_child($variant)); + } +} + +sub with_attribute { + local ($nodelist, $attrexpr) = @_; + local ($attr, $value) = split (/=/, $attrexpr); + local ($node, $attrvalue); + if (defined $value && $value ne '') { + $value =~ s/"//g; + foreach $node (@{$nodelist}) { + $attrvalue = node_attribute($node, $attr); + if (defined $attrvalue && $attrvalue eq $value) { + return $node; + } + } + } else { + foreach $node (@{$nodelist}) { + if (! defined node_attribute($node, $attr)) { + return $node; + } + } + } + undef; +} + +# Subroutines + +sub parse { + local $intag = 0; + my (@node_stack, $parent); + $parent = @_[1]; + local ($tag, $text); + + while (<>) { + chomp; + @str = split /([<>])/; + shift @str if ($str[0] eq '' || $str[0] =~ /^[ \t]*$/); + + while (scalar @str) { + $token = shift @str; + if ($token eq '<') { + $intag = 1; + if (defined $text) { + add_text_node($parent, $text); + undef $text; + } + } elsif ($token eq '>') { + $intag = 0; + if ($tag =~ /^\/(.*)/) { # close tag + $parent = pop @node_stack; + } elsif ($tag =~ /^([^\/]*)\/$/) { + empty_tag($parent, $1); + } else { + if (defined ($node = open_tag($parent, $tag))) { + push @node_stack, $parent; + $parent = $node; + } + } + undef $tag; + } else { + if ($intag == 1) { + if (defined $tag) { + $tag .= ' '. $token; + } else { + $tag = $token; + } + } else { + if (defined $text) { + $text .= "\n" . $token; + } else { + $text = $token; + } + } + } + } + } +} + +sub new_document { + $doc = new_node( 0, '', 'DOCUMENT'); + $doc->{CHILDREN} = []; + return $doc; +} + +sub new_node { + local ($parent_node, $tag, $type) = @_; + + my %node; + $node{PARENT} = $parent_node; + $node{TYPE} = $type; + + if ($type eq 'COMMENT' || $type eq 'TEXT') { + $node{TEXT} = $tag; + $node{NAME} = $type; + return \%node; + } + + local ($tname, $attr) = split(' ', $tag, 2); + $node{NAME} = $tname; + + if (defined $attr && $attr ne '') { + my %attr_table; + local @attr_list = split ( /"/, $attr); + local ($name, $value); + while (scalar @attr_list) { + $name = shift @attr_list; + $name =~ s/[ =]//g; + next if ($name eq ''); + $value = shift @attr_list; + $attr_table{$name} =$value; + } + $node{ATTRIBUTES} = \%attr_table; + } + return \%node; +} + +sub add_node { + local ($parent_node, $node) = @_; + push @{$parent_node->{CHILDREN}}, $node; + + local $tname = $node->{NAME}; + if (defined $parent_node->{$tname}) { + push @{$parent_node->{$tname}}, $node + } else { + $parent_node->{$tname} = [ $node ]; + } +} + +sub empty_tag { + local ($parent_node, $tag) = @_; + local $node = new_node($parent_node, $tag, 'EMPTY'); + add_node($parent_node, $node); +} + +sub open_tag { + local ($parent_node, $tag) = @_; + local $node; + + if ($tag =~ /^\?.*/ || $tag =~ /^\!.*/) { + $node = new_node($parent_node, $tag, 'COMMENT'); + add_node($parent_node, $node); + undef; return; + } else { + $node = new_node($parent_node, $tag, 'NODE'); + $node->{CHILDREN} = []; + add_node($parent_node, $node); + return $node; + } +} + +sub add_text_node { + local ($parent_node, $text) = @_; + local $node = new_node($parent_node, $text, 'TEXT'); + add_node($parent_node, $node); +} + +sub node_by_name { + local ($node, $name) = @_; + local ($tagname, $path) = split(/\//, $name, 2); + + my @nodelist; + + if ($tagname eq '') { + while ($node->{PARENT} != 0) { + $node = $node->{PARENT}; + } + sublist_by_name($node, $path, \@nodelist); + } else { + sublist_by_name($node, $name, \@nodelist); + } + return @nodelist; +} + +sub sublist_by_name { + local ($node, $name, $res) = @_; + local ($tagname, $path) = split(/\//, $name, 2); + + if (! defined $path) { + push @{$res}, (@{$node->{$tagname}}); + return; + } + + if ($tagname eq '..' && $node->{PARENT} != 0) { + $node = $node->{PARENT}; + sublist_by_name($node, $path, $res); + } else { + local $n; + for $n (@{$node->{$tagname}}) { + sublist_by_name($n, $path, $res); + } + } +} + +sub node_attribute { + local $node = @_[0]; + if (defined $node->{ATTRIBUTES}) { + return $node->{ATTRIBUTES}{@_[1]}; + } + undef; +} + +sub text_child { + local ($node) = @_; + local ($child) = node_by_name($node, 'TEXT'); + return $child->{TEXT}; +}