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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
|
#!/bin/sh
# Copyright (C) 2006 Osamu Aoki <osamu@debian.org>
# Copyright (C) 2005 - 2006 Kenshi Muto <kmuto@debian.org>
# Modified for Debian package.
# Copyright (C) 1999 - 2004 Red Hat, Inc. All rights reserved. This
# copyrighted material is made available to anyone wishing to use, modify,
# copy, or redistribute it subject to the terms and conditions of the
# GNU General Public License version 2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# system wide configuration directory
XINPUT_PATH=/etc/X11/xinit/xinput.d
# user specific customization directory
DOTXINPUT_PATH=${HOME}/.xinput.d
# All im-switch related alternatives start with xinput-
ALTER_XINPUT=/etc/alternatives/xinput-
# location for special hook scripts installed by each IM packages
HOOKDIR=/usr/share/im-switch
# $LNG is locale <languag>e_<region> without .<encoding> and .<encoding>@EURO
LNG=${LC_ALL:-${LC_CTYPE:-${LANG}}}
LNG=${LNG%@*}
LNG=${LNG%.*}
[ -z "$LNG" ] && LNG="all_ALL" || true
USERID=$(id -u)
VER=@@VERSION@@
VERBOSE=0
# echo to STDERR when VERBOSE is on.
vecho() {
if [ $VERBOSE -eq 1 ] ; then
echo "$1" >&2
fi
}
# echo local setups to STDERR when VERBOSE is on.
vlang() {
if [ $VERBOSE -eq 1 ] ; then
echo "LC_ALL=\"$LC_ALL\"" >&2
echo "LC_CTYPE=\"$LC_CTYPE\"" >&2
echo "LANG=\"$LANG\"" >&2
echo "LNG=\"$LNG\"" >&2
fi
}
# echo command line info to STDERR when VERBOSE is on.
errcmd() {
echo "Error: \"${0##*/}\" invoked with \"$ORGAT\" as options." >&2
echo "Error: Try \"${0##*/} -h\" for usage." >&2
}
# echo missing dependency information for $1=$LNG
dependency() {
if [ -z "$1" ] ; then
return
fi
if [ -r ${HOME}/$(basename "$1") ]; then
DEPENDS=$(grep -e "DEPENDS=" ${HOME}/$(basename $1) | sed -e 's/DEPENDS=//' -e 's/"//g')
elif [ -r "${XINPUT_PATH}/$1" ]; then
DEPENDS=$(grep -e "DEPENDS=" $XINPUT_PATH/$1 | sed -e 's/DEPENDS=//' -e 's/"//g')
else
DEPENDS=""
fi
vecho "From the package dependency information requires"
vecho " \"$DEPENDS\"."
if [ -z "$DEPENDS" ]; then
return
fi
RESULT=""
# split with ","
IFS=","
for i in `echo "$DEPENDS"`; do
INSTALLED=0
# split with |
IFS="|"
for j in `echo "$i"`; do
unset IFS
vecho "checking status of \"$j\" package"
if dpkg -s $j 2>/dev/null | grep -q -e "Status: install ok installed" ; then
vecho "+++ \"$j\" package is installed."
INSTALLED=1
else
vecho "---- \"$j\" package is NOT installed."
fi
done
done
if [ $INSTALLED -eq 0 ]; then
if [ -z "$RESULT" ]; then
RESULT="( $i )"
else
RESULT="${RESULT} and ( $i )"
fi
fi
if [ -n "$RESULT" ]; then
echo "Please install following packages:"
echo " $(echo \"$RESULT\" | sed -e 's/|/ or /g') ."
fi
}
# echo current system wide default IM setup name
current_system_im () {
if [ -r "${ALTER_XINPUT}${LNG}" ]; then
/usr/sbin/update-alternatives --display xinput-$LNG | \
sed -ne 's/^ *link currently points to \([^ ]*\)/\1/p' | \
sed -e "s%${XINPUT_PATH}/%%"
elif [ -r "${ALTER_XINPUT}all_ALL" ]; then
/usr/sbin/update-alternatives --display xinput-all_ALL | \
sed -ne 's/^ *link currently points to \([^ ]*\)/\1/p' | \
sed -e "s%${XINPUT_PATH}/%%"
else
echo "No system wide default \"${ALTER_XINPUT}${LNG} or ${ALTER_XINPUT}all_ALL\" is defined."
exit 1
fi
}
# echo current user IM setup name
current_user_im () {
if [ -h ${DOTXINPUT_PATH}/$LNG ]; then
readlink ${DOTXINPUT_PATH}/$LNG | \
sed -e "s%${XINPUT_PATH}/%%" -e "s%${DOTXINPUT_PATH}/%~/.xinput.d/%"
fi
}
# echo IM setup candidates
possible_im () {
( (/usr/bin/find $XINPUT_PATH -type f| sed -e "s%$XINPUT_PATH/%%") ; \
(/usr/bin/find $DOTXINPUT_PATH -type f| sed -e "s%$DOTXINPUT_PATH/%%" ; ) ) | \
sort -u
# XXX FIXME : should test for executable
}
# run system hook script when system wide IM setup is changed
# So far, I have not see its use yet.
# $PREVIOUS
# $DEFAULT
runhookscripts () {
if [ "$DEFAULT" != "$PREVIOUS" ]; then
[ "$PREVIOUS" -a -x "$HOOKDIR/$PREVIOUS" ] && $HOOKDIR/$PREVIOUS remove
[ "$DEFAULT" -a -x "$HOOKDIR/$DEFAULT" ] && $HOOKDIR/$DEFAULT install
fi
}
list() {
echo "Your input method setup under $LNG locale as below."
echo "======================================================="
if [ "$USERID" -eq 0 ]; then
echo "No private configuration can be defined for root account."
elif [ -r "${DOTXINPUT_PATH}/${LNG}" ]; then
if [ -L "${DOTXINPUT_PATH}/${LNG}" ]; then
echo "The configuration \"${DOTXINPUT_PATH}/${LNG}\" is defined as a link pointing to"
echo "$(basename $(readlink "${DOTXINPUT_PATH}/${LNG}"))"
else
echo "The private configuration is a static file \"${DOTXINPUT_PATH}/${LNG}\" ."
fi
echo "This private configuration supersedes the system wide default."
elif [ -L "${DOTXINPUT_PATH}/all_ALL" ]; then
if [ -L "${DOTXINPUT_PATH}/all_ALL" ]; then
echo "The configuration \"${DOTXINPUT_PATH}/all_ALL\" is defined as a link pointing to"
echo "$(basename $(readlink "${DOTXINPUT_PATH}/all_ALL"))"
else
echo "The private configuration is a static file \"${DOTXINPUT_PATH}/all_ALL\" ."
fi
echo "This private configuration supersedes the system wide default."
else
echo "No private \"${DOTXINPUT_PATH}/${LNG} or ${DOTXINPUT_PATH}/all_ALL\" is defined."
fi
echo "======================================================="
if [ -r "${ALTER_XINPUT}${LNG}" ]; then
echo "The system wide default is pointed by \"${ALTER_XINPUT}${LNG}\" ."
/usr/sbin/update-alternatives --display xinput-$LNG | sed -e "s%$XINPUT_PATH/%%"
elif [ -r "${ALTER_XINPUT}all_ALL" ]; then
echo "The system wide default is pointed by \"${ALTER_XINPUT}all_ALL\" ."
/usr/sbin/update-alternatives --display xinput-all_ALL | sed -e "s%$XINPUT_PATH/%%"
else
echo "No system wide default \"${ALTER_XINPUT}${LNG} or ${ALTER_XINPUT}all_ALL\" is defined."
fi
vecho "======================================================="
vecho "The system wide default input methods are available for the locales:"
for i in `/bin/ls $ALTER_XINPUT* | sed -e "s%$ALTER_XINPUT%%"`; do
vecho -n "$i "
done
vecho
echo "======================================================="
echo "The available input method configuration files are:"
for i in `possible_im` ; do
if [ -r $DOTXINPUT_PATH/$i ]; then
echo -n "~/.xinput.d/$i "
else
echo -n "$i "
fi
done
echo
vecho "======================================================="
vecho "The available input method hook scripts are in $HOOKDIR:"
for i in `/usr/bin/find $HOOKDIR -type f| sed -e "s%$HOOKDIR/%%"`; do
vecho -n "$i "
done
vecho
echo "======================================================="
}
# set IM to defaults
auto() {
if [ "$USERID" -eq 0 ]; then
if [ ! -r "${ALTER_XINPUT}${LNG}" ]; then
echo "No system wide default defined just for locale ${LNG} ."
echo "Use \"all_ALL\" quasi-locale and set IM."
LNG="all_ALL"
fi
PREVIOUS=$(current_system_im)
/usr/sbin/update-alternatives --auto xinput-$LNG
else
if [ -r "${DOTXINPUT_PATH}/${LNG}" ]; then
PREVIOUS=$(current_user_im)
mv ${DOTXINPUT_PATH}/${LNG} ${DOTXINPUT_PATH}/${LNG}.backup
fi
fi
DEFAULT=$(current_system_im)
dependency $DEFAULT
runhookscripts
}
# set im setup pointing to to $1 script in $XINPUT_PATH
setalt() {
if [ "$USERID" -eq 0 ]; then
vecho "You are root user."
# sanity check
if [ ! -r "$XINPUT_PATH/$1" ] ; then
echo "Error: no system wide configuration file \"$1\" exists." >&2
echo "Error: No action taken." >&2
exit 1
fi
if [ ! -r "${ALTER_XINPUT}${LNG}" ]; then
echo "No system wide default defined just for locale $LNG ."
echo "Use \"all_ALL\" quasi-locale and set IM."
LNG="all_ALL"
fi
PREVIOUS=$(current_system_im)
/usr/sbin/update-alternatives --set xinput-$LNG $XINPUT_PATH/${1}
DEFAULT=$(current_system_im)
vecho "Changed system wide default from $PREVIOUS to $DEFAULT."
else
# sanity check
if [ ! -r "$XINPUT_PATH/${1}" -a ! -r "$DOTXINPUT_PATH/${1}" ] ; then
echo "Error: no configuration file \"${1}\" exists." >&2
echo "Error: No action taken." >&2
exit 1
fi
vecho "You are non-root user."
if [ ! -d ${DOTXINPUT_PATH} ]; then
mkdir -p ${DOTXINPUT_PATH}
vecho "Creating ${DOTXINPUT_PATH} directory."
fi
if [ -r "${DOTXINPUT_PATH}/${LNG}" ]; then
PREVIOUS=$(current_user_im)
mv ${DOTXINPUT_PATH}/${LNG} ${DOTXINPUT_PATH}/${LNG}.backup
vecho "Backed up user configuration pointing to $PREVIOUS."
fi
if [ -r "$DOTXINPUT_PATH/${1}" ] ; then
ln -s $DOTXINPUT_PATH/${1} ${DOTXINPUT_PATH}/$LNG
else
ln -s $XINPUT_PATH/${1} ${DOTXINPUT_PATH}/$LNG
fi
DEFAULT=$(current_user_im)
vecho "Set user configuration pointing to $DEFAULT."
fi
dependency "$DEFAULT"
runhookscripts
}
# set im setup pointing to to a script in $XINPUT_PATH by terminal menu
cfgalt() {
if [ "$USERID" -eq 0 ]; then
vecho "You are root user."
if [ ! -r "${ALTER_XINPUT}${LNG}" ]; then
echo "No system wide default defined just for locale $LNG ."
echo "Use \"all_ALL\" quasi-locale and set IM."
LNG="all_ALL"
fi
PREVIOUS=$(current_system_im)
echo "System wide default for ${LNG} locale is marked with [+]."
/usr/sbin/update-alternatives --config xinput-$LNG
DEFAULT=$(current_system_im)
vecho "Changed system wide default from $PREVIOUS to $DEFAULT."
else
vecho "You are non-root user."
if [ ! -d ${DOTXINPUT_PATH} ]; then
mkdir -p ${DOTXINPUT_PATH}
vecho "Creating ${DOTXINPUT_PATH} directory."
fi
PREVIOUS_SYS=$(current_system_im)
if [ -r "${DOTXINPUT_PATH}/${LNG}" ]; then
PREVIOUS=$(current_user_im)
cp -a ${DOTXINPUT_PATH}/${LNG} ${DOTXINPUT_PATH}/${LNG}.backup
vecho "Backed up user configuration pointing to $PREVIOUS."
fi
vecho " PREVIOUS_SYS=\"$PREVIOUS_SYS\""
vecho " PREVIOUS=\"$PREVIOUS\""
COUNT=`possible_im | wc -l`
if [ "x$DISPLAY" != "x" ] && [ -x "/usr/bin/zenity" ]; then
zenity_ucfgalt
else
console_ucfgalt
fi
fi
DEFAULT=$(current_user_im)
vecho "Set user configuration pointing to $DEFAULT."
dependency "$DEFAULT"
runhookscripts
}
# set user im setup pointing to to a script in $XINPUT_PATH by console menu
console_ucfgalt() {
echo "Input Method Switcher im-switch Version: $VER"
echo " Selection Input Method Candidates for ${DOTXINPUT_PATH}/${LNG}:"
echo " ------------------------------------------------------------------"
INDEX=0
for i in `possible_im`; do
INDEX=$(($INDEX+1))
if [ -r $DOTXINPUT_PATH/$i ]; then
if [ "$PREVIOUS" = "~/.xinput.d/$i" ]; then
echo -n "*"
else
echo -n " "
fi
if [ "$PREVIOUS_SYS" = "~/.xinput.d/$i" ]; then
echo -n "+"
else
echo -n " "
fi
echo " $INDEX ~/.xinput.d/$i "
else
if [ "$PREVIOUS" = "$i" ]; then
echo -n "*"
else
echo -n " "
fi
if [ "$PREVIOUS_SYS" = "$i" ]; then
echo -n "+"
else
echo -n " "
fi
echo " $INDEX $i"
fi
done
echo "System wide default for ${LNG} (or all_ALL) locale is marked with [+]."
echo "Type \"REMOVE\" to remove user selection to enable system default."
echo -n "Press enter to keep the current selection[*], or type selection number: "
read SEL
echo
if [ -z "$SEL" ]; then
# No action because INDEX is larger than 0
SEL=0
fi
if [ "$SEL" != "REMOVE" ]; then
INDEX=0
for i in `possible_im`; do
INDEX=$(($INDEX+1))
if [ "$SEL" -eq "$INDEX" ]; then
if [ -r "$DOTXINPUT_PATH/$i" ] ; then
ln -fs $DOTXINPUT_PATH/$i ${DOTXINPUT_PATH}/$LNG
else
ln -fs $XINPUT_PATH/$i ${DOTXINPUT_PATH}/$LNG
fi
fi
done
else
if [ -h "$DOTXINPUT_PATH/$LNG" ] ; then
rm ${DOTXINPUT_PATH}/$LNG
vecho "${DOTXINPUT_PATH}/$LNG removed"
fi
fi
echo "Please read /usr/share/doc/im-switch/README.Debian.gz ."
echo "Please restart the X session to activate the selected Input Method."
}
menuitem_im () {
echo $1 | sed \
-e "s/^~\/\.xinput\.d\//User local configuration at ~\/\.xinput\.d\/: /" \
-e "s/default-xim$/Use xim (default-xim)/" \
-e "s/default$/Use setting by the sysadmin. (default)/" \
-e "s/ibus$/Use IBus (ibus)/" \
-e "s/lo-gtk$/Use thai IM_MODULE (lo-gtk)/" \
-e "s/none$/Do not use Input Method. (none)/" \
-e "s/scim-bridge$/Use SCIM via scim-bridge (scim-bridge)/" \
-e "s/scim-immodule$/Use SCIM via IM_MODULE (scim-immodule)/" \
-e "s/scim$/Use SCIM via xim (scim)/" \
-e "s/skim$/Use SCIM via IM_MODULE (skim)/" \
-e "s/th-gtk$/Use thai IM_MODULE (th-gtk)/" \
-e "s/th-xim$/Use thai xim (th-xim)/"
}
# set user im setup pointing to to a script in $XINPUT_PATH by zenity menu
zenity_ucfgalt() {
ZCMD0="zenity --title=\"Input Method Switcher (ver $VER)\" --width=600 --height=400 --text=\"Select User Input Method for ${LNG} . User choice supercedes system choice marked as default.\" --list --radiolist --hide-column=2 --column \"User\" --column \"im\" --column \"system\" --column \"Description of Input Method\""
ZCMD=""
for i in `possible_im`; do
if [ -r $DOTXINPUT_PATH/$i ]; then
if [ "$PREVIOUS" = "~/.xinput.d/$i" ]; then
ZCMD="$ZCMD TRUE"
else
ZCMD="$ZCMD FALSE"
fi
ZCMD="$ZCMD ~/.xinput.d/$i"
if [ "$PREVIOUS_SYS" = "~/.xinput.d/$i" ]; then
ZCMD="$ZCMD default"
else
ZCMD="$ZCMD \" \""
fi
ZCMD="$ZCMD \"$(menuitem_im ~/.xinput.d/$i)\""
else
if [ "$PREVIOUS" = "$i" ]; then
ZCMD="$ZCMD TRUE"
else
ZCMD="$ZCMD FALSE"
fi
ZCMD="$ZCMD $i"
if [ "$PREVIOUS_SYS" = "$i" ]; then
ZCMD="$ZCMD default"
else
ZCMD="$ZCMD \" \""
fi
ZCMD="$ZCMD \"$(menuitem_im $i)\""
fi
done
ZCMD="$ZCMD FALSE REMOVE \" \" \"Remove user choice to enable system choice\""
vecho "$ZCMD0 $ZCMD"
SEL=$(eval $ZCMD0 $ZCMD)
if [ -z "$SEL" ]; then
SEL=$PREVIOUS
fi
ZMES="No user configuration enabled for $LNG."
if [ -n "$SEL" ]; then
if [ "$SEL" != "REMOVE" ]; then
if [ -r "$DOTXINPUT_PATH/$SEL" ] ; then
ln -fs $DOTXINPUT_PATH/$SEL ${DOTXINPUT_PATH}/$LNG
ZMES="User configuration $(menuitem_im $SEL) enabled for $LNG."
else
ln -fs $XINPUT_PATH/$SEL ${DOTXINPUT_PATH}/$LNG
ZMES="User configuration $(menuitem_im $SEL) enabled for $LNG."
fi
else
if [ -h "$DOTXINPUT_PATH/$LNG" ] ; then
rm ${DOTXINPUT_PATH}/$LNG
vecho "${DOTXINPUT_PATH}/$LNG removed"
ZMES="User configuration removed for $LNG."
fi
fi
fi
zenity --info --text "Please read /usr/share/doc/im-switch/README.Debian.gz . \n\n$ZMES\n\nRestart the X session to activate the selected Imput Method."
}
help() {
echo "Input Method Switcher: im-switch Version=$VER"
echo ""
echo "\"${0##*/}\" configures the input method to be automatically switched based "
echo "on the locale (ll_CC) using Debian \"update-alternatives\" mechanism."
echo "When \"${0##*/}\" is invoked from root user, it sets system wide alternatives."
echo ""
echo "Usage: ${0##*/} [-v][-z ll_CC] -s inputmethodname"
echo " to set a specific input method for the language"
echo " ${0##*/} [-v][-z ll_CC] -c"
echo " to set an input method for the language by menu"
echo " ${0##*/} [-v][-z ll_CC] -a"
echo " to revert to the default input method for the language"
echo " ${0##*/} [-v][-z ll_CC] -l"
echo " to list current settings and available input methods for"
echo " the language, and also all the available languages"
echo " ${0##*/} -h"
echo " to show this help"
echo ""
echo "The \"ll_CC\" argument of -z takes the form \"<language>_<teritory>\" and "
echo "is used to override the current locale (ISO 639 / ISO 3188) : eg \"-z ja_JP\""
echo ""
echo "The use of -v option produces verbose outputs."
echo ""
}
ORGAT="$@"
while getopts "vfz:als:ch" OPTION; do
case $OPTION in
v) VERBOSE=1;;
z) vlang; LNG="$OPTARG"; LNG=${LNG%@*}; LNG=${LNG%.*};;
a) vlang; auto; exit 0;;
l) vlang; list; exit 0;;
s) vlang; setalt "$OPTARG"; exit 0;;
c) vlang; cfgalt; exit 0;;
h) vlang; help; exit 0;;
?) errcmd; exit 1;;
esac
done
# If no option --> Menu use under X :-)
vlang
cfgalt
exit 0
|