keymap.subr revision 279612
1139969Simpif [ ! "$_KEYMAP_SUBR" ]; then _KEYMAP_SUBR=1 21556Srgrimes# 31556Srgrimes# Copyright (c) 2013 Devin Teske 41556Srgrimes# All rights reserved. 51556Srgrimes# 61556Srgrimes# Redistribution and use in source and binary forms, with or without 71556Srgrimes# modification, are permitted provided that the following conditions 81556Srgrimes# are met: 91556Srgrimes# 1. Redistributions of source code must retain the above copyright 101556Srgrimes# notice, this list of conditions and the following disclaimer. 111556Srgrimes# 2. Redistributions in binary form must reproduce the above copyright 121556Srgrimes# notice, this list of conditions and the following disclaimer in the 131556Srgrimes# documentation and/or other materials provided with the distribution. 141556Srgrimes# 151556Srgrimes# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 161556Srgrimes# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 171556Srgrimes# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 181556Srgrimes# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 191556Srgrimes# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 201556Srgrimes# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 211556Srgrimes# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 221556Srgrimes# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 231556Srgrimes# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 241556Srgrimes# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 251556Srgrimes# SUCH DAMAGE. 261556Srgrimes# 271556Srgrimes# $FreeBSD: stable/10/usr.sbin/bsdconfig/share/keymap.subr 279612 2015-03-05 00:37:54Z dteske $ 281556Srgrimes# 291556Srgrimes############################################################ INCLUDES 301556Srgrimes 311556SrgrimesBSDCFG_SHARE="/usr/share/bsdconfig" 321556Srgrimes. $BSDCFG_SHARE/common.subr || exit 1 331556Srgrimesf_dprintf "%s: loading includes..." keymap.subr 3450471Speterf_include $BSDCFG_SHARE/struct.subr 351556Srgrimes 36211965Sbrian############################################################ CONFIGURATION 371556Srgrimes 3879526Sru# 391556Srgrimes# Defaults taken from usr.sbin/kbdmap/kbdmap.h 401556Srgrimes# 411556Srgrimes: ${DEFAULT_LANG:=en} 421556Srgrimes: ${DEFAULT_KEYMAP_DIR:=/usr/share/syscons/keymaps} 4368935Sru 4476286Skris############################################################ GLOBALS 451556Srgrimes 461556SrgrimesKEYMAPS= 471556SrgrimesNKEYMAPS=0 481556Srgrimes 491556Srgrimes# A "keymap" from kbdmap's point of view 5070150Sruf_struct_define KEYMAP \ 511556Srgrimes desc \ 521556Srgrimes keym \ 531556Srgrimes mark 5470150Sru 551556Srgrimes# 561556Srgrimes# Default behavior is to call f_keymap_get_all() automatically when loaded. 571556Srgrimes# 5870150Sru: ${KEYMAP_SELF_SCAN_ALL=1} 591556Srgrimes 601556Srgrimes############################################################ FUNCTIONS 611556Srgrimes 621556Srgrimes# f_keymap_register $name $desc $keym $mark 631556Srgrimes# 641556Srgrimes# Register a keymap. A `structure' (see struct.subr) is created with the name 651556Srgrimes# keymap_$name (so make sure $name contains only alpha-numeric characters or 6670150Sru# the underscore, `_'). The remaining arguments after $name correspond to the 671556Srgrimes# propertise of the `KEYMAP' structure-type (defined above). 6870150Sru# 6968935Sru# If not already registered, the keymap is then appended to the KEYMAPS 701556Srgrimes# environment variable, a space-separated list of all registered keymaps. 7176286Skris# 721556Srgrimesf_keymap_register() 731556Srgrimes{ 741556Srgrimes local name="$1" desc="$2" keym="$3" mark="$4" 751556Srgrimes 761556Srgrimes f_struct_new KEYMAP "keymap_$name" || return $FAILURE 7770150Sru keymap_$name set desc "$desc" 781556Srgrimes keymap_$name set keym "$keym" 791556Srgrimes keymap_$name set mark "$mark" 801556Srgrimes 8170150Sru # Scan our global register to see if needs ammending 821556Srgrimes local k found= 831556Srgrimes for k in $KEYMAPS; do 841556Srgrimes [ "$k" = "$name" ] || continue 8570150Sru found=1 && break 861556Srgrimes done 871556Srgrimes [ "$found" ] || KEYMAPS="$KEYMAPS $name" 881556Srgrimes 891556Srgrimes return $SUCCESS 9070150Sru} 911556Srgrimes 921556Srgrimes# f_keymap_checkfile $keymap 931556Srgrimes# 9470150Sru# Check that $keymap is a readable kbdmap(5) file. Returns success if $keymap 951556Srgrimes# is a file, is readable, and exists in $DEFAULT_KEYMAP_DIR; otherwise failure. 961556Srgrimes# If debugging is enabled, an appropriate debug error message is printed if 971556Srgrimes# $keymap is not available. 981556Srgrimes# 991556Srgrimesf_keymap_checkfile() 1001556Srgrimes{ 1011556Srgrimes local keym="$1" 10270150Sru 1031556Srgrimes # Fixup keymap if it doesn't already contain at least one `/' 10470150Sru [ "${keym#*/}" = "$keym" ] && keym="$DEFAULT_KEYMAP_DIR/$keym" 10568935Sru 1061556Srgrimes # Short-cuts 10776286Skris [ -f "$keym" -a -r "$keym" ] && return $SUCCESS 1081556Srgrimes f_debugging || return $FAILURE 1091556Srgrimes 1101556Srgrimes # Print an appropriate debug error message 1111556Srgrimes if [ ! -e "$keym" ]; then 1121556Srgrimes f_dprintf "%s: No such file or directory" "$keym" 1131556Srgrimes elif [ ! -f "$keym" ]; then 1141556Srgrimes f_dprintf "%s: Not a file!" "$keym" 1151556Srgrimes elif [ ! -r "$keym" ]; then 1161556Srgrimes f_dprintf "%s: Permission denied" "$keym" 1171556Srgrimes fi 1181556Srgrimes 1191556Srgrimes return $FAILURE 12070150Sru} 1211556Srgrimes 1221556Srgrimes# f_keymap_get_all 1231556Srgrimes# 12470150Sru# Get all keymap information for kbdmap(5) entries both in the database and 1251556Srgrimes# loosely existing in $DEFAULT_KEYMAP_DIR. 1261556Srgrimes# 1271556Srgrimesf_keymap_get_all() 12870150Sru{ 1291556Srgrimes local fname=f_keymap_get_all 1301556Srgrimes local lang="${LC_ALL:-${LC_CTYPE:-${LANG:-$DEFAULT_LANG}}}" 1311556Srgrimes [ "$lang" = "C" ] && lang="$DEFAULT_LANG" 13270150Sru 1331556Srgrimes f_dprintf "%s: Looking for keymap files..." $fname 1341556Srgrimes f_dialog_info "$msg_looking_for_keymap_files" 1351556Srgrimes f_dprintf "DEFAULT_LANG=[%s]" "$DEFAULT_LANG" 1361556Srgrimes 1371556Srgrimes eval "$( awk -F: -v lang="$lang" -v lang_default="$DEFAULT_LANG" ' 1381556Srgrimes BEGIN { 1391556Srgrimes # en_US.ISO8859-1 -> en_..\.ISO8859-1 1401556Srgrimes dialect = lang 1411556Srgrimes if (length(dialect) >= 6 && 1421556Srgrimes substr(dialect, 3, 1) == "_") 1431556Srgrimes dialect = substr(dialect, 1, 3) ".." \ 14470150Sru substr(dialect, 6) 1451556Srgrimes printf "f_dprintf \"dialect=[%%s]\" \"%s\";\n", dialect 14672432Sru 14768935Sru # en_US.ISO8859-1 -> en 1481556Srgrimes lang_abk = lang 1491556Srgrimes if (length(lang_abk) >= 3 && 1501556Srgrimes substr(lang_abk, 3, 1) == "_") 1511556Srgrimes lang_abk = substr(lang_abk, 1, 2) 1521556Srgrimes printf "f_dprintf \"lang_abk=[%%s]\" \"%s\";\n", 15370150Sru lang_abk 1541556Srgrimes } 1551556Srgrimes function find_token(buffer, token) 1561556Srgrimes { 15770150Sru if (split(buffer, tokens, /,/) == 0) return 0 1581556Srgrimes found = 0 1591556Srgrimes for (t in tokens) 1601556Srgrimes if (token == tokens[t]) { found = 1; break } 16170150Sru return found 1621556Srgrimes } 1631556Srgrimes function add_keymap(desc,mark,keym) 1641556Srgrimes { 16570150Sru marks[keym] = mark 1661556Srgrimes name = keym 1671556Srgrimes gsub(/[^[:alnum:]_]/, "_", name) 1681556Srgrimes gsub(/'\''/, "'\''\\'\'\''", desc); 1691556Srgrimes printf "f_keymap_checkfile %s && " \ 1701556Srgrimes "f_keymap_register %s '\'%s\'' %s %u\n", 1711556Srgrimes keym, name, desc, keym, mark 1721556Srgrimes } 1731556Srgrimes !/^[[:space:]]*(#|$)/ { 17470150Sru sub(/^[[:space:]]*/, "", $0) 1751556Srgrimes keym = $1 17672432Sru if (keym ~ /^(MENU|FONT)$/) next 1771556Srgrimes lg = ($2 == "" ? lang_default : $2) 1781556Srgrimes 17995204Scharnier # Match the entry and store the type of match we made 18095204Scharnier # as the mark value (so that if we make a better match 18195204Scharnier # later on with a higher mark, it overwrites previous) 1821556Srgrimes 18395204Scharnier mark = marks[keym]; 18495204Scharnier if (find_token(lg, lang)) 1851556Srgrimes add_keymap($3, 4, keym) # Best match 1861556Srgrimes else if (mark <= 3 && find_token(lg, dialect)) 1871556Srgrimes add_keymap($3, 3, keym) 1881556Srgrimes else if (mark <= 2 && find_token(lg, lang_abk)) 1891556Srgrimes add_keymap($3, 2, keym) 1901556Srgrimes else if (mark <= 1 && find_token(lg, lang_default)) 1911556Srgrimes add_keymap($3, 1, keym) 1921556Srgrimes else if (mark <= 0) 1931556Srgrimes add_keymap($3, 0, keym) 19436049Scharnier } 1951556Srgrimes ' "$DEFAULT_KEYMAP_DIR/INDEX.${DEFAULT_KEYMAP_DIR##*/}" )" 1961556Srgrimes 1971556Srgrimes 19871895Sru # 1991556Srgrimes # Look for keymaps not in database 2001556Srgrimes # 2011556Srgrimes local direntry keym name 20295204Scharnier set +f # glob 2031556Srgrimes for direntry in "$DEFAULT_KEYMAP_DIR"/*; do 2041556Srgrimes [ "${direntry##*.}" = ".kbd" ] || continue 2051556Srgrimes keym="${direntry##*/}" 2061556Srgrimes f_str2varname "$keym" name 20771895Sru f_struct keymap_$name && continue 2081556Srgrimes f_keymap_checkfile "$keym" && 2091556Srgrimes f_keymap_register $name "${keym%.*}" "$keym" 0 2101556Srgrimes f_dprintf "%s: not in kbdmap(5) database" "$keym" 2111556Srgrimes done 21295204Scharnier 2131556Srgrimes # 21479754Sdd # Sort the items by their descriptions 21571895Sru # 2161556Srgrimes f_dprintf "%s: Sorting keymap entries by description..." $fname 2171556Srgrimes KEYMAPS=$( 2181556Srgrimes for k in $KEYMAPS; do 2191556Srgrimes echo -n "$k " 2201556Srgrimes # NOTE: Translate '8x8' to '8x08' before sending to 2211556Srgrimes # sort(1) so that things work out as we might expect. 2221556Srgrimes debug= keymap_$k get desc | awk 'gsub(/8x8/,"8x08")||1' 2231556Srgrimes done | sort -k2 | awk '{ 2241556Srgrimes printf "%s%s", (started ? " " : ""), $1; started = 1 2251556Srgrimes }' 22695204Scharnier ) 2271556Srgrimes 2281556Srgrimes return $SUCCESS 2291556Srgrimes} 2301556Srgrimes 23179754Sdd# f_keymap_kbdcontrol $keymap 2321556Srgrimes# 23379754Sdd# Install keyboard map file from $keymap. 2341556Srgrimes# 23579754Sddf_keymap_kbdcontrol() 2361556Srgrimes{ 2371556Srgrimes local keymap="$1" 2381556Srgrimes 2391556Srgrimes [ "$keymap" ] || return $SUCCESS 2401556Srgrimes 24195204Scharnier # Fixup keymap if it doesn't already contain at least one `/' 2421556Srgrimes [ "${keymap#*/}" = "$keymap" ] && keymap="$DEFAULT_KEYMAP_DIR/$keymap" 2431556Srgrimes 2441556Srgrimes [ "$USE_XDIALOG" ] || kbdcontrol -l "$keymap" 24579754Sdd} 2461556Srgrimes 2471556Srgrimes############################################################ MAIN 2481556Srgrimes 2491556Srgrimes# 2501556Srgrimes# Scan for keymaps unless requeted otherwise 2511556Srgrimes# 2521556Srgrimesf_dprintf "%s: KEYMAP_SELF_SCAN_ALL=[%s]" keymap.subr "$KEYMAP_SELF_SCAN_ALL" 2531556Srgrimescase "$KEYMAP_SELF_SCAN_ALL" in 2541556Srgrimes""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;; 2551556Srgrimes*) f_keymap_get_all 2561556Srgrimesesac 2571556Srgrimes 2581556Srgrimesf_count NKEYMAPS $KEYMAPS 2591556Srgrimesf_dprintf "%s: Found %u keymap file(s)." keymap.subr $NKEYMAPS 2601556Srgrimes 2611556Srgrimesf_dprintf "%s: Successfully loaded." keymap.subr 2621556Srgrimes 2631556Srgrimesfi # ! $_KEYMAP_SUBR 2641556Srgrimes