#!/bin/sh # /!\ ATTENTION : l’appel de ce script sans argument change immédiatement et # radicalement la disposition du clavier. # Ce n’est certainement pas une bonne idée si vous ne savez pas ce que vous # faites ou si vous n’avez pas sauvegardé vos travaux en cours. # beop # Auteur : Laurent Dudouеt # $Revision: 1.83 $ # $Date: 2022/09/08 04:59:51 $ # Ce script est fourni sans aucune garantie. # Vous pouvez l’utiliser selon les termes de la licence GNU GPL version 2 ou # ultérieure de la Free Software Foundation # (http://www.gnu.org/licenses/licenses.html#GPL). # Ce script charge immédiatement ou installe la disposition de clavier Béop # (voir http://beop.free.fr/), suivant les options avec lesquelles il est # appelé, sous X.org ou la console de GNU/Linux. # Pour obtenir l’aide, appelez-le avec l’option -h # Pour voir la disposition, appelez-le avec l’option -carte dans un terminal en # UTF-8. Ça devrait l’afficher sous une forme plus lisible que ci-dessous et en # tenant compte d’éventuelles options. # Disposition Béop, version par défaut : # ┏━━━━┱────┬────┬────┬────┬────┬────┰────┬────┬────┬────┬────┬────┲━━━━━━━━┓ # ┃Alt ┃ § →│ W ⇒│ « ¯│ » Ñ│ “ „│ ” Þ┃ Ù ˘│ Ç °│ – ′│ — ″│ µ ˙│ ‰ ®┃ ┃ # ┃Comp┃ # ʒ│ w ij│ - ‑│ ' ñ│ " ð│ ` þ┃ ù ŭ│ ç 8│ ( 9│ ) ,│ ¨ .│ % =┃ ⌫ ┃ # ┣━━━━┻━━┱─┴──┬─┴──┬─┴──┬─┴──┬─┴──┰─┸──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┺━━┳━━━━━┫ # ┃ ⇤ ┃ B ʼ│ É Æ│ O Œ│ P ˚│ È ẞ┃ ! ˇ│ V ±│ D ᵈ│ L ᵉ│ J ˝│ Z º│ × †┃ ┃ # ┃ ⇥ ┃ b |│ é æ│ o œ│ p &│ è ß┃ ˆ ¡│ v +│ d 4│ l 5│ j 6│ z 7│ ´ *┃ ┃ # ┣━━━━━━━┻┱───┴┬───┴┬───┴┬───┴┬───┸┰───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┺┓ ↲ ┃ # ┃ Verr. ┃ A ≤│ U ≃│ E ¤│ I ≥│ ; /┃ C ©│ T –│ S ˢ│ R ʳ│ N ᵒ│ F ª│ ÷ ‡┃ ┃ # ┃ Maj. ┃ a <│ u =│ e €│ i >│ , /┃ c @│ t -│ s 0│ r 1│ n 2│ f 3│ ` /┃ ┃ # ┣━━━━━┳━━┹─┬──┴─┬──┴─┬──┴─┯━─┴─┬──┸─┰──┴─┯━─┴─┬──┴─┬──┴─┬──┴─┲━━┷━━━━┻━━━━┫ # ┃ ┃ Ê │ À ‐│ Y ≠│ X •│ : ·│ K ˜┃ ? ‘│ Q ˛│ G ¸│ H ,│ M ․┃ ┃ # ┃ ⇧ ┃ ê *│ à \│ y {│ x }│ . …│ k ~┃ ’ ¿│ q [│ g ]│ h ^│ m $┃ ⇧ ┃ # ┣━━━━━┻┳━━━┷━━┳━┷━━━━┷┱───┴────┴────┸────┴───┲┷━━━━┷━┳━━┷━━━┳┻━━━━━┳━━━━━━┫ # ┃ ┃ ┃ ┃ insécable ins. fine ┃ ┃ WinD ┃ Menu ┃ ┃ # ┃ Ctrl ┃ Alt ┃ AltGr ┃ Espace _ ┃ AltGr ┃ Menu ┃ WinG ┃ Ctrl ┃ # ┗━━━━━━┻━━━━━━┻━━━━━━━┹──────────────────────┺━━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛ # ┌────┐ # │ O Œ│ Maj. (⇧) + touche → O , AltGr + Maj. (⇧) + touche → Œ # │ o œ│ touche seule → o , AltGr + touche → œ # └────┘ # Ce script essaie autant que possible d’être en « shell portable », dans la # mesure ou Perl n’est pas installé en standard sur les systèmes les plus # hostiles et qu’un shell évolué n’est pas forcément disponible non plus, ou # alors pas à un emplacement standard. # Ça implique beaucoup de limitations : pas de tableaux, pas de fonctions de # traitement de chaînes pratiques, pas de variables locales (/bin/sh # d’OpenIndiana)… # Ce script essaie aussi d’éviter au maximum les dépendances externes. # Il a été mis au point sur plusieurs distributions GNU/Linux courantes (Arch, # CentOS, Debian, Fedora, Ubuntu) et sur FreeBSD, OpenBSD et OpenIndiana. # Cependant la dernière version n’a pas forcément été testée sur tous ces # systèmes. Merci de prévenir si vous constatez une régresison ou si vous # essayez sur un autre système (beop chez free point fr). # Adaptations suivant le système analyse_systeme() { # On détermine les répertoires concernés pour X. # Ils correspondent normalement à cette expression : # /usr{,/local}{,/X11R6,/X11R7)/{share,lib}/X11/xkb (qu’on évite d’utiliser # pour limiter les risques d’incompatibilité avec les shells les moins # évolués). as_fich_fr='' # variable utilisée pour savoir si on installe pour X for as_rep_local in '' '/local'; do for as_rep_X11R in '' '/X11R6' '/X11R7'; do for as_rep_share in 'share' 'lib'; do as_rep="$rep_install/usr$as_rep_local$as_rep_X11R/$as_rep_share/X11/xkb" if [ -d "$as_rep" ]; then as_rep_xkb="$as_rep" as_rep_symbols="$as_rep_xkb/symbols" as_rep_rules="$as_rep_xkb/rules" if [ -f "$as_rep_symbols/pc/fr" ]; then as_fich_fr="$as_rep_symbols/pc/fr" else as_fich_fr="$as_rep_symbols/fr" fi break 3 fi done done done # L’existence d’un fichier séparé pour la disposition fr latin9 # permet de savoir si les dispositions sont installées séparément ou # comme variantes ; on agit en fonction. if [ -n "$as_fich_fr" ] && [ -f "${as_fich_fr}-latin9" ]; then as_fich_X="${as_fich_fr}-beop" as_fich_X_separe=true else as_fich_X="$as_fich_fr" as_fich_X_separe=false fi # Fichier pour tester l’existence des symboles # S’il est présent sur le système, on utilise l’include qui les définit, if [ -f /usr/include/X11/keysymdef.h ]; then as_symb_fich='/usr/include/X11/keysymdef.h' # sinon on se rabat sur le fichier de définition des claviers français (sur # un système relativement récent, il contient la disposition Bépo qui # utilise les caractères qu’on recherche ; sur un système ancien, il ne # contient rien d’intéressant, mais la plupart des symboles récents # n’existent pas (en tout cas dead_greek, postérieur à l’intégration de la # disposition Bépo). else as_symb_fich="$as_fich_fr" fi # Suivant l’existence ou non de certain symboles, on les utilise ou on passe # à une solution de repli. if [ -n "$as_symb_fich" ]; then if grep dead_greek $as_symb_fich > /dev/null 2>&1; then as_dead_greek='dead_greek' else as_dead_greek='mu' fi if grep dead_stroke $as_symb_fich > /dev/null 2>&1; then as_dead_stroke='dead_stroke' else as_dead_stroke='UFDD0' fi if grep dead_currency $as_symb_fich > /dev/null 2>&1; then as_dead_currency='dead_currency' else as_dead_currency='currency' fi if grep dead_belowcomma $as_symb_fich > /dev/null 2>&1; then as_dead_belowcomma='dead_belowcomma' else as_dead_belowcomma='UFDD3' fi fi # On détermine l’éventuel fichier de déclaration spécifique à Debian et ses # dérivées. as_fich_debian='' for as_nom_fich in keyboard-configuration.config console-setup.config; do as_fich="$rep_install/var/lib/dpkg/info/$as_nom_fich" if [ -f "$as_fich" ] && grep bepo "$as_fich" > /dev/null 2>&1; then as_fich_debian="$as_fich" break fi done } # Réglage des éventuelles couleurs d’affichage couleurs() { co_couleurs="$1" # Si les couleurs ne sont pas prises en charge, on affiche en noir et blanc { $co_couleurs && [ -t 1 ] && { tput colors || tput Co ; } > /dev/null 2>&1; } || co_couleurs=false if $co_couleurs; then co_ecr_norm='\033[39m' co_fond_norm='\033[49m' case "$co_couleurs" in # Note : certains terminaux ne prennent pas en charge les codes de # couleurs claires (à partir de 90 pour l’écriture et 100 pour le fond), # on fixe donc auparavant une couleur de repli. # Fond blanc, écriture noire *fond_clair) if [ "$COLORTERM" = "truecolor" ]; then co_ecr='\033[30;38;2;0;0;0m' co_fond='\033[47;107;48;2;255;255;255m' co_mort='\033[31;91;38;2;223;0;0m' co_insec='\033[47;48;2;191;191;191m' co_grise='\033[34;90;38;2;127;127;127m' else co_ecr='\033[30m' co_fond='\033[47;107m' co_mort='\033[31m' co_insec='\033[47m' co_grise='\033[34;90m' fi ;; # Fond noir, écriture blanche *fond_sombre) if [ "$COLORTERM" = "truecolor" ]; then co_ecr='\033[37;97;38;2;255;255;255m' co_fond='\033[40;48;2;0;0;0m' co_mort='\033[31;38;2;255;63;31m' co_insec='\033[44;100;48;2;63;63;63m' co_grise='\033[37;38;2;127;127;127m' else co_ecr='\033[37;97m' co_fond='\033[40m' co_mort='\033[31;91m' co_insec='\033[44;100m' co_grise='\033[37m' fi ;; # Couleurs relativement passe-partout *) co_ecr="$co_ecr_norm" co_fond="$co_fond_norm" co_mort='\033[31;91m' co_insec='\033[44m' co_grise='\033[34m' ;; esac co_fmort="$co_ecr" co_finsec="$co_fond" co_fgrise="$co_ecr" else # Pas de couleurs co_ecr_norm='' co_fond_norm='' co_ecr='' co_fond='' co_mort='' co_fmort='' co_insec='' co_finsec='' co_grise='' co_fgrise='' fi } # Adaptation des caractères suivant la version et la variante de la disposition version() { ve_version="$1"; ve_variante="$2"; ve_altgr_sur_win="$3" ve_guillemets_avec_espaces_norm="$4"; ve_guillemets_avec_espaces_typo="$5" ve_large="$6"; ve_couleurs="$7"; ve_prefixe="$8" $debug && echo "version '$1' '$2' '$3' '$4' '$5' '$6' '$7' '$8'" >&2 couleurs "$ve_couleurs" # Selon l’option choisie, on met les guillemets français tels quels ou on # les remplace par des codes qui leur associeront les espaces insécables # normale et fine. Cela nécessite d’avoir les définitions suivantes dans # .XCompose : # : "« " # : " »" # : "« " # : " »" # ve_guillemets_avec_espaces_norm et _typo n’ont pas été forcément été # définies par la fonction appelante, mais si elles ne l’ont pas été, c’est # qu’elle n’a pas besoin des variables qui en dépendent. # Par contre, une fonction parente pourrait en avoir besoin. On évite donc # de les écraser au cas ou les appels ne seraient pas faits dans le « bon » # ordre. if [ -n "$ve_guillemets_avec_espaces_norm" ]; then if $ve_guillemets_avec_espaces_norm; then ve_guil_ouvr="UFDE8" ve_guil_ferm="UFDE9" else ve_guil_ouvr="guillemotleft" ve_guil_ferm="guillemotright" fi fi if [ -n "$ve_guillemets_avec_espaces_typo" ]; then if $ve_guillemets_avec_espaces_typo; then ve_guil_ouvr_typo="UFDEA" ve_guil_ferm_typo="UFDEB" else ve_guil_ouvr_typo="guillemotleft" ve_guil_ferm_typo="guillemotright" fi fi # On adapte suivant la version. case "$ve_version" in 1.0) ve_AE01_a='ə' ve_AE01_a_symb='schwa' ve_AE01_a_symbc='U+0259' ve_AE02_a='ð' ve_AE02_a_symb='eth' ve_AE02_a_symbc="$ve_AE02_a_symb" ve_AE03_a='ij' ve_AE03_a_symb='U0133' ve_AE03_a_symbc='U+0133' ve_AE03_ma="${co_insec}‑${co_finsec}" ve_AE03_ma_symb='U2011' ve_AE03_ma_symbc='U+2011' ve_AE04_a='æ' ve_AE04_a_symb='ae' ve_AE04_a_symbc="+ae" ve_AE04_ma='Æ' ve_AE04_ma_symb='AE' ve_AE04_ma_symbc="+AE" ve_AE05_a='ñ' ve_AE05_a_symb='ntilde' ve_AE05_a_symbc="+ntilde" ve_AE05_ma='Ñ' ve_AE05_ma_symb='Ntilde' ve_AE05_ma_symbc="+Ntilde" # En couleurs, la couleur permettra de distinguer le point souscrit # et il sera plus lisible en gros. if $co_couleurs; then ve_AE07_ma="${co_mort}.${co_fmort}" else ve_AE07_ma='․' fi ve_AE07_ma_symb='dead_belowdot' ve_AE07_ma_symbc='U+0323' ve_AE12_ma='º' ve_AE12_ma_symb='masculine' ve_AE12_ma_symbc="$ve_AE12_ma_symb" ve_AD01_ma='¦' ve_AD01_ma_symb='brokenbar' ve_AD01_ma_symbc='U+00a6' ve_AD02_type='"FOUR_LEVEL_SEMIALPHABETIC"' ve_AD02_a="${co_mort}´${co_fmort}" ve_AD02_a_symb='dead_acute' ve_AD02_a_symbc="$ve_AD02_a_symb" ve_AD02_ma="${co_mort}˝${co_fmort}" ve_AD02_ma_symb='dead_doubleacute' ve_AD02_ma_symbc="$ve_AD02_ma_symb" ve_AD04_ma='„' ve_AD04_ma_symb='doublelowquotemark' ve_AD04_ma_symbc='U+201e' ve_AD05_type='"FOUR_LEVEL_SEMIALPHABETIC"' ve_AD05_a="${co_mort}\`${co_fmort}" ve_AD05_a_symb='dead_grave' ve_AD05_a_symbc="$ve_AD05_a_symb" ve_AD05_ma="${co_mort}˚${co_fmort}" ve_AD05_ma_symb='dead_abovering' ve_AD05_ma_symbc='degree' ve_AD08_ma='™' ve_AD08_ma_symb='trademark' ve_AD08_ma_symbc="$ve_AD08_ma_symb" # U+2122 ve_AD09_ma="${co_mort}/${co_fmort}" ve_AD09_ma_symb="$as_dead_stroke" ve_AD09_ma_symbc='slash' ve_AD10_ma='ᵒ' ve_AD10_ma_symb='U1D52' ve_AD10_ma_symbc='U+1d52' # U+00ba ve_AD11_ma='ˢ' ve_AD11_ma_symb='U02E2' ve_AD11_ma_symbc='U+02e2' ve_AD12='*' ve_AD12_symb='asterisk' ve_AD12_symbc="$ve_AD12_symb" ve_AC05_ma="${co_mort}˘${co_fmort}" ve_AC05_ma_symb='dead_breve' ve_AC05_ma_symbc="$ve_AC05_ma_symb" ve_AC08_ma='ß' ve_AC08_ma_symb='ssharp' ve_AC08_ma_symbc="$ve_AC08_ma_symb" ve_AC09_ma='®' ve_AC09_ma_symb='registered' ve_AC09_ma_symbc="$ve_AC09_ma_symb" ve_AC10_ma='¬' ve_AC10_ma_symb='notsign' ve_AC10_ma_symbc="$ve_AC10_ma_symb" ve_BKSL='/' ve_BKSL_symb='slash' ve_BKSL_symbc="$ve_BKSL_symb" ve_AB10_ma="${co_mort}¯${co_fmort}" ve_AB10_ma_symb='dead_macron' ve_AB10_ma_symbc='macron' ;; *) ve_AE01_a='ʒ' ve_AE01_a_symb='ezh' ve_AE01_a_symbc="$ve_AE01_a_symb" ve_AE02_a='ij' ve_AE02_a_symb='U0133' ve_AE02_a_symbc='U+0133' ve_AE03_a="${co_insec}‑${co_finsec}" ve_AE03_a_symb='U2011' ve_AE03_a_symbc='U+2011' ve_AE03_ma="${co_mort}¯${co_fmort}" ve_AE03_ma_symb='dead_macron' ve_AE03_ma_symbc='macron' ve_AE04_a='ñ' ve_AE04_a_symb='ntilde' ve_AE04_a_symbc='+ntilde' ve_AE04_ma='Ñ' ve_AE04_ma_symb='Ntilde' ve_AE04_ma_symbc='+Ntilde' # Légère adaptation suivant la variante. case "$ve_variante" in prog) ve_AE05_a='_' ve_AE05_a_symb='underscore' ve_AE05_a_symbc="$ve_AE05_a_symb" ;; *) ve_AE05_a='ð' ve_AE05_a_symb='eth' ve_AE05_a_symbc="$ve_AE05_a_symb" ;; esac ve_AE05_ma='„' ve_AE05_ma_symb='doublelowquotemark' ve_AE05_ma_symbc='U+201e' ve_AE07_ma="${co_mort}˘${co_fmort}" ve_AE07_ma_symb='dead_breve' ve_AE07_ma_symbc="$ve_AE07_ma_symb" ve_AE12_ma='®' ve_AE12_ma_symb='registered' ve_AE12_ma_symbc="$ve_AE12_ma_symb" ve_AD01_ma='ʼ' ve_AD01_ma_symb='U02BC' ve_AD01_ma_symbc='U+02bc' ve_AD02_type='"FOUR_LEVEL_ALPHABETIC" ' ve_AD02_a='æ' ve_AD02_a_symb='ae' ve_AD02_a_symbc='+ae' ve_AD02_ma='Æ' ve_AD02_ma_symb='AE' ve_AD02_ma_symbc='+AE' ve_AD04_ma="${co_mort}˚${co_fmort}" ve_AD04_ma_symb='dead_abovering' ve_AD04_ma_symbc='degree' ve_AD05_type='"FOUR_LEVEL_ALPHABETIC" ' ve_AD05_a='ß' ve_AD05_a_symb='ssharp' ve_AD05_a_symbc="$ve_AD05_a_symb" ve_AD05_ma='ẞ' ve_AD05_ma_symb='U1E9E' ve_AD05_ma_symbc='U+1e9e' ve_AD08_ma='ᵈ' ve_AD08_ma_symb='U1D48' ve_AD08_ma_symbc='U+1d48' ve_AD09_ma='ᵉ' ve_AD09_ma_symb='U1D49' ve_AD09_ma_symbc='U+1d49' ve_AD10_ma="${co_mort}˝${co_fmort}" ve_AD10_ma_symb='dead_doubleacute' ve_AD10_ma_symbc="$ve_AD10_ma_symb" ve_AD11_ma='º' ve_AD11_ma_symb='masculine' ve_AD11_ma_symbc="$ve_AD11_ma_symb" ve_AD12="${co_mort}´${co_fmort}" ve_AD12_symb='dead_acute' ve_AD12_symbc="$ve_AD12_symb" ve_AC05_ma="${co_mort}/${co_fmort}" ve_AC05_ma_symb="$as_dead_stroke" ve_AC05_ma_symbc='slash' ve_AC08_ma='ˢ' ve_AC08_ma_symb='U02E2' ve_AC08_ma_symbc='U+02e2' ve_AC09_ma='ʳ' ve_AC09_ma_symb='U02B3' ve_AC09_ma_symbc='U+02b3' ve_AC10_ma='ᵒ' ve_AC10_ma_symb='U1D52' ve_AC10_ma_symbc='U+1d52' ve_BKSL="${co_mort}\`${co_fmort}" ve_BKSL_symb='dead_grave' ve_BKSL_symbc="$ve_BKSL_symb" # En couleurs, la couleur permettra de distinguer le point souscrit # et il sera plus lisible en gros. if $co_couleurs; then ve_AB10_ma="${co_mort}.${co_fmort}" else ve_AB10_ma='․' fi ve_AB10_ma_symb='dead_belowdot' ve_AB10_ma_symbc='U+0323' ;; esac # On adapte suivant la variante. case "$ve_variante" in prog) ve_AE01_ma='→' ve_AE01_ma_symb='U2192' ve_AE01_ma_symbc='U+2192' ve_AE02_ma='⇒' ve_AE02_ma_symb='U21D2' ve_AE02_ma_symbc='U+21d2' ve_AE03='-' ve_AE03_symb='minus' ve_AE03_symbc='minus' ve_AC01_ma='≤' ve_AC01_ma_symb='lessthanequal' ve_AC01_ma_symbc='U+2264' ve_AC04_ma='≥' ve_AC04_ma_symb='greaterthanequal' ve_AC04_ma_symbc='U+2265' ve_AB01_ma_carte="${co_insec}⍽${co_finsec}" ve_AB01_ma='(espace insécable fine)' ve_AB01_ma_symb='U202F' ve_AB01_ma_symbc='U+202f' ve_SPCE_m='␣' ve_SPCE_m_symb='space' ve_SPCE_m_symbc="$ve_SPCE_m_symb" ve_SPCE_ma='⍽' ve_SPCE_ma_symb='nobreakspace' ve_SPCE_ma_symbc="$ve_SPCE_ma_symb" if $ve_large; then ve_SPCE_m_carte=" ${co_insec}Espace insécable${co_finsec}" ve_SPCE_a_carte='_ ' else ve_SPCE_m_carte=" ${co_insec}Esp. insécable${co_finsec}" ve_SPCE_a_carte='_ ' fi ;; typo) [ -n "$ve_guil_ouvr_typo" ] && ve_guil_ouvr="$ve_guil_ouvr_typo" [ -n "$ve_guil_ferm_typo" ] && ve_guil_ferm="$ve_guil_ferm_typo" ve_AE01_ma='‹' ve_AE01_ma_symb='U2039' ve_AE01_ma_symbc='U+2039' ve_AE02_ma='›' ve_AE02_ma_symb='U203A' ve_AE02_ma_symbc='U+203a' ve_AE03='‐' ve_AE03_symb='U2010' ve_AE03_symbc='U+2010' ve_AC01_ma='⩽' ve_AC01_ma_symb='U2A7D' ve_AC01_ma_symbc='U+2a7d' ve_AC04_ma='⩾' ve_AC04_ma_symb='U2A7E' ve_AC04_ma_symbc='U+2a7e' case "$ve_version" in 1.0) ve_AB01_ma_carte='℃' ve_AB01_ma='℃' ve_AB01_ma_symb='U2103' ve_AB01_ma_symbc='U+2103' ;; *) ve_AB01_ma_carte="${co_grise}‐${co_fgrise}" ve_AB01_ma='‐' ve_AB01_ma_symb='hyphen' ve_AB01_ma_symbc="$ve_AB01_ma_symb" ;; esac ve_SPCE_m='(espace insécable fine)' ve_SPCE_m_symb='U202F' ve_SPCE_m_symbc='U+202F' ve_SPCE_ma='⍽' ve_SPCE_ma_symb='nobreakspace' ve_SPCE_ma_symbc="$ve_SPCE_ma_symb" if $ve_large; then ve_SPCE_m_carte="${co_insec}inséc. fine${co_finsec} ${co_insec}Esp. insécable${co_finsec}" ve_SPCE_a_carte=' _ ' else ve_SPCE_m_carte="${co_insec}ins. fine${co_finsec} ${co_insec}insécable${co_finsec} " ve_SPCE_a_carte=' _' fi ;; *) ve_AE01_ma='→' ve_AE01_ma_symb='U2192' ve_AE01_ma_symbc='U+2192' ve_AE02_ma='⇒' ve_AE02_ma_symb='U21D2' ve_AE02_ma_symbc='U+21d2' ve_AE03='-' ve_AE03_symb='minus' ve_AE03_symbc='minus' ve_AC01_ma='≤' ve_AC01_ma_symb='lessthanequal' ve_AC01_ma_symbc="U+2264" ve_AC04_ma='≥' ve_AC04_ma_symb='greaterthanequal' ve_AC04_ma_symbc='U+2265' case "$ve_version" in 1.0) ve_AB01_ma_carte='℃' ve_AB01_ma='℃' ve_AB01_ma_symb='U2103' ve_AB01_ma_symbc='U+2103' ;; *) ve_AB01_ma_carte="${co_grise}‐${co_fgrise}" ve_AB01_ma='‐' ve_AB01_ma_symb='hyphen' ve_AB01_ma_symbc="$ve_AB01_ma_symb" ;; esac ve_SPCE_m='⍽' ve_SPCE_m_symb='nobreakspace' ve_SPCE_m_symbc="$ve_SPCE_m_symb" ve_SPCE_ma='(espace insécable fine)' ve_SPCE_ma_symb='U202F' ve_SPCE_ma_symbc="U+202F" if $ve_large; then ve_SPCE_m_carte="${co_insec}Esp. insécable${co_finsec} ${co_insec}inséc. fine${co_finsec}" ve_SPCE_a_carte=' _' else ve_SPCE_m_carte="${co_insec}insécable${co_finsec} ${co_insec}ins. fine${co_finsec} " ve_SPCE_a_carte=' _' fi ;; esac # On adapte suivant la position d’AltGr à gauche. if $ve_altgr_sur_win; then ve_t_incl_altgr='lwin ralt' ve_LWIN_def='"ONE_LEVEL" , [ ISO_Level3_Shift ]'; ve_LALT_def='"TWO_LEVEL" , [ Alt_L, Meta_L ]'; ve_Mod1=''; ve_Mod5=''; ve_LWIN_symbc='AltGr'; ve_LALT_symbc='Alt'; ve_TLDE=' ' ve_LWIN='AltGr' ve_LALT=' Alt ' else ve_t_incl_altgr='alt' ve_LWIN_def='"TWO_LEVEL" , [ Alt_L, Meta_L ]'; ve_LALT_def='"ONE_LEVEL" , [ ISO_Level3_Shift ]'; ve_Mod1=', '; ve_Mod5=''; ve_LWIN_symbc='Alt'; ve_LALT_symbc='AltGr'; ve_TLDE="${co_grise}Alt${co_fgrise}" if $ve_large; then ve_LWIN=' Alt ' else ve_LWIN='Alt ' fi ve_LALT='AltGr' fi # On adapte suivant si on affiche la carte large ou pas. if $ve_large; then ve_AE00_carte="${co_mort}Comp.${co_fmort}" else ve_AE00_carte="${co_mort}Comp${co_fmort}" fi } # Affichage de la carte sur la sortie standard affiche_carte() { ac_version="$1"; ac_variante="$2"; ac_altgr_sur_win="$3" ac_large="$4"; ac_couleurs="$5"; ac_prefixe="$6" $debug && echo "affiche_carte '$1' '$2' '$3' '$4' '$5' '$6'" >&2 [ -z "$ac_couleurs" ] && ac_couleurs=true # Si printf n’est pas disponible, on se rabat sur la version de base, # affichée par cat. if printf '' > /dev/null 2>&1; then ac_cat=false else ac_cat=true ac_large=false ac_couleurs=false fi # On adapte suivant la version, la variante et les options. version "$ac_version" "$ac_variante" "$ac_altgr_sur_win" '' '' "$ac_large" "$ac_couleurs" "$ac_prefixe" # Avertissement pour la variante typographique if [ "$ac_variante" = "typo" ]; then if $ac_large; then cat <│ , /┃ c @│ t -│ s 0│ r 1│ n 2│ f 3│ ${ve_BKSL} /┃ ┃ ${ac_prefixe}┣━━━━━┳━━┹─┬──┴─┬──┴─┬──┴─┯━─┴─┬──┸─┰──┴─┯━─┴─┬──┴─┬──┴─┬──┴─┲━━┷━━━━┻━━━━┫ ${ac_prefixe}┃ ┃ Ê │ À ${ve_AB01_ma_carte}│ Y ≠│ X •│ : ·│ K ˜┃ ? ‘│ Q ˛│ G ¸│ H ,│ M ${ve_AB10_ma}┃ ┃ ${ac_prefixe}┃ ⇧ ┃ ê *│ à \\│ y {│ x }│ . …│ k ~┃ ’ ¿│ q [│ g ]│ h ^│ m \$┃ ⇧ ┃ ${ac_prefixe}┣━━━━━┻┳━━━┷━━┳━┷━━━━┷┱───┴────┴────┸────┴───┲┷━━━━┷━┳━━┷━━━┳┻━━━━━┳━━━━━━┫ ${ac_prefixe}┃ ┃ ┃ ┃ ${ve_SPCE_m_carte}┃ ┃ WinD ┃ Menu ┃ ┃ ${ac_prefixe}┃ Ctrl ┃ ${ve_LWIN}┃ ${ve_LALT} ┃ Espace ${ve_SPCE_a_carte} ┃ AltGr ┃ Menu ┃ WinG ┃ Ctrl ┃ ${ac_prefixe}┗━━━━━━┻━━━━━━┻━━━━━━━┹──────────────────────┺━━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛ ${ac_legende} CARTE_BASIQUE # Si la carte choisie est la large, on l’affiche. elif $ac_large; then printf \ "${co_fond}${co_ecr}${ac_prefixe}┏━━━━━┱─────┬─────┬─────┬─────┬─────┬─────┰─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━┓ ${ac_prefixe}┃ ${ve_TLDE} ┃ § ${ve_AE01_ma} │ W ${ve_AE02_ma} │ « ${ve_AE03_ma} │ » ${ve_AE04_ma} │ “ ${ve_AE05_ma} │ ” Þ ┃ Ù ${ve_AE07_ma} │ Ç ° │ – ′ │ — ″ │ ${co_mort}µ${co_fmort} "${co_mort}˙${co_fmort}" │ ‰ ${ve_AE12_ma} ┃ ┃ ${ac_prefixe}┃${ve_AE00_carte}┃ # ${ve_AE01_a} │ w ${ve_AE02_a} │ ${ve_AE03} ${ve_AE03_a} │ ' ${ve_AE04_a} │ \" ${ve_AE05_a} │ \` þ ┃ ù ŭ │ ç 8 │ ( 9 │ ) , │ ${co_mort}¨${co_fmort} . │ %% = ┃ ⌫ ┃ ${ac_prefixe}┣━━━━━┻━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┰──┸──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┺━━┳━━━━━━┫ ${ac_prefixe}┃ ⇤ ┃ B ${ve_AD01_ma} │ É ${ve_AD02_ma} │ O Œ │ P ${ve_AD04_ma} │ È ${ve_AD05_ma} ┃ ! ${co_mort}ˇ${co_fmort} │ V ± │ D ${ve_AD08_ma} │ L ${ve_AD09_ma} │ J ${ve_AD10_ma} │ Z ${ve_AD11_ma} │ × † ┃ ┃ ${ac_prefixe}┃ ⇥ ┃ b | │ é ${ve_AD02_a} │ o œ │ p & │ è ${ve_AD05_a} ┃ ${co_mort}ˆ${co_fmort} ¡ │ v + │ d 4 │ l 5 │ j 6 │ z 7 │ ${ve_AD12} * ┃ ┃ ${ac_prefixe}┣━━━━━━━━┻┱────┴┬────┴┬────┴┬────┴┬────┸┰────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┺┓ ↲ ┃ ${ac_prefixe}┃ Verr. ┃ A ${ve_AC01_ma} │ U ≃ │ E ${co_mort}¤${co_fmort} │ I ${ve_AC04_ma} │ ; ${ve_AC05_ma} ┃ C © │ T – │ S ${ve_AC08_ma} │ R ${ve_AC09_ma} │ N ${ve_AC10_ma} │ F ª │ ÷ ‡ ┃ ┃ ${ac_prefixe}┃ Maj. ┃ a < │ u = │ e € │ i > │ , / ┃ c @ │ t - │ s 0 │ r 1 │ n 2 │ f 3 │ ${ve_BKSL} / ┃ ┃ ${ac_prefixe}┣━━━━━━┳━━┹──┬──┴──┬──┴──┬──┴─╼┯╾─┴──┬──┸──┰──┴─╼┯╾─┴──┬──┴──┬──┴──┬──┴──┲━━┷━━━━━┻━━━━━┫ ${ac_prefixe}┃ ┃ Ê │ À ${ve_AB01_ma_carte} │ Y ≠ │ X • │ : · │ K ${co_mort}˜${co_fmort} ┃ ? ‘ │ Q ${co_mort}˛${co_fmort} │ G ${co_mort}¸${co_fmort} │ H ${co_mort},${co_fmort} │ M ${ve_AB10_ma} ┃ ┃ ${ac_prefixe}┃ ⇧ ┃ ê * │ à \\\\ │ y { │ x } │ . … │ k ~ ┃ ’ ¿ │ q [ │ g ] │ h ^ │ m \$ ┃ ⇧ ┃ ${ac_prefixe}┣━━━━━━┻━┳━━━┷━━━┳━┷━━━━━╅─────┴─────┴─────┸─────┴─────╆━━━━━┷━┳━━━┷━━━┳━┻━━━━━┳━━━━━━━━┫ ${ac_prefixe}┃ ┃ ┃ ┃ ${ve_SPCE_m_carte} ┃ ┃ WinD ┃ Menu ┃ ┃ ${ac_prefixe}┃ Ctrl ┃ ${ve_LWIN} ┃ ${ve_LALT} ┃ Espace ${ve_SPCE_a_carte} ┃ AltGr ┃ Menu ┃ WinG ┃ Ctrl ┃ ${ac_prefixe}┗━━━━━━━━┻━━━━━━━┻━━━━━━━┹─────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┻━━━━━━━━┛ ${ac_legende}${ac_fin}" else # Sinon, on affiche la carte étroite (compatible avec un terminal en 80×25). printf \ "${co_fond}${co_ecr}${ac_prefixe}┏━━━━┱────┬────┬────┬────┬────┬────┰────┬────┬────┬────┬────┬────┲━━━━━━━━┓ ${ac_prefixe}┃${ve_TLDE} ┃ § ${ve_AE01_ma}│ W ${ve_AE02_ma}│ « ${ve_AE03_ma}│ » ${ve_AE04_ma}│ “ ${ve_AE05_ma}│ ” Þ┃ Ù ${ve_AE07_ma}│ Ç °│ – ′│ — ″│ ${co_mort}µ${co_fmort} "${co_mort}˙${co_fmort}"│ ‰ ${ve_AE12_ma}┃ ┃ ${ac_prefixe}┃${ve_AE00_carte}┃ # ${ve_AE01_a}│ w ${ve_AE02_a}│ ${ve_AE03} ${ve_AE03_a}│ ' ${ve_AE04_a}│ \" ${ve_AE05_a}│ \` þ┃ ù ŭ│ ç 8│ ( 9│ ) ,│ ${co_mort}¨${co_fmort} .│ %% =┃ ⌫ ┃ ${ac_prefixe}┣━━━━┻━━┱─┴──┬─┴──┬─┴──┬─┴──┬─┴──┰─┸──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┺━━┳━━━━━┫ ${ac_prefixe}┃ ⇤ ┃ B ${ve_AD01_ma}│ É ${ve_AD02_ma}│ O Œ│ P ${ve_AD04_ma}│ È ${ve_AD05_ma}┃ ! ${co_mort}ˇ${co_fmort}│ V ±│ D ${ve_AD08_ma}│ L ${ve_AD09_ma}│ J ${ve_AD10_ma}│ Z ${ve_AD11_ma}│ × †┃ ┃ ${ac_prefixe}┃ ⇥ ┃ b |│ é ${ve_AD02_a}│ o œ│ p &│ è ${ve_AD05_a}┃ ${co_mort}ˆ${co_fmort} ¡│ v +│ d 4│ l 5│ j 6│ z 7│ ${ve_AD12} *┃ ┃ ${ac_prefixe}┣━━━━━━━┻┱───┴┬───┴┬───┴┬───┴┬───┸┰───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┺┓ ↲ ┃ ${ac_prefixe}┃ Verr. ┃ A ${ve_AC01_ma}│ U ≃│ E ${co_mort}¤${co_fmort}│ I ${ve_AC04_ma}│ ; ${ve_AC05_ma}┃ C ©│ T –│ S ${ve_AC08_ma}│ R ${ve_AC09_ma}│ N ${ve_AC10_ma}│ F ª│ ÷ ‡┃ ┃ ${ac_prefixe}┃ Maj. ┃ a <│ u =│ e €│ i >│ , /┃ c @│ t -│ s 0│ r 1│ n 2│ f 3│ ${ve_BKSL} /┃ ┃ ${ac_prefixe}┣━━━━━┳━━┹─┬──┴─┬──┴─┬──┴─┯━─┴─┬──┸─┰──┴─┯━─┴─┬──┴─┬──┴─┬──┴─┲━━┷━━━━┻━━━━┫ ${ac_prefixe}┃ ┃ Ê │ À ${ve_AB01_ma_carte}│ Y ≠│ X •│ : ·│ K ${co_mort}˜${co_fmort}┃ ? ‘│ Q ${co_mort}˛${co_fmort}│ G ${co_mort}¸${co_fmort}│ H ${co_mort},${co_fmort}│ M ${ve_AB10_ma}┃ ┃ ${ac_prefixe}┃ ⇧ ┃ ê *│ à \\\\│ y {│ x }│ . …│ k ~┃ ’ ¿│ q [│ g ]│ h ^│ m \$┃ ⇧ ┃ ${ac_prefixe}┣━━━━━┻┳━━━┷━━┳━┷━━━━┷┱───┴────┴────┸────┴───┲┷━━━━┷━┳━━┷━━━┳┻━━━━━┳━━━━━━┫ ${ac_prefixe}┃ ┃ ┃ ┃ ${ve_SPCE_m_carte}┃ ┃ WinD ┃ Menu ┃ ┃ ${ac_prefixe}┃ Ctrl ┃ ${ve_LWIN}┃ ${ve_LALT} ┃ Espace ${ve_SPCE_a_carte} ┃ AltGr ┃ Menu ┃ WinG ┃ Ctrl ┃ ${ac_prefixe}┗━━━━━━┻━━━━━━┻━━━━━━━┹──────────────────────┺━━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛ ${ac_legende}${ac_fin}" fi # Valeur de retour OK return 0 } # Affichage de l’usage usage() { us_version="$1"; us_variante="$2"; us_altgr_sur_win="$3"; us_large="$4" us_couleurs="$5" cat <<'DEBUT_USAGE' Disposition de clavier Béop http://beop.free.fr/ DEBUT_USAGE affiche_carte "$us_version" "$us_variante" "$us_altgr_sur_win" "$us_large" "$us_couleurs" cat <<'FIN_USAGE' La disposition Béop dérive de la disposition Bépo (voir http://bepo.fr/). Tout comme elle, cette disposition est placée sous double licence GFDL et CC-BY-SA. Ce script en tant que tel est fourni sans aucune garantie et placé sous la licence GPL version 2 ou ultérieure. Il permet de changer dynamiquement la disposition du clavier sous X.org depuis la session de l’utilisateur ou sous la console texte Linux. Depuis le compte root ou avec sudo, il permet d’installer la disposition sur le système. Sans arguments, – s’il est lancé sous le nom "azerty" ou "auei", il rétablit la disposition Azerty. – s’il se se termine par _switch ou contient _switch_, il bascule entre les dispositions Azerty et Béop. – s’il contient _install(_*), il installe la disposition Béop sur le système. Par défaut, il charge la disposition Béop (s’il contient _1.0(_*) la version 1.0, sinon la version 1.1 ; s’il contient _prog(_*), la variante programmation ; s’il contient _typo(_*), la variante typographie). Il est conseillé de créer des liens symboliques dessus nommés qsdf et auei, afin de pouvoir basculer entre les dispositions Béop et Azerty simplement en entrant la commande formée par les touches de la position de repos de la main gauche. Ce script supporte les arguments suivants (prioritaires sur le nom) : -h ou --help : affichage de cette aide --carte : affichage de la carte de la disposition (en couleur si possible) -a ou --azerty : passage en Azerty -b ou --beop : passage en Béop (action par défaut) -1.0 : version 1.0 de la disposition -1.1 : version 1.1 (par défaut) -pr ou --prog : variante destinée à la programmation (en mode chargement immédiat ; en mode installation, les deux versions sont systématiquement installées) -ty ou --typo : variante pour une meilleure typographie (mais moins bien supportée par certains logiciels) -s ou --switch : passage en Béop si l’on est en Azerty et vice-versa --installe : installation de la disposition Béop sur le système --installerep rep : installation sur un système monté sur le répertoire rep --desinstalle : désinstallation de la disposition Béop du système (par restauration des fichiers d’origine) ATTENTION : si vous avez modifié des fichiers où la disposition Béop a été installée ou déclarée, vos modifications seront perdues ! --desinstallerep rep : désinstallation d’un système monté sur le répertoire rep --reinstalle : désinstallation puis réinstallation de la disposition Béop sur le système --reinstallerep rep : réinstallation sur un système monté sur le répertoire rep Prérequis : bash ou un autre shell POSIX, grep -E ou egrep, et – pour X.org : xkbcomp, setxkbmap, awk (pour l’installation), – pour la console, loadkeys et dumpkeys. FIN_USAGE } # Fonctions de traitement de chaînes en shell POSIX # Permettent d’éviter de lancer des commandes externes pour s’affranchir des # dépendances. # Test d’inclusion d’une chaîne dans une autre chaine_incluse() { # Paramètres : 'sous-chaîne' 'chaîne' # Utiliser une commande interne pour le test évite de plomber le temps # d’exécution en cas d’appel de la fonction dans une boucle. case "$2" in *$1*) return 0 ;; *) return 1 ;; esac } # Remplacement d’une sous-chaîne par une nouvelle remplace_chaine() { # Paramètres : nom_variable_chaine 'ancienne sous-chaîne' 'nouvelle' #local __rc_chaine # On déréférence la chaîne eval __rc_chaine="\"\$$1\"" # Si la chaîne n’est pas incluse, on retourne faux (important pour la # fonction de remplacement multiple). chaine_incluse "$2" "$__rc_chaine" || return 1 # Remplacement de la première occurrence avec les moyens du bord en shell # POSIX. __rc_chaine="${__rc_chaine%%$2*}$3${__rc_chaine#*$2}" eval $1="'$__rc_chaine'" # On récupère la variable interne (certains shells ne permettent pas les # variables locales). unset __rc_chaine # On retourne vrai explicitement (important pour la fonction de remplacement # multiple). return 0 } # Remplacement multiple d’une sous-chaîne par une nouvelle # Fonction à usage interne uniquement : si l’ancienne sous-chaîne était # incluse dans la nouvelle, la fonction bouclerait ! __remplace_multiple_chaine() { # Paramètres : nom_variable_chaine 'ancienne sous-chaîne' 'nouvelle' # On remplace la sous-chaîne tant qu’on peut. while remplace_chaine "$1" "$2" "$3"; do true done } # Remplacement multiple d’une sous-chaîne par une nouvelle remplace_multiple_chaine() { # Paramètres : nom_variable_chaine 'ancienne sous-chaîne' 'nouvelle' # Si l’ancienne chaîne est incluse dans la nouvelle, c’est problématique. if chaine_incluse "$2" "$3"; then # On utilise une chaîne intermédiaire improbable pour éviter de boucler, # après avoir vérifié que l’ancienne sous-chaîne n’y est pas incluse. if chaine_incluse "$2" '%w_7Z.y/U^'; then # Sinon, on en utilise une autre sans caractère commun. __remplace_multiple_chaine "$1" "$2" '6K=Dz,<+Y@' __remplace_multiple_chaine "$1" '6K=Dz,<+Y@' "$3" else __remplace_multiple_chaine "$1" "$2" '%w_7Z.y/U^' __remplace_multiple_chaine "$1" '%w_7Z.y/U^' "$3" fi else # Dans le cas normal, on fait le remplacement directement. __remplace_multiple_chaine "$1" "$2" "$3" fi } # Ajout de la disposition Béop à un fichier (attendu en paramètre) cat_beop() { cb_nom_fich="$1"; cb_version="$2"; cb_variante="$3"; cb_altgr_sur_win="$4" cb_mode_install="$5"; cb_mode_principale="$6" # Il sera utile par la suite de pouvoir distinguer si la fonction a été # appelée pour un chargement à la volée de la disposition ou pour son # installation, et si elle est installée comme variante ou disposition # principale. cb_guillemets_avec_espaces_norm="$7"; cb_guillemets_avec_espaces_typo="$8" $debug && echo "cat_beop '$1' '$2' '$3' '$4' '$5' '$6' '$7' '$8'" >&2 # On ajoute la définition de la disposition Béop au fichier passé en paramètre. # Prise en charge du mode installation if $cb_mode_install; then # En mode installation, on installe systématiquement les trois versions, # on ne modifie pas celle de base. cb_variante="norm" # On ajoute le commentaire cat >> "$cb_nom_fich" <> "$cb_nom_fich" # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret # Si chaque disposition est installée comme disposition à part entière # (anciennes versions de X), la disposition est celle par défaut. if $cb_mode_principale; then cb_default='default ' else cb_default='' fi # En mode installation, la définition se présente comme une redéfinition # partielle par rapport à la définition basique du clavier. cat >> "$cb_nom_fich" <> "$cb_nom_fich" < /dev/null 2>&1; then cb_include_base='pc/pc(pc105)' else cb_include_base='pc(pc105)' fi cat >> "$cb_nom_fich" < /dev/null` if [ -n "$cb_inet" ]; then cb_inet="inet(${cb_inet#*inet(}" cb_inet="${cb_inet%%)*})" cat >> "$cb_nom_fich" < /dev/null 2>&1; then cat >> "$cb_nom_fich" < /dev/null 2>&1; then cat >> "$cb_nom_fich" <> "$cb_nom_fich" < { repeat = no, type = "ONE_LEVEL" , [ Multi_key ] }; // Compose key { type = "FOUR_LEVEL" , [ numbersign, section, $ve_AE01_a_symb, $ve_AE01_ma_symb ] }; // # § $ve_AE01_a $ve_AE01_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ w, W, $ve_AE02_a_symb, $ve_AE02_ma_symb ] }; // w W $ve_AE02_a $ve_AE02_ma key { type = "FOUR_LEVEL" , [ $ve_AE03_symb, $ve_guil_ouvr, $ve_AE03_a_symb, $ve_AE03_ma_symb ] }; // ${ve_AE03} « $ve_AE03_a $ve_AE03_ma key { type = "FOUR_LEVEL" , [ apostrophe, $ve_guil_ferm, $ve_AE04_a_symb, $ve_AE04_ma_symb ] }; // ' » $ve_AE04_a $ve_AE04_ma key { type = "FOUR_LEVEL" , [ quotedbl , leftdoublequotemark, $ve_AE05_a_symb, $ve_AE05_ma_symb ] }; // " “ $ve_AE05_a $ve_AE05_ma key { type = "FOUR_LEVEL" , [ grave, rightdoublequotemark, thorn, THORN ] }; // \` ” þ Þ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ ugrave, Ugrave, ubreve, $ve_AE07_ma_symb ] }; // ù Ù ŭ $ve_AE07_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ ccedilla, Ccedilla, 8, degree ] }; // ç Ç 8 ° key { type = "FOUR_LEVEL" , [ parenleft, endash, 9, minutes ] }; // ( – 9 ′ key { type = "FOUR_LEVEL" , [ parenright, emdash, comma, seconds ] }; // ) — , ″ key { type = "FOUR_LEVEL" , [ dead_diaeresis, $as_dead_greek, period, dead_abovedot ] }; // ¨ µ . ˙ key { type = "FOUR_LEVEL" , [ percent, U2030, equal, $ve_AE12_ma_symb ] }; // % ‰ = $ve_AE12_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ b, B, bar, $ve_AD01_ma_symb ] }; // b B | $ve_AD01_ma key { type = $ve_AD02_type, [ eacute, Eacute, $ve_AD02_a_symb, $ve_AD02_ma_symb ] }; // é É $ve_AD02_a $ve_AD02_ma key { type = "FOUR_LEVEL_ALPHABETIC" , [ o, O, oe, OE ] }; // o O œ Œ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ p, P, ampersand, $ve_AD04_ma_symb ] }; // p P & $ve_AD04_ma key { type = $ve_AD05_type, [ egrave, Egrave, $ve_AD05_a_symb, $ve_AD05_ma_symb ] }; // è È $ve_AD05_a $ve_AD05_ma key { type = "FOUR_LEVEL" , [ dead_circumflex, exclam, exclamdown, dead_caron ] }; // ^ ! ¡ ˇ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ v, V, plus, plusminus ] }; // v V + ± key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ d, D, 4, $ve_AD08_ma_symb ] }; // d D 4 $ve_AD08_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ l, L, 5, $ve_AD09_ma_symb ] }; // l L 5 $ve_AD09_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ j, J, 6, $ve_AD10_ma_symb ] }; // j J 6 $ve_AD10_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ z, Z, 7, $ve_AD11_ma_symb ] }; // z Z 7 $ve_AD11_ma key { type = "FOUR_LEVEL" , [ $ve_AD12_symb, multiply, asterisk, dagger ] }; // $ve_AD12 × * † key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ a, A, less, $ve_AC01_ma_symb ] }; // a A < $ve_AC01_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ u, U, equal, U2243 ] }; // u U = ≃ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ e, E, EuroSign, $as_dead_currency ] }; // e E € ¤ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ i, I, greater, $ve_AC04_ma_symb ] }; // i I > $ve_AC04_ma key { type = "FOUR_LEVEL" , [ comma, semicolon, slash, $ve_AC05_ma_symb ] }; // , ; / $ve_AC05_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ c, C, at, copyright ] }; // c C @ © key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ t, T, minus, U2212 ] }; // t T - − key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ s, S, 0, $ve_AC08_ma_symb ] }; // s S 0 $ve_AC08_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ r, R, 1, $ve_AC09_ma_symb ] }; // r R 1 $ve_AC09_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ n, N, 2, $ve_AC10_ma_symb ] }; // n N 2 $ve_AC10_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ f, F, 3, ordfeminine ] }; // f F 3 ª key { type = "FOUR_LEVEL" , [ $ve_BKSL_symb, division, slash, doubledagger ] }; // $ve_BKSL ÷ / ‡ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ ecircumflex, Ecircumflex, asterisk, U262D ] }; // ê Ê * key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ agrave, Agrave, backslash, $ve_AB01_ma_symb ] }; // à À \\ $ve_AB01_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ y, Y, braceleft, notequal ] }; // y Y { ≠ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ x, X, braceright, U2022 ] }; // x X } • key { type = "FOUR_LEVEL" , [ period, colon, ellipsis, periodcentered ] }; // . : … · key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ k, K, asciitilde, dead_tilde ] }; // k K ~ ˜ key { type = "FOUR_LEVEL" , [ rightsinglequotemark, question, questiondown, leftsinglequotemark ] }; // ’ ? ¿ ‘ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ q, Q, bracketleft, dead_ogonek ] }; // q Q [ ˛ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ g, G, bracketright, dead_cedilla ] }; // g G ] ¸ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ h, H, asciicircum, $as_dead_belowcomma ] }; // h H ^ , key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ m, M, dollar, $ve_AB10_ma_symb ] }; // m M \$ $ve_AB10_ma key { type = "THREE_LEVEL" , [ dead_tilde, dead_tilde, U26BD ] }; // ˜ ˜ (touche spécifique aux claviers brésiliens) key { type = $ve_LWIN_def }; key { type = $ve_LALT_def }; key { type = "FOUR_LEVEL" , [ space, $ve_SPCE_m_symb, underscore, $ve_SPCE_ma_symb ] }; // ␣ $ve_SPCE_m _ $ve_SPCE_ma key { type = "ONE_LEVEL" , [ ISO_Level3_Shift ] }; key { type = "TWO_LEVEL" , [ Menu, Super_R ] }; key { type = "TWO_LEVEL" , [ Super_L, Menu ] }; DISPO_7 # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret # Si l’option --multimedia_pause est active, on définit le mode muet sur # pause. if $multimedia_pause; then cat >> "$cb_nom_fich" < { type = "THREE_LEVEL" , [ XF86AudioMute, Break, Pause ] }; DISPO_8 # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret fi # Si l’option --multimedia_curseur est active, on définit des actions # en AltGr sur les touches curseur. if $multimedia_curseur; then cat >> "$cb_nom_fich" < { type = "THREE_LEVEL" , [ Up, Up, XF86AudioRaiseVolume ] }; key { type = "THREE_LEVEL" , [ Left, Left, XF86Back ] }; key { type = "THREE_LEVEL" , [ Right, Right, XF86Forward ] }; key { type = "THREE_LEVEL" , [ Down, Down, XF86AudioLowerVolume ] }; DISPO_9 # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret fi # En chargement dynamique, on définit tout de même les touches de base, par # précaution. if ! $cb_mode_install; then cat >> "$cb_nom_fich" < { type = "TWO_LEVEL" , [ Tab, ISO_Left_Tab ] }; key { type = "ONE_LEVEL" , [ Return ] }; key { type = "ONE_LEVEL" , [ Caps_Lock ] }; key { type = "ONE_LEVEL" , [ Shift_L ] }; key { type = "ONE_LEVEL" , [ Shift_R ] }; key { type = "ONE_LEVEL" , [ Control_L ] }; key { type = "ONE_LEVEL" , [ Control_R ] }; modifier_map Shift { , }; modifier_map Control { , }; DISPO_10 # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret fi # Pour finir, on définit les modificatrices spécifiques au Béop. cat >> "$cb_nom_fich" < }; }; FIN_DISPO # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret # Si l’on est en chargement dynamique, on a fini. $cb_mode_install || return 0 # Installation des variantes (traitements communs) # On détermine le préfixe éventuel pour l’inclusion de la disposition de # base. cb_prefixe_inclusion='' chaine_incluse '/pc/' "$cb_nom_fich" && cb_prefixe_inclusion='pc/' # Installation de la variante programmation # Adaptation selon si chaque disposition est installée comme disposition à # part entière (anciennes versions de X)… if $cb_mode_principale; then cb_nom_variante='fr-beop_prog' cb_inclusion="${cb_prefixe_inclusion}fr-beop" cb_nom_fich_pr="${cb_nom_fich}_prog" # … ou comme variante pour une langue (versions récentes de X) else cb_nom_variante='beop_prog' cb_inclusion="${cb_prefixe_inclusion}fr(beop)" cb_nom_fich_pr="$cb_nom_fich" fi # On ajoute le commentaire. cat >> "$cb_nom_fich_pr" <> "$cb_nom_fich_pr" # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret # On ajoute la disposition. cat >> "$cb_nom_fich_pr" < { type = "FOUR_LEVEL" , [ quotedbl , leftdoublequotemark, $ve_AE05_a_symb, $ve_AE05_ma_symb ] }; // " “ $ve_AE05_a $ve_AE05_ma key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ agrave, Agrave, backslash, U202F ] }; // à À \\ (espace insécable fine) key { type = "FOUR_LEVEL" , [ space, space, underscore, nobreakspace ] }; // ␣ ␣ _ ⍽ }; FIN_BEOP_PROG # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret # Installation de la variante typographique # Adaptation selon si chaque disposition est installée comme disposition à # part entière (anciennes versions de X)… if $cb_mode_principale; then cb_nom_variante='fr-beop_typo' cb_inclusion="${cb_prefixe_inclusion}fr-beop" cb_nom_fich_ty="${cb_nom_fich}_typo" # … ou comme variante pour une langue (versions récentes de X) else cb_nom_variante='beop_typo' cb_inclusion="${cb_prefixe_inclusion}fr(beop)" cb_nom_fich_ty="$cb_nom_fich" fi # On ajoute le commentaire. cat >> "$cb_nom_fich_ty" <> "$cb_nom_fich_ty" # Si l’écriture a échoué, on retourne une erreur. cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret # On ajoute le début de la disposition et les premières touches modifiées. cat >> "$cb_nom_fich_ty" < { type = "FOUR_LEVEL" , [ numbersign, section, $ve_AE01_a_symb, U2039 ] }; // # § $ve_AE01_a ‹ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ w, W, $ve_AE02_a_symb, U203A ] }; // w W $ve_AE02_a › key { type = "FOUR_LEVEL" , [ U2010, $ve_guil_ouvr_typo, $ve_AE03_a_symb, $ve_AE03_ma_symb ] }; // ‐ « $ve_AE03_a $ve_AE03_ma BEOP_TYPO_1 cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret # Selon l’option de guillemets avec espace, on redéfinit la touche # éventuellement concernée. if $cb_guillemets_avec_espaces_typo || $cb_guillemets_avec_espaces_norm; then cat >> "$cb_nom_fich_ty" < { type = "FOUR_LEVEL" , [ apostrophe, $ve_guil_ferm_typo, $ve_AE04_a_symb, $ve_AE04_ma_symb ] }; // ' » $ve_AE04_a $ve_AE04_ma BEOP_TYPO_2 cb_val_ret=$? [ $cb_val_ret -ne 0 ] && return $cb_val_ret fi # On ajoute les autres touches modifiées. cat >> "$cb_nom_fich_ty" < { type = "FOUR_LEVEL_SEMIALPHABETIC", [ a, A, less, U2A7D ] }; // a A < ⩽ key { type = "FOUR_LEVEL_SEMIALPHABETIC", [ i, I, greater, U2A7E ] }; // i I > ⩾ key { type = "FOUR_LEVEL" , [ space, U202F, underscore, nobreakspace ] }; // ␣ (espace insécable fine) _ ⍽ }; FIN_BEOP_TYPO } # Passage en Béop beop() { be_version="$1"; be_variante="$2"; be_altgr_sur_win="$3" be_guillemets_avec_espaces_norm="$4"; be_guillemets_avec_espaces_typo="$5" # Lancer setxkbmap -print alors qu’on a modifié la disposition avec xkbcomp # semble parfois causer des problèmes,donc si on est déjà en Béop, on essaie # de restaurer l’Azerty avant. xkbcomp -xkb -o - $DISPLAY | $egrep '^xkb_symbols.*beop' > /dev/null && setxkbmap fr # Vérification qu’on peut récupérer les paramètres actuels setxkbmap -print > /dev/null 2>&1 be_val_ret=$? if [ $be_val_ret -ne 0 ]; then echo "Impossible de récupérer les paramètres actuels avec setxkbmap -print"; echo return $be_val_ret fi # Fichier temporaire pour créer la définition Xkb be_temp_fich="/tmp/$(basename $0).$$.xkb" # On récupère les réglages actuels (hormis la disposition). setxkbmap -print | $egrep 'xkb_(keymap|keycodes|types|compat|geometry)' > $be_temp_fich be_val_ret=$? if [ $be_val_ret -ne 0 ]; then echo "Échec de création du fichier temporaire $be_temp_fich"; echo exit $be_val_ret fi # On les complète avec la disposition Béop… cat_beop "$be_temp_fich" "$be_version" "$be_variante" "$be_altgr_sur_win" false false "$be_guillemets_avec_espaces_norm" "$be_guillemets_avec_espaces_typo" be_val_ret=$? if [ $be_val_ret -ne 0 ]; then echo "Échec d'écriture dans le fichier temporaire $be_temp_fich"; echo exit $be_val_ret fi # … et l’accolade fermante. cat >> $be_temp_fich < "$cbc_nom_fich" < /dev/null 2>&1 cob_val_ret=$? # Suivant le code de retour, on affiche le message approprié. if [ $cob_val_ret -eq 0 ]; then echo 'Disposition Béop chargée sur les consoles texte' else echo 'Échec du chargement de la disposition Béop sur les consoles texte' fi rm $cob_temp_fich return $cob_val_ret } # Passage en Azerty des consoles texte console_azerty() { # Tant qu’à faire, on essaie de mettre la meilleure version d’abord. loadkeys fr-latin9 > /dev/null 2>&1 || loadkeys fr > /dev/null 2>&1 ca_val_ret=$? if [ $ca_val_ret -eq 0 ]; then echo 'Disposition Azerty chargée sur les consoles texte' else echo 'Échec du rétablissement de la disposition Azerty sur les consoles texte' fi return $ca_val_ret } # Insertion de texte avant une ligne contenant un repère insere_texte_avant() { ita_nom_fich_entree="$1"; ita_nom_fich_sortie="$2"; ita_repere="$3"; ita_ajout="$4" # On intercale le Béop avec awk ou sed, ou une boucle en shell pour limiter # les dépendances (mais ils ne permettent pas de vérifier si le fichier a # bien la structure attendue…). ### Pour test, décommenter à ajuster la variable suivante : #commande_insertion='read' if [ "$commande_insertion" = "awk" ]; then remplace_multiple_chaine ita_repere '/' '\/' remplace_multiple_chaine ita_ajout '"' '\"' awk "/$ita_repere/ { print \"$ita_ajout\" } { print }" "$ita_nom_fich_entree" > "$ita_nom_fich_sortie" ita_val_ret=$? elif [ "$commande_insertion" = "sed" ]; then remplace_multiple_chaine ita_repere '~' '\~' remplace_multiple_chaine ita_ajout '~' '\~' sed -e "s~^\(.*$ita_repere\)~$ita_ajout\n\1~" < "$ita_nom_fich_entree" > "$ita_nom_fich_sortie" ita_val_ret=$? else # Solution pas dépendante d’awk ou sed… mais de read -r ( IFS=''; while read -r ita_ligne || [ -n "$ita_ligne" ]; do # La construction read ita_ligne || [ -n "$ita_ligne" ] permet de ne pas # rater la dernière ligne si elle ne se termine pas par une fin # de ligne comme elle devrait (et c’est le cas avec certaines # versions de XKB). chaine_incluse "$ita_repere" "$ita_ligne" && printf "$ita_ajout\n" echo "$ita_ligne" done < "$ita_nom_fich_entree" > "$ita_nom_fich_sortie" ) ita_val_ret=$? fi return $ita_val_ret } # Ajout de la disposition sous X.org installe_beop_X() { ibx_version="$1"; ibx_altgr_sur_win="$2" ibx_guillemets_avec_espaces_norm="$3"; ibx_guillemets_avec_espaces_typo="$4" $debug && echo "installe_beop_X '$1' '$2' '$3' '$4'" >&2 # Si le fichier n’a pas été déterminé, l’installation est impossible. if [ -z "$as_fich_X" ]; then echo "Pas d’installation pour X.org : répertoire xkb non trouvé"; echo return 1 fi # On ajoute la définition de la disposition Béop uniquement si elle n’est # pas déjà présente. if grep 'xkb_symbols "beop"' "$as_fich_X" > /dev/null 2>&1; then echo; echo "Disposition Béop déjà ajoutée au fichier $as_fich_X ;" echo "pas de modification." else if ! $as_fich_X_separe; then echo; echo "Sauvegarde du fichier $as_fich_X d'origine en" echo " $as_fich_X.sans_beop" cp -pf "$as_fich_X" "$as_fich_X.sans_beop" ibx_val_ret=$? if [ $ibx_val_ret -ne 0 ]; then echo "Échec !" echo "Assurez-vous de lancer la commande en tant que root" echo "et qu'il reste de la place sur le disque."; echo exit $ibx_val_ret fi fi echo; echo "Ajout de la disposition Béop au fichier $as_fich_X" if ! $as_fich_X_separe; then cat >> "$as_fich_X" <<'FIN_ESPACE' FIN_ESPACE fi # Ajout de la disposition au fichier cat_beop "$as_fich_X" "$ibx_version" "norm" "$ibx_altgr_sur_win" true "$as_fich_X_separe" "$ibx_guillemets_avec_espaces_norm" "$ibx_guillemets_avec_espaces_typo" ibx_val_ret=$? if [ $ibx_val_ret -ne 0 ]; then echo "Échec !" echo "Assurez-vous de lancer la commande en tant que root" echo "et qu'il reste de la place sur le disque."; echo exit $ibx_val_ret fi fi # Vérification de la disponibilité d’une commande pour l’insertion if echo | awk ''; then commande_insertion='awk' elif echo a | sed 's/a/b\nc/' | grep '^b$' > /dev/null 2>&1; then commande_insertion='sed' elif echo | read -r ibx_ligne 2>/dev/null; then commande_insertion='while_read' else echo; echo "ERREUR !" echo "awk ou une version de sed supportant \n ou read -r est nécessaire pour la" echo "déclaration de la disposition."; echo return 1 fi # Déclaration de la disposition dans base.lst, evdev.xml, evdev.lst et # base.xml. for ibx_fich in base.lst evdev.xml evdev.lst base.xml xorg.lst xorg.xml; do # Si le fichier n’existe pas ou que c’est juste un lien (auquel cas le # fichier désigné est normalement aussi dans la liste), on passe. [ -f "$as_rep_rules/$ibx_fich" ] || continue [ -L "$as_rep_rules/$ibx_fich" ] && continue # Si la disposition est déjà déclarée, on ne fait rien. if grep beop "$as_rep_rules/$ibx_fich" > /dev/null 2>&1; then echo; echo "Disposition Béop déjà déclarée dans $as_rep_rules/$ibx_fich ;" echo "pas de modification." continue fi # On sauvegarde la version actuelle du fichier. echo; echo "Sauvegarde du fichier $as_rep_rules/$ibx_fich d'origine en" echo " $as_rep_rules/$ibx_fich.sans_beop" cp -pf "$as_rep_rules/$ibx_fich" "$as_rep_rules/$ibx_fich.sans_beop" ibx_val_ret=$? if [ $ibx_val_ret -ne 0 ]; then echo "Échec !" echo "Assurez-vous de lancer la commande en tant que root" echo "et qu'il reste de la place sur le disque."; echo exit $ibx_val_ret fi # On ajoute la déclaration du Bépo. echo; echo "Déclaration de la disposition Béop dans $as_rep_rules/$ibx_fich" # Traitement des fichiers XML if chaine_incluse '.xml' "$ibx_fich"; then # Dans les versions récentes de X.org, les dispositions sont # considérées comme des variantes pour un pays. if ! $as_fich_X_separe; then # Si le Bépo apparaît, on l’utilise comme repère, if grep 'bepo' "$as_rep_rules/$ibx_fich" > /dev/null 2>&1; then ibx_repere='bepo' # sinon on utilise la variante latin9 de l’Azerty. else ibx_repere='latin9' fi insere_texte_avant "$as_rep_rules/$ibx_fich.sans_beop" "$as_rep_rules/$ibx_fich" "$ibx_repere" ' beop\n Français (Béop, ergonomique, dérivée plus radicale de Bépo)\n \n \n \n \n beop_prog\n Français (Béop, ergonomique, variante pour la programmation)\n \n \n \n \n beop_typo\n Français (Béop, ergonomique, variante pour une meilleure typographie)\n \n \n \n ' ibx_val_ret=$? # Dans les anciennes versions de X.org, les dispositions étaient # considérées comme des dispositions à part entière. else insere_texte_avant "$as_rep_rules/$ibx_fich.sans_beop" "$as_rep_rules/$ibx_fich" "fr-latin9" " fr-beop\n Français (Béop, ergonomique, dérivée plus radicale de Bépo)\n \n \n \n \n fr-beop_prog\n Français (Béop, ergonomique, variante pour la programmation)\n \n \n \n \n fr-beop_typo\n Français (Béop, ergonomique, variante pour une meilleure typographie)\n \n \n \n " ibx_val_ret=$? fi # Traitement des fichiers lst else # Versions récentes de X.org (variante) if ! $as_fich_X_separe; then if grep bepo "$as_rep_rules/$ibx_fich" > /dev/null 2>&1; then ibx_repere='bepo ' else ibx_repere='latin9 ' fi insere_texte_avant "$as_rep_rules/$ibx_fich.sans_beop" "$as_rep_rules/$ibx_fich" "$ibx_repere" " beop fr: Français (Béop, ergonomique, dérivée plus radicale de Bépo)\n beop_prog fr: Français (Béop, ergonomique, variante pour la programmation)\n beop_typo fr: Français (Béop, ergonomique, variante pour une meilleure typographie)" ibx_val_ret=$? # Versions anciennes (disposition séparée) else insere_texte_avant "$as_rep_rules/$ibx_fich.sans_beop" "$as_rep_rules/$ibx_fich" 'fr-latin9' " fr-beop\tFrench (ergonomic)\n fr-beop_prog\tFrench (ergonomic)\n fr-beop_typo\tFrench (ergonomic)" ibx_val_ret=$? fi fi # On indique une éventuelle erreur. if [ $ibx_val_ret -ne 0 ]; then mv -f "$as_rep_rules/$ibx_fich.sans_beop" "$as_rep_rules/$ibx_fich" echo "Échec !" echo "Assurez-vous de lancer la commande en tant que root" echo "et qu'il reste de la place sur le disque." echo "Il est possible aussi que le fichier $as_rep_rules/$ibx_fich présente un cas non prévu par ce script." fi done return $ibx_val_ret } # Ajout de la disposition pour la console installe_beop_console() { ibc_version="$1"; ibc_altgr_sur_win="$2" # On détermine le répertoire d’installation. ibc_keymaps='' for ibc_rep in "$rep_install/usr/share/kbd/keymaps" "$rep_install/usr/share/keymaps" "$rep_install/usr/lib/kbd/keymaps" "$rep_install/lib/kbd/keymaps"; do if [ -d "$ibc_rep" ]; then ibc_keymaps="$ibc_rep" break fi done # En cas d’échec, on sort. [ -z "$ibc_keymaps" ] && return 0 # Si le répertoire est vide aussi. for ibc_i in "$ibc_keymaps"/*; do break done [ "$ibc_i" = "$ibc_keymaps/*" ] && return 0 # Détermination du sous-répertoire approprié if [ -d "$ibc_keymaps/xkb" ]; then ibc_keymaps="$ibc_keymaps/xkb" elif [ -d "$ibc_keymaps/i386" ]; then ibc_keymaps="$ibc_keymaps/i386/beop" fi # Si nécessaire, création du sous-répertoire [ -d $ibc_keymaps ] || mkdir -p $ibc_keymaps # Vérification que la dispositon n’est pas déjà installée if [ -e "$ibc_keymaps/fr-beop.map" ] || [ -e "$ibc_keymaps/fr-beop.map.gz" ]; then echo; echo "Disposition Béop déjà installée pour la console ;" echo "pas de modification."; echo ibc_val_ret_base=0 # Sinon, installation else cat_beop_cons "$ibc_keymaps/fr-beop.map" "$ibc_version" "norm" "$ibc_altgr_sur_win" ibc_val_ret_base=$? echo; echo "Disposition Béop installée pour la console dans $ibc_keymaps/fr-beop.map."; echo fi # Vérification que la variante programmation n’est pas déjà installée if [ -e "$ibc_keymaps/fr-beop_prog.map" ] || [ -e "$ibc_keymaps/fr-beop_prog.map.gz" ]; then echo "Disposition Béop (variante programmation) déjà installée pour la console ;" echo "pas de modification."; echo ibc_val_ret_prog=0 # Sinon, installation else cat_beop_cons "$ibc_keymaps/fr-beop_prog.map" "$ibc_version" "prog" "$ibc_altgr_sur_win" ibc_val_ret_prog=$? echo "Disposition Béop (variante programmation) installée pour la console dans" echo "$ibc_keymaps/fr-beop_prog.map."; echo fi # Vérification que la variante typographique n’est pas déjà installée if [ -e "$ibc_keymaps/fr-beop_typo.map" ] || [ -e "$ibc_keymaps/fr-beop_typo.map.gz" ]; then echo "Disposition Béop (variante typographique) déjà installée pour la console ;" echo "pas de modification."; echo ibc_val_ret_typo=0 # Sinon, installation else cat_beop_cons "$ibc_keymaps/fr-beop_typo.map" "$ibc_version" "typo" "$ibc_altgr_sur_win" ibc_val_ret_typo=$? echo "Disposition Béop (variante typographique) installée pour la console dans" echo "$ibc_keymaps/fr-beop_typo.map."; echo fi if [ $ibc_val_ret_base -ne 0 ]; then return $ibc_val_ret_base elif [ $ibc_val_ret_prog -ne 0 ]; then return $ibc_val_ret_prog else return $ibc_val_ret_typo fi } # Déclaration complémentaire pour Debian et ses dérivées (Ubuntu, Linux Mint…) # Permet de choisir Béop comme disposition générale pour le système avec # dpkg-reconfigure keyboard-configuration declare_beop_debian() { # Si on n’est pas sous Debian ou une distribution dérivée, rien à faire. [ -n "$as_fich_debian" ] || return 0 [ -f "$as_fich_debian" ] || return 0 # On ajoute la définition de la disposition Béop uniquement si elle n’est # pas déjà présente. if grep '\*beop\*' "$as_fich_debian" > /dev/null 2>&1; then echo; echo "Disposition Béop déjà déclarée dans $as_fich_debian ;" echo "pas de modification." return 0 fi # Vérification de la disponibilité d’awk if echo | awk ''; then : else echo; echo "ERREUR !" echo "awk est nécessaire pour la déclaration de la disposition dans $as_fich_debian."; echo fi echo; echo "Sauvegarde du fichier $as_fich_debian d'origine en" echo " $as_fich_debian.sans_beop" cp -pf "$as_fich_debian" "$as_fich_debian.sans_beop" dbd_val_ret=$? if [ $dbd_val_ret -ne 0 ]; then echo "Échec !" echo "Assurez-vous de lancer la commande en tant que root (par exemple avec sudo)" echo "et qu'il reste de la place sur le disque."; echo exit $dbd_val_ret fi echo; echo "Déclaration de la disposition Béop dans $as_fich_debian" awk '/\*bepo\*/ { l=$0 sub(/bepo/, "beop", l) sub(/Bepo/, "Beop", l) sub(/Bépo/, "Béop", l) sub(/ \(BEPO\)/, " (BÉOP, more radical derivative of BÉPO)", l) sub(/, ergonomic, Dvorak way/, ", ergonomic, more radical derivative of Bepo", l) sub(/, komforteca, dvorake/, ", komforteca, pli radikala derivaĵo de Bepo", l) sub(/, ergonomique, façon Dvorak/, ", ergonomique, dérivée plus radicale de Bépo", l) print l sub(/beop/, "beop_prog", l) sub(/Beop/, "Beop_prog", l) sub(/Béop/, "Béop_prog", l) sub(/ \(BÉOP, more radical derivative of BÉPO\)/, " (BÉOP variant for programming)", l) sub(/, ergonomic, more radical derivative of Bepo/, ", ergonomic, Beop variant for programming", l) sub(/, komforteca, pli radikala derivaĵo de Bepo/, ", komforteca, variaĵo de Beop por programado", l) sub(/, ergonomique, dérivée plus radicale de Bépo/, ", ergonomique, variante de Béop pour la programmation", l) print l } { print } ' "$as_fich_debian.sans_beop" > "$as_fich_debian" dbd_val_ret=$? # On indique une éventuelle erreur. if [ $dbd_val_ret -ne 0 ]; then mv -f "$as_fich_debian.sans_beop" "$as_fich_debian" echo "Échec !" echo "Assurez-vous de lancer la commande en tant que root" echo "et qu'il reste de la place sur le disque." fi return $dbd_val_ret } # Installation de la disposition Béop sur le système installe_beop() { $debug && echo "installe_beop '$1' '$2' '$3' '$4'" >&2 # Installation pour X.org installe_beop_X "$1" "$2" "$3" "$4" ib_val_ret_X=$? # Si l’on est sous Linux (ou qu’on ne peut être sûr de ne pas l’être), # on installe la disposition pour la console. ib_systeme=`uname` if [ -z "$ib_systeme" ] || echo "$ib_systeme" | grep -i 'Linux' > /dev/null 2>&1; then installe_beop_console "$1" "$2" ib_val_ret_cons=$? else ib_val_ret_cons=0 fi # Traitement complémentaire pour Debian et ses dérivées, # si l’installation de la disposition a réussi. if [ $ib_val_ret_X -eq 0 ] ; then declare_beop_debian ib_val_ret_deb=$? else ib_val_ret_deb=0 fi if [ $ib_val_ret_X -ne 0 ]; then return $ib_val_ret_X elif [ $ib_val_ret_cons -ne 0 ]; then return $ib_val_ret_cons else return $ib_val_ret_deb fi } # Désinstallation de la disposition Béop du système desinstalle_beop() { # Rétablissement des versions sauvegardées du fichier des dispositions du # français et des fichiers de déclaration for db_fich_actuel in $as_fich_fr $as_rep_rules/* $as_fich_debian; do # On évite le cas où * ne serait pas développé… [ -e "$db_fich_actuel" ] || continue # On évite les liens. [ -L "$db_fich_actuel" ] && continue # On évite les fichiers qui n’ont pas une version sauvegardée. db_fich="${db_fich_actuel}.sans_beop" [ -e "$db_fich" ] || continue # Si le fichier actuel contient bien le beop, if grep beop $db_fich_actuel > /dev/null 2>&1; then # on le remplace par la version sauvegardée. if mv -f $db_fich $db_fich_actuel; then echo "$db_fich_actuel remplacé par $db_fich"; echo else echo "Impossible de remplacer $db_fich_actuel par $db_fich" echo "Assurez-vous de lancer la commande en root"; echo exit 255 fi # Sinon, c’est qu’il a déjà dû être écrasé par une version plus récente. else echo "La disposition Béop n’est pas installée dans $db_fich_actuel" echo "Ce fichier a peut-être été remplacé lors d’une mise à jour du système" echo "Pas de modification" echo fi done # On supprime les dispositions définies à part (anciennes versions de X). for db_fich in "${as_fich_fr}-beop" "${as_fich_fr}-beop_prog" "${as_fich_fr}-beop_typo"; do if [ -e $db_fich ]; then if rm -f $db_fich; then echo "$db_fich supprimé"; echo else echo "Impossible de supprimer $db_fich_actuel" echo "Assurez-vous de lancer la commande en root"; echo exit 255 fi fi done # Suppression des définitions pour la console Linux # On commence par déterminer tous les chemiens possibles. for db_rep in "$rep_install/usr/share/kbd/keymaps" "$rep_install/usr/share/keymaps" "$rep_install/usr/lib/kbd/keymaps" "$rep_install/lib/kbd/keymaps"; do for db_sous_rep in 'xkb' 'i386' 'i386/beop'; do for db_fich in 'fr-beop.map' 'fr-beop_prog.map' 'fr-beop_typo.map' 'fr-beop.map.gz' 'fr-beop_prog.map.gz' 'fr-beop_typo.map.gz'; do db_fich_actuel="$db_rep/$db_sous_rep/$db_fich" # Si le fichier existe, on le supprime. [ -e $db_fich_actuel ] || continue if rm -f "$db_fich_actuel"; then echo "Fichier $db_fich_actuel supprimé"; echo else echo "Impossible de supprimer $db_fich_actuel" echo "Assurez-vous de lancer la commande en root"; echo exit 255 fi done done # Le cas échéant, on supprime le répertoire spécifique. if [ -d "$db_rep/i386/beop" ]; then if rmdir "$db_rep/i386/beop"; then echo "Répertoire $db_rep/i386/beop supprimé"; echo else echo "Impossible de supprimer le répertoire $db_rep/i386/beop"; echo echo "Assurez-vous de lancer la commande en root"; echo exit 255 fi fi done return 0 } # Programme principal # L’action par défaut est de passer en Béop action='beop' # Paramètres par défaut rep_install='' version='1.1' variante='norm' altgr_sur_win=false guillemets_avec_espaces_norm=false guillemets_avec_espaces_typo=false multimedia_curseur=false multimedia_pause=false large=false couleurs=true debug=false # Détermination de l’option large par rapport à la largeur du terminal tput cols > /dev/null 2>&1 && [ `tput cols` -ge 89 ] && large=true # Rediriger la sortie d’erreur dans les apostrophes inversées causerait le # lancement dans un sous-shell non interactif et la valeur indiquée par tput # serait fausse. # Détermination de l’action à effectuer et des options tout d’abord d’après le # nom de la commande (attention : pas de vérification syntaxique) nom=`basename $0` # Traitement de l’action case "$nom" in # Si le nom sous lequel la commande a été lancée est azerty # ou les touches de repos gauches en Béop, on repasse en Azerty. azerty|auei|*_azerty|*-azerty) action='azerty' ;; # S’il contient _install, on installe la disposition sur le système. *_install|*_install_*|*_installe|*_installe_*) action='installe' ;; # S’il contient _switch, on bascule entre le Béop et l’Azerty. *_switch|*_switch_∗|*_bascule|*_bascule_*) action='switch' ;; esac # Traitement des options (elles peuvent être multiples) case "$nom" in *_1.0|*_1.0_*) version='1.0' ;; esac case "$nom" in *_1.1|*_1.1_*) version='1.1' ;; esac case "$nom" in *_pr|*_pr_*|*_prog|*_prog_*) variante=prog ;; esac case "$nom" in *_ty|*_ty_*|*_typo|*_typo_*) variante=typo ;; esac case "$nom" in *_gaen|*_gaen_*) guillemets_avec_espaces_norm=true ;; esac case "$nom" in *_gaet|*_gaet_*) guillemets_avec_espaces_typo=true ;; esac case "$nom" in *_gae|*_gae_*) guillemets_avec_espaces_norm=true guillemets_avec_espaces_typo=true ;; esac case "$nom" in *_asw|*_asw_*|*_aow|*_aow_*|*_altgr-sur-win|*_altgr-sur-win_*|_*altgr-on-win|*_altgr-on-win_*|*_altgrsurwin|*_altgrsurwin_*|*_altgronwin|*_altgronwin_*) altgr_sur_win=true ;; esac case "$nom" in *_mc|*_mc_*|*_multimedia-cursor|*_multimedia-cursor_*|*_multimedia-curseur|*_multimedia-curseur_*) multimedia_curseur=true ;; esac case "$nom" in *_mp|*_mp_*|*_multimedia-pause|*_multimedia-pause_*) multimedia_pause=true ;; esac case "$nom" in *_m|*_m_*|*_multimedia|*_multimedia_*) multimedia_curseur=true multimedia_pause=true ;; esac case "$nom" in *_test*) debug=true ;; esac # Détermination de l’action à effectuer et des options suivant les paramètres # (le dernier paramètre est prioritaire). while [ $# -gt 0 ]; do case "$1" in -h|-help|--help|-aide|--aide|-usage|--usage) action='usage' ;; -map|--map|-carte|--carte) action='affiche_carte' ;; -a|-azerty|--azerty) action='azerty' ;; -b|-beop|--beop) action='beop' ;; -s|-switch|--switch|-bascule|--bascule) action='switch' ;; -install|--install|-installe|--installe) action='installe' ;; -installdir|--installdir|-install-dir|--install-dir|-install_dir|--install_dir|-installerep|--installerep|-installe-rep|--installe-rep|-installe_rep|--installe_rep) action='installe' rep_install="$2" shift ;; -uninstall|--uninstall|-desinstalle|--desinstalle) action='desinstalle' ;; -uninstalldir|--uninstalldir|-uninstall-dir|--urinstall-dir|-uninstall_dir|--uninstall_dir|-desinstallerep|--desinstallerep|-desinstalle-rep|--desinstalle-rep|-desinstalle_rep|--desinstalle_rep) action='desinstalle' rep_install="$2" shift ;; -reinstall|--reinstall|-reinstalle|--reinstalle) action='reinstalle' ;; -reinstalldir|--reinstalldir|-reinstall-dir|--reinstall-dir|-reinstall_dir|--reinstall_dir|-reinstallerep|--reinstallerep|-reinstalle-rep|--reinstalle-rep|-reinstalle_rep|--reinstalle_rep) action='reinstalle' rep_install="$2" shift ;; -1.0|--1.0) version='1.0' ;; -1.1|--1.1) version='1.1' ;; -pr|--pr|-prog|--prog) variante='prog' ;; -ty|--ty|-typo|--typo) variante='typo' ;; -gae|--gae|-guillemets-avec-espaces|-guillemets_avec_espaces|-guillemetsavecespaces|--guillemets-avec-espaces|--guillemets_avec_espaces|--guillemetsavecespaces) guillemets_avec_espaces_norm=true guillemets_avec_espaces_typo=true ;; -gaen|--gaen|-guillemets-avec-espaces-norm|-guillemets_avec_espaces_norm|-guillemetsavecespacesnorm|--guillemets-avec-espaces-norm|--guillemets_avec_espaces_norm|--guillemetsavecespaces_norm) guillemets_avec_espaces_norm=true ;; -gaet|--gaet|-guillemets-avec-espaces-typo|-guillemets_avec_espaces_typo|-guillemetsavecespacestypo|--guillemets-avec-espaces-typo|--guillemets_avec_espaces_typo|--guillemetsavecespacestypo) guillemets_avec_espaces_typo=true ;; -asw|--asw|-aow|--aow|-altgr-sur-win|-altgr_sur_win|-altgrsurwin|--altgr-sur-win|--altgr_sur_win|--altgrsurwin|altgr-on-win|-altgr_on_win|-altgronwin|--altgr-on-win|--altgr_on_win|--altgronwin) altgr_sur_win=true ;; -mc|--mc|-multimedia-cursor|--multimedia-cursor|-multimedia-curseur|--multimedia-curseur) multimedia_curseur=true ;; -mp|--mp|-multimedia-pause|--multimedia-pause) multimedia_pause=true ;; -m|--m|-multimedia|--multimedia) multimedia_curseur=true multimedia_pause=true ;; -large|--large) large=true ;; -etroit|-etroite|--etroit|--etroite) large=false ;; -clair|-claire|--clair|--claire) couleurs="true fond_clair" ;; -sombre|--sombre) couleurs="true fond_sombre" ;; *) usage "$version" "$variante" "$altgr_sur_win" "$large" "$couleurs" echo; echo "Paramètre non reconnu : $1"; echo exit 255 ;; esac shift done # Si l’action est d’afficher l’usage ou la carte, on le fait tout de suite et on # sort (les opérations qui suivent ne sont pas utiles pour ça). case "$action" in usage|affiche_carte) $action "$version" "$variante" "$altgr_sur_win" "$large" "$couleurs" exit 0 ;; esac # Vérification de la disponibilité de grep -E if echo ab | grep -E '(a)(b)' > /dev/null 2>&1; then egrep='grep -E' elif echo ab | egrep '(a)(b)' > /dev/null 2>&1; then egrep='egrep' else echo; echo "ERREUR !" echo "Ni grep -E ni egrep ne sont fonctionnels."; echo exit 255 fi # Si l’action est switch, if [ "$action" = "switch" ]; then # on passe en Azerty si l’on était en Béop, sinon en Béop. if [ -n "$DISPLAY" ]; then if xkbcomp -xkb -o - $DISPLAY | $egrep '^xkb_symbols.*beop' > /dev/null; then action=azerty else action=beop fi elif [ "$TERM" = "linux" ]; then if dumpkeys | $egrep '^[[:space:]]*keycode[[:space:]]+19[[:space:]]*=[[:space:]]*\+p' > /dev/null; then action=azerty else action=beop fi fi fi # Si l’action consiste à changer de disposition, on vérifie qu’on est sous X.org # ou sous une console Linux. if { [ "$action" = "azerty" ] || [ "$action" = "beop" ]; } && [ -z "$DISPLAY" ] && [ "$TERM" != "linux" ]; then usage "$version" "$variante" "$altgr_sur_win" "$large" "$couleurs" echo; echo "ERREUR : Ce script ne prend en charge que X.org et la console texte Linux."; echo exit 255 fi # On analyse le système analyse_systeme # On effectue l’action retenue. case "$action" in azerty) if [ "$TERM" = "linux" ]; then console_azerty fi # Éviter la construction [ "$DISPLAY " ] && ... permet d’éviter que la # valeur de la condition n’affecte la valeur de retour. if [ -n "$DISPLAY" ]; then azerty fi ;; beop) if [ "$TERM" = "linux" ]; then console_beop "$variante" "$altgr_sur_win" fi if [ -n "$DISPLAY" ]; then beop "$version" "$variante" "$altgr_sur_win" "$guillemets_avec_espaces_norm" "$guillemets_avec_espaces_typo" fi ;; *installe) if [ "$action" = "desinstalle" ] || [ "$action" = "reinstalle" ]; then desinstalle_beop fi if [ "$action" = "installe" ] || [ "$action" = "reinstalle" ]; then installe_beop "$version" "$altgr_sur_win" "$guillemets_avec_espaces_norm" "$guillemets_avec_espaces_typo" fi ;; esac