keymap-set 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #!/bin/sh
  2. # 10 Feb 2010 by shinobar (Masaki Shinomiya <shino@pos.to>)
  3. # 15 Feb 2010 remove include dir etc. from list
  4. # 18 Jul 2010 work without layouts file, remove error messages from dialog reply
  5. # 21 Jul 2010 opton '-load' force sets X properties
  6. # 24 Jul 2010 add input section if not exists (thanks to Abnormalter), variant qwerty|qwertz
  7. # 11 Aug 2010 keymap_previous to prevent xwin rewrites
  8. # 12 Aug 2010 azerty(fr) fixed
  9. # 5 Jan 2011 Allow keymaps work with with X but do not on the consile
  10. #111020 fix spelling typo.
  11. #120627 handle different path to keymaps in kbd pkg.
  12. #120715 fix wrong pattern, 'de' was finding 'de-latin1'. fix symbols different location.
  13. MYNAME=$(basename $0)
  14. VERSION=20100812
  15. usage() {
  16. echo "$MYNAME ver.-$VERSION
  17. usage: $MYNAME [ somekeymap ]
  18. set keymap to 'somekeymap' or ask with dialog
  19. $MYNAME cli
  20. ask keymap with console dialog
  21. $MYNAME --load
  22. set keymap according to /etc/keymap
  23. $MYNAME --xopt [ somekeymap ]
  24. show xorg.conf xkb options for 'somekeymap' or according to /etc/keymap
  25. $MYNAME --list
  26. show available key maps"
  27. exit 1
  28. }
  29. xmap() {
  30. M=$1
  31. case "$M" in
  32. az*) M="fr";; #azerty
  33. cf*) M="ca";; #canadian french
  34. cr*) M="hr";; #croat
  35. dv*) M="us";; #dvorak
  36. mk*) M="mkd";; #macedonia
  37. sl*) M="si";; #slovene
  38. sv) M="se";; #sweden
  39. uk) M="gb";; #united kingdom
  40. wa*) M="be";; #wangbe
  41. *) M=$(echo $M|cut -b 1-2)
  42. echo "$SYMBOLS" | grep -q "$M" || M="us"
  43. ;;
  44. esac
  45. echo $M
  46. }
  47. makelist() {
  48. DEFMAP="us"
  49. MAPS=$(echo "$MAPS"| grep -v "^$OLDMAP\$"| grep -v "^$DEFMAP"| sed -e 's/\.map//')
  50. OLDMAP=$(basename $OLDMAP .map)
  51. [ "$OLDMAP" = "$DEFMAP" ] && DEFMAP=""
  52. if [ -f /usr/share/i18n/layouts ]; then
  53. for MP in $OLDMAP $DEFMAP $MAPS; do
  54. M=$(echo $MP| tr '1' '-'| cut -d'-' -f1)
  55. M=$(xmap $M)
  56. M=$(grep "^[[:blank:]]*$M " /usr/share/i18n/layouts| sed -e 's/^[[:blank:]]*[a-z-]*[ ]*//')
  57. echo -n "$MP"
  58. [ "$M" != "" ] && echo " ($M)" || echo " ."
  59. done
  60. else
  61. #echo "$OLDMAP"
  62. #[ "$DEFMAP" != "" ] && echo "$DEFMAP"
  63. #echo "$MAPS"
  64. for MP in $OLDMAP $DEFMAP $MAPS; do
  65. echo "$MP ."
  66. done
  67. fi
  68. }
  69. [ $# -le 2 ] || usage
  70. LANGORG=$LANG
  71. LANG=C
  72. KMAPPATH='/lib/keymaps'
  73. [ -d /usr/share/kbd/keymaps/i386 ] && KMAPPATH='/usr/share/kbd/keymaps/i386'
  74. [ -d /usr/share/keymaps/i386 ] && KMAPPATH='/usr/share/keymaps/i386' #debian, gentoo. note, debian files have extension .kmap.gz, gentoo have .map.gz
  75. case $KMAPPATH in #120627
  76. /lib/keymaps) KMAPFILES="`find /lib/keymaps -mindepth 1 -maxdepth 1 -name '*.gz' | sort`" ;; #ex: us.gz
  77. *) KMAPFILES="`find ${KMAPPATH}/[^i]* -name '*.map' -o -name '*.kmap' -o -name '*.map.gz' -o -name '*.kmap.gz' -not -name 'defkeymap*' | sort`" ;;
  78. esac
  79. MAPS="$(echo "$KMAPFILES" | sed -e 's%^.*/%%' -e 's%\.gz$%%')"
  80. if [ -d /etc/X11/xkb/symbols/pc ];then #120715 fix symbols different location.
  81. SYMBOLS=$(ls -1 /etc/X11/xkb/symbols/pc)
  82. else
  83. SYMBOLS="$(find /etc/X11/xkb/symbols -mindepth 1 -maxdepth 1 -type f | sed -e 's%/etc/X11/xkb/symbols/%%')"
  84. fi
  85. OLDMAP=""
  86. [ -f /etc/keymap ] && OLDMAP=$(cat /etc/keymap)
  87. [ "$OLDMAP" = "" ] && OLDMAP="us"
  88. [ "$DISPLAY" ] && XSTATUS="yes" || XSTATUS=""
  89. # options
  90. NEWMAP=""
  91. XOPT=""
  92. VERBOSE=""
  93. case "$1" in
  94. *-li*) # show available key maps
  95. makelist
  96. exit ;;
  97. *-lo*) # load keymap according /etc/keymap
  98. NEWMAP=$(cat /etc/keymap 2>/dev/null)
  99. VERBOSE="yes"
  100. ;;
  101. *-x*)
  102. XOPT="yes"
  103. shift
  104. [ "$1" != "" ] || NEWMAP=$(cat /etc/keymap 2>/dev/null)
  105. ;;
  106. cli) XSTATUS=""; shift;;
  107. -ver) echo "$MYNAME ver.-$VERSION"; exit;;
  108. -*) usage;;
  109. esac
  110. [ $# -le 1 ] || usage
  111. # verify
  112. [ "$NEWMAP" != "" ] || NEWMAP=$(basename "$1" .gz)
  113. if [ "$NEWMAP" = "" ] ; then
  114. DIALOG="dialog --aspect 10"
  115. MENUOPT="--menu"
  116. REP=/tmp/$(basename $0).txt
  117. [ "$XSTATUS" = "yes" ] && DIALOG="Xdialog" && MENUOPT="--menubox"
  118. CHOICES=$(makelist)
  119. CHOICES=$(echo $CHOICES|sed -e "s/(/'(/g" -e "s/)/)'/g")
  120. eval "$DIALOG --title \"$(gettext 'Setting keyboard layout')\" $MENUOPT \"$(gettext 'Choose keyboard layout for your country...')\" 0 0 0 $CHOICES" 2>$REP #111020 typo.
  121. NEWMAP=$(tail -n 1 $REP)
  122. rm -f $REP
  123. fi
  124. NEW=$(echo "$MAPS"|grep "^${NEWMAP}$"| head -n 1) #120715 wrong, fix.
  125. if [ "$NEW" = "" ];then
  126. NEWMAP=$(echo $NEWMAP| cut -b 1-2)
  127. NEW=$(echo "$MAPS"|grep -w "^$NEWMAP"| head -n 1)
  128. fi
  129. #echo "NEWMAP=$NEWMAP"
  130. # keymap for X. NEWMAP can be *.map
  131. XKEYMAP=$(basename $NEWMAP .kmap) #120627
  132. XKEYMAP=$(basename $XKEYMAP .map)
  133. MODEL="pc102"
  134. VARIANT=""
  135. if ! echo "$SYMBOLS" | grep -q "$XKEYMAP"; then
  136. XK1=$(echo $XKEYMAP | cut -d'-' -f1)
  137. XK2=$(echo $XKEYMAP | cut -d'-' -f2)
  138. XK3=$(echo $XKEYMAP | cut -d'-' -f3)
  139. XKEYMAP=$(xmap $XK1)
  140. if [ "$XK2" != "" ]; then
  141. for K in $XK1 $XK2 $XK3; do
  142. case "$K" in
  143. dvorak|qwerty|qwertz) VARIANT="$K";;
  144. esac
  145. done
  146. fi
  147. fi
  148. LAYOUT=$XKEYMAP
  149. case $XKEYMAP in
  150. br*) MODEL="abnt2"
  151. LAYOUT="br";;
  152. jp*) MODEL="jp106"
  153. LAYOUT="jp";;
  154. esac
  155. # xopt
  156. if [ "$XOPT" = "yes" ]; then
  157. echo "XKBMODEL=\"$MODEL\""
  158. echo "XKBLAYOUT=\"$LAYOUT\""
  159. echo "XKBVARIANT=\"$VARIANT\""
  160. exit 0
  161. fi
  162. # update
  163. if [ "$NEW" != "" ];then
  164. NEWMAP=$NEW
  165. #[ "$NEWMAP" = "$OLDMAP" ] && exit 0
  166. [ "$VERBOSE" ] && echo -ne "Loading \"$NEWMAP\" keyboard map... "
  167. echo -n $NEWMAP > /etc/keymap
  168. cp -f /etc/keymap /etc/keymap_previous # prevent xwin rewrites
  169. case $NEWMAP in
  170. *.map|*.kmap) loadkeys $NEWMAP || exit 1 #120627
  171. ;;
  172. *) /bin/gzip -dcf /lib/keymaps/$NEWMAP.gz | /sbin/loadkmap || exit 1
  173. ;;
  174. esac
  175. elif [ -s /usr/share/i18n/layouts ]; then
  176. NEW=$(grep -w "$NEWMAP" /usr/share/i18n/layouts| head -n 1 | tr -s ' ' |cut -d ' ' -f2)
  177. [ "$NEW" != "" ] && echo "Warning: The keymap '$NEW' does not act on the console(without X)." >&2
  178. fi
  179. [ "$NEW" != "" ] && NEWMAP=$NEW || exit 1
  180. echo -n $NEWMAP > /etc/keymap
  181. #[ "$NEWMAP" = "$OLDMAP" ] && exit 0
  182. # apply xkeymap now
  183. XVARIANT=""
  184. [ "$VARIANT" != "" ] && XVARIANT="-variant $VARIANT"
  185. setxkbmap -rules xorg -model "$MODEL" -layout "$LAYOUT" $XVARIANT || exit 1
  186. # rewrite xorg.conf
  187. F=/etc/X11/xorg.conf
  188. TMPF=/tmp/xorg.conf
  189. # read old settings
  190. ALINE=$(grep -i '^[[:blank:]]*Option.*XkbModel' $F| head -n 1| cut -d'#' -f1)
  191. for W in $ALINE; do :; done # set last word to W
  192. OLDMODEL=$(echo $W|tr -d '"')
  193. ALINE=$(grep -i '^[[:blank:]]*Option.*XkbLayOut' $F| head -n 1| cut -d'#' -f1)
  194. for W in $ALINE; do :; done
  195. OLDLAYOUT=$(echo $W|tr -d '"')
  196. ALINE=$(grep -i '^[[:blank:]]*Option.*XkbVariant' $F| head -n 1| cut -d'#' -f1)
  197. for W in $ALINE; do :; done # set last word to W
  198. OLDVARIANT=$(echo $W|tr -d '"')
  199. #[ "$OLDMODEL" = "" -a "$OLDLAYOUT" = "" ] && exit
  200. # rewrite xorg.conf
  201. if [ "$MODEL" != "$OLDMODEL" -o "$LAYOUT" != "$OLDLAYOUT" -o "$VARIANT" != "$OLDVARIANT" ]; then
  202. (while read ALINE; do
  203. FOUND="yes"
  204. echo $ALINE| grep -v '^[[:blank:]]*Option.*Xkb' || break
  205. FOUND=""
  206. done
  207. if [ "$FOUND" = "" ]; then
  208. echo 'Section "InputDevice"
  209. Identifier "Keyboard0"
  210. Driver "kbd"'
  211. fi
  212. echo " Option \"XkbRules\" \"xorg\""
  213. echo " Option \"XkbModel\" \"$MODEL\""
  214. echo " Option \"XkbLayout\" \"$LAYOUT\" #xkeymap0"
  215. [ "$VARIANT" != "" ] && echo " Option \"XkbVariant\" \"$VARIANT\""
  216. if [ "$FOUND" = "" ]; then
  217. echo 'EndSection'
  218. fi
  219. while read ALINE; do
  220. echo $ALINE| grep -v '^[[:blank:]]*Option.*Xkb' && break
  221. done
  222. while read ALINE; do echo $ALINE; done) <$F >$TMPF
  223. [ -s $TMPF ] && mv -f $F $F.bak && mv $TMPF $F
  224. fi