-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
install-dreymar-xmod.sh
executable file
·278 lines (248 loc) · 12.2 KB
/
install-dreymar-xmod.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#!/bin/bash
## =================================================================
## === INSTALL-DREYMAR-XMOD.sh for DreymaR's XKB modifications ===
## === by Øystein "DreymaR" Bech-Aase, 2016- ===
## =================================================================
#
HeadStr="DreymaR's Big Bag Of Tricks install script (by OeBeAa, 2016-)"
DescStr=\
"\e[1mShell script to apply DreymaR's changes to the X keyboard files:\e[0m\n"\
" - The Colemak [edition DreymaR] layout, using my own lv3-4 mappings,\n"\
" - Curl/Angle/Wide Ergonomic keyboard models for pc104/pc105 keyboards,\n"\
" - Extend mappings as a Misc option and CapsLock as a chooser (using lv5-8),\n"\
" - locale variants of Colemak[eD] with 'keep local' or 'unified' symbol keys,\n"\
" - phonetic variants of Colemak for other scripts such as Greek,\n"\
" - mirrored Colemak[eD] for one-handed typing (if I ever break an arm...),\n"\
" - and the Tarmak(1-4) transitional step-by-step Colemak learning layouts.\n"\
"\n"\
"- By default, this script creates a backup of the X11 files if none exist.\n"\
"- With '-o', overwrite the system X11 files (makes the mod GUI accessible).\n"\
"- With a ShortStr at the end, specify a model/layout to activate immediately.\n"\
" - ShortStr format: '[4|5][n|a|c][w|f] loc [ks|us]'; 'loc'(ale) is 2-letter.\n"\
" - E.g., '5n fr us' is normal pc105 model, French Cmk[eD]-'UniSym'.\n"\
" - See setkb.sh help for more info on ShortStr syntax.\n"\
"- With '-?', list further instructions and default values.\n"\
"- See http://forum.colemak.com/viewtopic.php?id=1438 for more info\n"
#
FootStr="Happy xkb-hacking! ~ Øystein 'DreymaR' Bech-Aase"
#"- With '-i <dir>', specify a directory path/name to install in.\n"\
#"- With '-g', also install GTK 2.0/3.0 config for XF86 Cut/Copy/Paste.\n"\
## NOTE: The mod directory has the form $DModTag="x-mod_v<VER>[_<DATE>]"
## - Unless you change this tag, it should be in the same dir as this script
## - It has subdirectories like 'xkb' that are to be installed (one, some or all)
## NOTE: This is now the preferred way instead of patching the system files:
## - Backup system xkb to dbak-xkb_<DATE> (and the same for any other subdirs)
## - Copy X11/xkb to ${InstDir}/dxkb, then modify files in dxkb
## - Set up setkb.sh to run from the modified dxkb [WARNING: This may not work now!]
## - Or, (-o) overwrite the system files instead
## NOTE: The x-mod dir now holds x-mod*/xkb; eventually there may be a locale dir too.
##-------------- init ------------------------------------------
MyDATE=`date +"%Y-%m-%d_%H-%M"`
MyNAME=`basename $0`
MyPATH=`dirname $0`
## @@@ The default X11 dir under Debian/Ubuntu/etc is /usr/share/X11 @@@
## @@@ The default X11 dir under some (older) distros is /usr/lib/X11 @@@
X11DIR='/usr/share/X11'; [ -d "${X11DIR}" ] || X11DIR='/usr/lib/X11'
#~ XVERSION='2-17-1ub1'
XVERSION=''
ModDATE=''
DModDir=`dirname $0` # (-d) Path to the script (and mod?) root directory
ToolDir="${DModDir}/dreymar-xtools" # The loc. of tool scripts (like setkb.sh)
DMod='xkb-data_xmod' # (--) Name of the directory with DreymaR's modded xkb-data files
DModTag="${DMod}${XVERSION:+'_v'}${XVERSION}${ModDATE:+'_'}${ModDATE}" # (-t) Mod dir "prefix"
DBakFix='dbak-' # (--) Backup dir prefix
DModFix='d' # (--) Modded dir prefix
InstDir="${X11DIR}" # (-i) Path to install subfolder(s) in
#~ InstDir="${HOME}/dreymar-xmod" # (-i) Path to install subfolder(s) in
WriteSys='no' # (-o) Overwrite the original xkb dir with the modded one
Restore='0' # (-r) Reverse: Restore from backup # instead of installing
DoBackup='ifnone' # (-n/b) Default backup behavior is "if no backups are found"
SubDirs='all' # (-m) Directory/-ies inside X11 to modify (e.g., 'xkb locale', 'all')
InstGTK='no' # (-g) Whether to install the GTK 2.0/3.0 config (if not present)
NoSudo='no' # (-s) Do not use sudo. Helpful for local dir installation.
SetXMap='no' # (-x) Whether to run the setkb script after installing
SetXStr='5caws us us' # (--) Shortcut string for setkb - 'kbd loc sym' (model layout eD-variant)
## NOTE: '# (-a)' means that the value can be set by option argument '-a <value>'
HelpStr="\e[1mUsage: bash ${MyNAME} [optional args] [<kbd> [<loc> <sym>]]\e[0m\n"\
" Run this from the directory containing the x-mod dir\n"\
"===========================================================\n"\
"[-#] Functionality - 'default' \n"\
"===========================================================\n"\
"[-i] <Install path> - ${InstDir}\n"\
"[-c] Change path to X11 - ${X11DIR}\n"\
"[-o] Override install path w/ X11 - ${WriteSys}\n"\
"[-b] Force backup | location - ${X11DIR}\n"\
"[-n] Force no backup | default - ${DoBackup}\n"\
"[-r] <#> Restore backup | 1 is oldest - ${Restore}\n"\
"[-d] <mod dir path> - ${DModDir}\n"\
"[-m] <X11 subdir(s) to mod> - ${SubDirs}\n"\
"[-t] <mod dir prefix tag> - ${DModTag}\n"\
"[-g] Install GTK 2.0/3.0 edit config? - ${InstGTK}\n"\
"[-x] Run the setkb script afterwards? - ${SetXMap}\n"\
"[-s] Install without using sudo? - ${NoSudo}\n"\
"[--] [Setxkb ShortStr <kbd loc sym>] - ${SetXStr}\n"
#~ "( - <val> : Default settings)\n"
##-------------- functions and line parser ---------------------
MyMsg() # Formatted output: last arg is printf 'style[;fgcolor[;bgcolor]]'
{
# Style: 0-Off, 1-Bold, 4-Underscore, 5-Blink, 7-Reverse, 8-Concealed
# Color: (3#/4# FG/BG): 0-Black, 1-Red, 2-Green, 3-Yellow, 4-Blue, 5-Magenta, 6-Cyan, 7-White
printf "\n\e[${3:-1;32;40}m@@@ $1 @@@\e[0m\n$2" # default: Bold green on black
}
PrintHelpAndExit()
{
MyMsg "${HeadStr}" "\n"
printf "${DescStr}\n"
printf "${HelpStr}"
MyMsg "${FootStr}" "\n"
exit $1
}
MyEcho()
{
printf "$1\n"
[ -z "$2" ] || printf "$1\n" >> "$2"
}
MyPoint()
{
MyEcho "\e[1;32m¤ \e[0m$@" # Bold green
}
MyWarning()
{
MyMsg "WARNING: ${@:-'Beware of nargles!'}" "\n" '1;36;44' # Bold cyan on blue
#~ exit 1
}
MyError()
{
MyMsg "$MyNAME - ERROR: ${@:-'Undefined error'}" "\n" '1;37;41' # Bold white on red
exit 1
}
#~ MyCD()
#~ {
#~ OldDir=`pwd`
#~ NewDir=${1:-`pwd`}
#~ cd ${NewDir} || MyError "Change to '${NewDir}' failed"
#~ MyPoint "Changed dir to '${NewDir}'"
#~ }
#~ if [ "$#" == 0 ]; then PrintHelpAndExit 2; fi # No args
while getopts "obngxsm:i:c:d:t:r:h?" cmdarg; do
case $cmdarg in
o) WriteSys='yes' ;;
b) DoBackup='yes' ;;
n) DoBackup='no' ;;
g) InstGTK='yes' ;;
x) SetXMap='yes' ;;
s) NoSudo='yes' ;;
m) SubDirs="$OPTARG" ;;
i) InstDir="$OPTARG" ;;
c) X11DIR="$OPTARG" ;;
d) DModDir="$OPTARG" ;;
t) DModTag="$OPTARG" ;;
r) Restore="$OPTARG" ;;
h) PrintHelpAndExit 0 ;;
\?) PrintHelpAndExit 0 ;;
:) PrintHelpAndExit 1 ;;
# s) SetXStr="$OPTARG"
# SetXMap='yes' ;;
esac
done
#~ pos_arg=${@:$OPTIND:1} # Get the remaining positional arg (old way)
shift $(( $OPTIND - 1 )) # Remove already processed args
[[ "$@" == "" ]] || SetXStr=$@ # Don't split the ShortString here!
##-------------- main ------------------------------------------
MyMsg "$HeadStr"
#~ MyPoint "Working from '`pwd`'"
## Check for a mod dir (the latest found) and if found, get its full name
DModDir=`find "${DModDir%/}/${DModTag}"* -maxdepth 0 -type d 2>/dev/null | tail -n 1`
[ -n "${DModDir}" ] || MyError "Mod root dir not found!"
MyPoint "Found mod root dir '${DModDir}'"
## Read the mod subdirs
if [ "${SubDirs}" == "all" ]; then
SubDirs=`find "${DModDir}/"* -maxdepth 0 -type d -exec basename '{}' \; 2>/dev/null`
SubDirs=`echo ${SubDirs}` # A trick to make a var space separated for the following echo cmd
[ -n "${SubDirs}" ] || MyError "No mod subdirs found!"
fi
MyPoint "Subdirectories to mod: '${SubDirs}'"
## For each subdir, backup if either DoBackup = 'yes' or DoBackup = 'ifnone' and no backup exists
BackIt=''
if [ ${DoBackup} == 'yes' ]; then
BackIt="${SubDirs}"
elif [ ${DoBackup} == 'ifnone' ] && [ ${Restore} == '0' ]; then
for That in ${SubDirs}; do
MyPoint "Looking for '${That}' backup in '${X11DIR}'..."
# Test for (at least one) backup dir; if none found then proceed without errors
# if [ -z `find "${X11DIR}/${DBakFix}${That}"* -maxdepth 0 -type d 2>/dev/null | head -n 1` ]; then
if [ -z `find "${X11DIR}/${DBakFix}${That}"* -maxdepth 0 -type d -print -quit 2>/dev/null` ]; then
[ -n "${BackIt}" ] && BackIt+=' ' # join with ' '; note that += is a bashism
BackIt+="${That}"
fi
done
fi
[ -z "${BackIt}" ] && MyPoint "Backing up: None" || MyPoint "Backing up: '${BackIt}'"
## Check for root privileges (if not root, sudo command); note that root is only needed in some cases!
DoSudo=''
if [ ${NoSudo} = 'yes' ]; then
MyPoint "Not using sudo."
else
if [ "$EUID" -ne 0 ]; then # not root, so test for and use sudo instead (but some distros don't have it!)
#[ command -v sudo >/dev/null 2>&1 ] || MyError "Root access needed - sudo won't run!"
( command -v sudo >/dev/null 2>&1 ) || MyWarning "Root/superuser access may be needed!"
DoSudo='sudo'
fi
fi
## Perform the actual backup(s)
## NOTE: cp -a makes an "archive" copy, preserving all attributes and links
for That in ${BackIt}; do
[ -d "${X11DIR}/${That}" ] || MyError "Unable to backup '${That}': Directory not found!"
${DoSudo} cp -a "${X11DIR}/${That}" "${X11DIR}/${DBakFix}${That}_${MyDATE}" || MyError "Copy error!"
done
## For each subfolder: Restore from backup #, overwrite X11 files or make new mod folder
for That in ${SubDirs}; do
if [ ${Restore} != '0' ]; then # Restore from specified backup
## Restore from backup. Pick a backup # by parameter, 1 being oldest; use 999 or such for the last one
BackIt=`find "${X11DIR}/${DBakFix}${That}"* -maxdepth 0 -type d 2>/dev/null | head -n ${Restore} | tail -n 1`
[ -d "${BackIt}" ] || MyError "Unable to locate restore dir '$(basename "${BackIt}")'"
MyPoint "Restoring from backup '$(basename "${BackIt}")'"
${DoSudo} cp -a "${BackIt}/"* "${X11DIR}/${That}" 2>/dev/null \
&& MyPoint "Restore done" || MyError "Restore copy error!"
XKBDir="${X11DIR}/xkb" # Setxkbmap will default to the X11 dir, but this makes it unambigous
elif [ ${WriteSys} == 'yes' ] || [ ${InstDir} == ${X11DIR} ] && [ -d "${DModDir}/${That}" ]; then # Overwrite OS files
MyPoint "Replacing files in '${X11DIR}/${That}' with mod"
${DoSudo} cp -a "${DModDir}/${That}/"* "${X11DIR}/${That}" 2>/dev/null \
&& MyPoint "System install done" || MyError "System files copy error!"
XKBDir="${X11DIR}/xkb"
else ## Make new mod folder (will not show up in keyboard settings GUI; use setxkbmap instead)
DoSudo=''
mkdir -p "${InstDir}" 2>/dev/null && [ -w "${InstDir}" ] || DoSudo='sudo' # check whether sudo is needed
MyDir="${InstDir%/}/${DModFix}${That}"
#~ MyDir="$(dirname "${MyDir}")/${DModFix}$(basename "${MyDir}")" # Insert prefix in path/name
MyPoint "Installing mod files in '${MyDir}'"
MyWarning "It seems that setxkbmap w/ local dir isn't working now?!"
${DoSudo} mkdir -p "${MyDir}" || MyError "Can't make '${MyDir}'!"
${DoSudo} cp -a "${X11DIR}/${That}/"* "${MyDir}" 2>/dev/null || MyError "Local files copy error!"
${DoSudo} cp -a "${DModDir}/${That}/"* "${MyDir}" 2>/dev/null \
&& MyPoint "Local install done" || MyError "Local files copy error!"
XKBDir="${InstDir%/}/${DModFix}xkb" # Prepare for setxkbmap
cp -a setkb.sh ${InstDir} # Copy over the setkb.sh script to the new dir
fi
done
## If selected, call the DreymaR GTK bindings install script
## The DreymaR gtk edit install script sets GTK Cut/Copy/Paste key config (if not already present)
if [ ${InstGTK} == 'yes' ]; then
"${ToolDir}/gtk_edit_install.sh" || MyError "gtk_edit_install.sh failed!"
fi
#~ ## Call the DreymaR setxkbmap script unless 'q' is pressed, to activate the new (default) layout
#~ That='' #; [ ${InstGTK} == 'yes' ] && That=" and GTK edit config"
#~ MyMsg "Press any key to set the new xkb map${That}, or 'q' to quit"
#~ read -p '$>' -n 1 keypress
#~ if [ "${keypress}" == 'q' ]; then
## If selected, call the DreymaR setxkbmap script to activate the new (default) layout
if [ "${SetXMap}" != 'yes' ]; then
MyMsg "XKBmap activation skipped" "" '1;33;40'
else
bash ./setkb.sh -d "${XKBDir}" ${SetXStr} || MyError "setkb.sh failed!"
fi
MyMsg "${MyNAME} finished!" "\n"
exit 0
##-------------- misc ------------------------------------------
#~ MyWarning "'${MyNAME}' debug - exiting!"; exit 0
#~ echo "$1 $2 $3 $4 $5"; exit 0 # debug