#!/usr/bin/perl -w # Enable PLUM to work as a standard pc keyboard # Written 2008 by Hans-Christoph Wirth # $Revision$ # $Date$ # # This command modifies any current X keymap (which is assumed to be # designed for use with an ordinary 105 key PC keyboard) so that it # can be used (almost) identically on a connected PLUM keyboard (see # www.plum.bz for information on that matrix-like keyboard). # # Usage: # # 1. Setup your keyboard layout for your standard keyboard using xmodmap. # 2. Read the warning below and prepare a recovery mechanism. # 3. Run this script without any parameters. # # Run with option "-n" to print the commands without executing them. # # Warning: # # There is no reliable way (that I am aware of) to determine the type # of the currently active keyboard. Hence we cannot prevent that you # call this script twice, which will instantaneously switch keyboard # input into a completely useless state. To recover from that, you # should prepare your desktop to run a recovery command (like 'xmodmap # $HOME/your-standard.modmap') on a mouse click. # ###################################################################### $XMODMAP = "/usr/bin/xmodmap"; # # Options # $opt = shift || ""; $noexec = $opt eq "-n" ? 1 : 0; $P = $noexec ? "! " : ""; # # Read transformation matrix # while () { ($plum, $pc) = split; $plum[$pc] = 0+ $plum; } # # Read and parse existing map # print "${P}reading existing keymap\n"; open (IN, "$XMODMAP -pke |") or die "read keyboard mapping failed\n"; while () { /^keycode\s+(\d+)\s+=\s+(.*)$/o or die "error: malformed line: $_\n"; if ($plum[$1]) { push @clearkeys, "keycode $plum[$1] =\n"; push @setkeys, "keycode $plum[$1] = $2\n"; push @report_keys, (split( ' ', $2, 2 ))[0]; } } close (IN); # # Read and parse existing modifiers # print "${P}reading existing modifiers\n"; open (IN, "$XMODMAP -pm |") or die "read modifier list failed\n"; while () { unless (/^(shift|lock|control|mod\d)\s*(.*)$/) { next; } ($mod, $info) = ($1, $2); @infos = (); for (split( /,/, $info )) { s/\(\S*\)//; next if /^\s*$/; push @infos, $_; } push @clearmodifiers, "clear $mod\n"; push @report_clearmodifiers, "$mod "; if (@infos) { push @setmodifiers, "add $mod = @infos\n"; push @report_setmodifiers, "$mod "; } } close (IN); # # Now perform the changes using two external calls. # print "${P}clearing " . @report_keys . " keys... @report_keys\n"; print "${P}clearing " . @report_clearmodifiers . " modifiers... @report_clearmodifiers\n"; if ($noexec) { open (OUT, "| cat") or die "clear map failed\n"; } else { open (OUT, "| $XMODMAP -") or die "clear map failed\n"; } print OUT @clearkeys; print OUT @clearmodifiers; close (OUT) or die "clear map failed\n"; print "${P}setting all keys and modifiers @report_setmodifiers\n"; if ($noexec) { open (OUT, "| cat") or die "set new map failed\n"; } else { open (OUT, "| $XMODMAP -") or die "set new map failed\n"; } print OUT @setkeys; print OUT @setmodifiers; close (OUT) or die "set new map failed\n"; # The data section lists the plum keyboard scancodes ordered from left # to right and top to bottom. Each line describes one key position in # the form 'plum code' 'pc code'. Since the keyboard is short of a # few keys we have to move some keys in the periphery: this affects in # particular # # - the key to the left of '1' moves down next to right shift # - the key to the right of left shift moves down; there is no longer # a left windows key # - return key moves down to space key, obviously # # As an example, the standard German 105 key layout is mapped as # follows: # # # regular pc layout # # esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 # ^ 1 2 3 4 5 6 7 8 9 0 ß ' -bsp- # tab q w e r t z u i o p ü + ret # lock a s d f g h j k l ö ä # # shf < y x c v b n m , . - ---shf--- # ctr win alt ---------spc--------- agr win men ctr # # # plum mapping # # esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 # 1 2 3 4 5 6 7 8 9 0 ß ' bsp # tab q w e r t z u i o p ü + # lck a s d f g h j k l ö ä # # shf y x c v b n m , . - shf ^ # ctr < alt ---ret--- ---spc--- agr win ctr __DATA__ 9 9 67 67 68 68 69 69 70 70 71 71 72 72 73 73 74 74 75 75 76 76 95 95 96 96 49 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 47 23 33 24 46 25 30 26 58 27 23 28 22 29 54 30 41 31 42 32 24 33 48 34 51 35 36 36 50 66 27 38 26 39 38 40 40 41 32 42 57 43 28 44 43 45 31 46 39 47 62 48 61 51 66 50 45 52 44 53 55 54 56 55 59 56 60 57 25 58 53 59 29 60 52 61 34 62 35 49 37 37 115 94 64 64 65 65 113 113 116 116 109 109