#!/usr/bin/perl use strict; use warnings; sub process_variant { my ($input, $output, $layout, $variant, $cmd) = @_; my $line; my $level; my $match; open (IN, $input) || return 0; open (OUT, ">$output") || return 0; $level = 0; $match = 0; while ($line = <IN>) { if (($line =~ m/<layoutList>/) && ($level eq 0)) { $level++ } if (($line =~ m/<layout>/) && ($level eq 1)) { $level++; } if (($line =~ m/<name>$layout<\/name>/) && ($level eq 2)) { $match = 1 } if (($line =~ m/<variantList>/) && ($level eq 2)) { $level++ } if ($level eq 3) { # Remove command if (($cmd eq "remove") && ($line =~ m/<variant>/)) { # read completely next variant (concat on same line) while ($line !~ m/<\/variant>/) { my $line_cat; unless ($line_cat = <IN>) { last } else { $line .= $line_cat } } # correct entry, drop entire line if ($line =~ m/<name>$variant<\/name>/) { $line = '' } } # Add command if (($cmd eq "add") && $match) { # some stuff can be written on the same line after tag, so # remove only tag in $line and still print $line after insertion $line =~ s/<variantList>//; $line =~ s/\n//; print OUT "<variantList>\n"; print OUT "<variant>\n$variant</variant>\n"; $level++; } } # Print current line print OUT $line; if (($line =~ m/<\/variantList>/) && ($level eq 3)) { $level-- } if (($line =~ m/<\/layout>/) && ($level eq 2)) { $level--; $match = 0; } } close(OUT); close(IN); return 1; } sub process_xml { my ($file, $variant, $variant_xml, $cmd) = @_; my $temp = "$file.temp"; if ( ! -f "$file") { return 0 } &process_variant($file, $temp, "us", $variant, "remove") || die("Error configuring '$file'!"); if ($cmd eq "install") { &process_variant($temp, $file, "us", $variant_xml, "add") || die("Error configuring '$file'!"); unlink($temp); } elsif ($cmd eq "uninstall") { unlink($file) && rename($temp, $file); } return 1; } my $XKB = "/usr/share/X11/xkb"; my $VARIANT = "altgr-weur"; my $VARIANT_XML = <<'END_XML'; <configItem> <name>altgr-weur</name> <description>English (Western European AltGr dead keys)</description> <languageList> <iso639Id>dan</iso639Id> <iso639Id>nld</iso639Id> <iso639Id>eng</iso639Id> <iso639Id>fin</iso639Id> <iso639Id>fra</iso639Id> <iso639Id>deu</iso639Id> <iso639Id>ita</iso639Id> <iso639Id>nor</iso639Id> <iso639Id>por</iso639Id> <iso639Id>spa</iso639Id> <iso639Id>swe</iso639Id> </languageList> </configItem> END_XML my ($cmd) = @ARGV; $cmd //= "help"; # Default value if undefined # Deal with symbols file if ($cmd eq "install") { # Check that our file exists if ( !-f "$XKB/symbols/$VARIANT") { die("Error: file '$XKB/symbols/$VARIANT' not found!\n"); } # Remove existing backup file if any if (-f "$XKB/symbols/us.$VARIANT.bak") { unlink("$XKB/symbols/us.$VARIANT.bak"); } # Make a backup of "us" file `cp "$XKB/symbols/us" "$XKB/symbols/us.$VARIANT.bak"`; # Concat backup "us" file with our file into new "us" file `cat "$XKB/symbols/us.$VARIANT.bak" "$XKB/symbols/$VARIANT" > "$XKB/symbols/us"`; } elsif ($cmd eq "uninstall") { # Restore existing backup file if any if (-f "$XKB/symbols/us.$VARIANT.bak") { rename("$XKB/symbols/us.$VARIANT.bak", "$XKB/symbols/us"); } } else { die("usage: $0 install|uninstall\n"); } # Deal with evdev if (-f "$XKB/rules/evdev.extra.xml") { &process_xml("$XKB/rules/evdev.extras.xml", $VARIANT, $VARIANT_XML, $cmd); #https://bugs.launchpad.net/ubuntu/+source/gnome-control-center/+bug/1029979 &process_xml("$XKB/rules/evdev.xml", $VARIANT, $VARIANT_XML, $cmd); } elsif (-f "$XKB/rules/evdev.xml") { &process_xml("$XKB/rules/evdev.xml", $VARIANT, $VARIANT_XML, $cmd); } # Deal with base if (-f "$XKB/rules/base.extras.xml") { &process_xml("$XKB/rules/base.extras.xml", $VARIANT, $VARIANT_XML, $cmd); } elsif (-f "$XKB/rules/base.xml") { &process_xml("$XKB/rules/base.xml", $VARIANT, $VARIANT_XML, $cmd); } elsif (-f "$XKB/base.xml") { &process_xml("$XKB/base.xml", $VARIANT, $VARIANT_XML, $cmd); }