OSDN Git Service

[update] : Slick gtk command
[alterlinux/dmc.git] / dmc
1 #!/usr/bin/env bash
2 #
3 # Yamada Hayao
4 # Twitter: @Hayao0819
5 # Email  : hayao@fascode.net
6 #
7 # (c) 2019-2021 Fascode Network.
8 #
9 # dmc
10 #
11 # LICENSE: THE SUSHI-WARE LICENSE
12 # https://github.com/MakeNowJust/sushi-ware
13 #
14 #
15 # 参考資料
16 # https://qiita.com/laikuaut/items/4bc07eabce56ee30812d
17 # https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51
18
19 script_usage(){
20     echo "usage: dmc [options] [command]"
21     echo
22     echo "A simple tool for switching LightDM Greeters"
23     echo
24     echo " LightDM command:"
25     echo "    autologin [username] [session]    Set up automatic login (with blank username to disable)"
26     echo "    greeter                           Run greeter setup wizard"
27     echo "    greeter-create [file]             Set the specified executable file as Greeter"
28     echo "    greeter-change [greeter]          Specify the greeter to use"
29     echo "    greeter-edit [greeter]            Edit the greeter configs"
30     echo "    greeter-list                      Show a list of currently installed Greeters"
31     echo "    remove                            Removes all changes made by this command"
32     echo "    edit                              Edit lightdm config"
33     echo "    show-config                       Show current settings"
34     echo
35     echo " GDM command:"
36     echo "    autologin [username] [session]    Set up automatic login (with blank username to disable)"
37     echo "    cursor                            Run cursor selection wizard"
38     echo "    cursor-change [cursor]            Specify the cursor theme"
39     echo "    cursor-list                       Show a list of cursor theme"
40     echo "    sound [true or false]             Toggle the sound when an event occurs"
41     echo "    logo [image]                      Specify the logo of the login screen"
42     echo "    tap [true or false]               Toggle whether to recognize the tap as a click"
43     echo "    accessibility [true or false]     Toggle whether to show accessibility menu"
44     echo "    root-login [true or false]        Toggle whether to enable root login"
45     echo
46     echo " Webkit2 command:"
47     echo "    theme                             Run theme selection wizard"
48     echo "    theme-change [theme]              Specify the theme"
49     echo
50     echo " Qtquick command:"
51     echo "    back                              Specify the background image"
52     echo
53     echo " Slick command:"
54     echo "    back [image]                      Specify the background image"
55     echo "    grid [true or false]              Toggle whether to show grid"
56     echo "    icon                              Run icon theme selection wizard"
57     echo "    gtk                               Run gtk theme selection wizard"
58     echo "    gtk-change [theme]                Specify gtk theme"
59     echo
60     echo " SDDM command:"
61     echo "    autologin [username] [session]    Set up automatic login (with blank username to disable)"
62     echo "    cursor                            Run cursor selection wizard"
63     echo "    cursor-change [cursor]            Specify the cursor theme"
64     echo "    numlock [true or false]           Toggle whether to enable Numlock force"
65     echo "    tty [int number]                  The lowest virtual terminal number that will be used"
66     echo "    theme                             Run theme selection wizard"
67     echo "    theme-change [theme]              Specify the theme"
68     echo
69     echo " LXDM command:"
70     echo "    autologin [username] [session]    Set up automatic login (with blank username to disable)"
71     echo "    back [image]                      Specify the background image"
72     echo "    session                           Run default session selection wizard"
73     echo "    session-change [session]          Specify the default session"
74     echo "    remove-last                       Remove last selected setting"
75     echo "    edit-script                       Edit the script"
76     echo
77     echo " General option:"
78     echo "    -m | --mode [mode name]           Specifiy the target you want to set"
79     echo "    -e | --editer [editor path]       Specifiy the editor to use for editing"
80     echo "    -h | --help                       This help message and exit"
81     echo "    --non-interactive                 Run in non-interactive mode"
82     echo "    --no-check-target                 No check the target for the selected mode"
83     echo "    --noroot                          No check root permission"
84     echo "    --write-all-files                 Allows rewriting of all configuration files"
85     echo
86     echo " Supported modes:"
87     echo "    Display managers: lightdm, gdm, sddm, lxdm"
88     echo "    LightDM greeters: webkit2, qtquick, slick"
89     echo
90     echo " Default mode: ${DISPLAY_MANAGER}"
91     echo
92     echo " This tool is incomplete and still under development."
93     echo " If you find a bug, please report it on GitHub."
94     echo " https://github.com/FascodeNet/dmc"
95     echo
96 }
97
98 set -eu
99
100 # エラー
101 msg_error() {
102     echo "${@}" 1>&2
103 }
104
105 # 警告
106 msg_warn() {
107     echo "${@}" 1>&2
108 }
109
110 # rootチェック
111 check_root(){
112     if [[ "${NOROOT}" = false ]] && (( "${UID}" != 0 )); then
113         msg_error "You have to run as root"
114         exit 1
115     fi
116 }
117
118 # 数値チェック
119 check_int(){
120     set +e
121     #if (( "$(expr "${1}" + 1 >/dev/null 2>&1; printf "${?}")" < 2 )); then
122     if printf "%s" "${1}" | grep -E "^[0-9]+$" 1>/dev/null 2>&1; then
123         set -e
124         return 0
125     else
126         set -e
127         return 1
128     fi
129 }
130
131 check_bool(){
132     if [[ -n "${1}" ]] && { [[ "${1}" = "true" ]] ||[[ "${1}" = "false" ]]; }; then
133         return 0
134     else
135         return 1
136     fi
137 }
138
139 # コマンドラッパー
140 wrapper(){
141     local _command="${1}"
142     shift 1
143     if which "${_command}" >/dev/null 2>&1; then
144         $(which "${_command}") "${@}"
145     else
146         msg_error "${_command} was not found"
147         exit 1
148     fi
149 }
150
151 # crudini ラッパー
152 crudini(){
153     wrapper crudini "${@}"
154 }
155
156 # jq ラッパー
157 jq(){
158     wrapper jq "${@}"
159 }
160
161 # 指定されたコマンドが現在のモードで実行可能かどうかを判定する
162 check_command_dm(){
163     if ! printf "%s\n" "${@}" | grep -xE "${DISPLAY_MANAGER}" >/dev/null 2>&1; then
164         msg_error "This command (${COMMAND}) is not available in the current mode (${DISPLAY_MANAGER})."
165         exit 1
166     fi
167 }
168
169 # 現在のモードのメインバイナリが存在しているかどうか確認する
170 check_main_binary(){
171     if [[ -z "${MAIN_BINARY["${DISPLAY_MANAGER}"]+SET}" ]]; then
172         msg_warn "The main binary for the selected mode is not set."
173     elif [[ ! -f "${MAIN_BINARY["${DISPLAY_MANAGER}"]}" ]]; then
174         msg_error "The target for the selected mode is not installed."
175         exit 1
176     fi
177 }
178
179 # カーソルテーマの一覧を取得
180 get_cursor_theme(){
181     # カーソルテーマの一覧を取得
182     # 参考: https://wiki.archlinux.jp/index.php/%E3%82%AB%E3%83%BC%E3%82%BD%E3%83%AB%E3%83%86%E3%83%BC%E3%83%9E
183     # 参考: https://wiki.archlinux.jp/index.php/GDM
184     #echo "Searching cursor themes..." 1>&2
185     local _dir _cursor_theme_dir_list _find_cursor_dir_list=("/usr/share/icons" "${HOME}/.local/share/icons" "${HOME}/.icons")
186     for _dir in "${_find_cursor_dir_list[@]}"; do
187         if [[ -d "${_dir}" ]]; then
188             while read -r line; do
189                 _cursor_theme_dir_list+=("${line}")
190             done < <(find "${_dir}" -type d -name "cursors" -print0 | xargs -0 -i dirname {} | sort)
191         fi
192     done
193     unset _dir _find_cursor_dir_list
194     
195     local _cursor_theme _cursor_theme_name _name
196     for _cursor_theme in "${_cursor_theme_dir_list[@]}"; do
197         _name="$(grep -E "^Name=" "${_cursor_theme}/cursor.theme" 2> /dev/null | sed "s|^Name=||g")"
198         if [[ -z "${_name}" ]]; then
199             _name="$(basename "${_cursor_theme}")"
200         fi
201         _cursor_theme_name+=("${_name}")
202     done
203     printf "%s\n" "${_cursor_theme_name[@]}"
204 }
205
206 # GTKテーマの一覧を取得
207 get_gtk_theme(){
208     echo "Loading GTK themes..." >&2
209     local _dir _find_theme_dir_list=("/usr/share/themes" "${HOME}/.local/share/themes" "${HOME}/.themes")
210     for _dir in "${_find_theme_dir_list[@]}"; do
211         if [[ -d "${_dir}" ]]; then
212             while read -r line; do
213                 _gtk_theme_dir_list+=("${line}")
214             done < <(find "${_dir}" -type d -name "gtk-*" -print0 | xargs -0 -i dirname {} | tr " " "\n" | sort | uniq)
215         fi
216     done
217
218     local _theme_name
219     for _dir in "${_gtk_theme_dir_list[@]}"; do
220         _theme_name="$(crudini --get "${_dir}/index.theme" 'Desktop Entry' "Name" 2> /dev/null ;:)"
221         if [[ -z "${_theme_name}" ]]; then
222             continue
223         else
224             _gtk_theme_name_list+=("${_theme_name}")
225         fi
226     done
227     
228     printf "%s\n" "${_gtk_theme_name_list[@]}" | sort | uniq
229 }
230
231 get_icon_theme(){
232     echo "Loading icons..." >&2
233     local _dir _find_theme_dir_list=("/usr/share/icons" "${HOME}/.local/share/icons" "${HOME}/.icons")
234     for _dir in "${_find_theme_dir_list[@]}"; do
235         if [[ -d "${_dir}" ]]; then
236             while read -r line; do
237                 _icon_theme_dir_list+=("${line}")
238             done < <(find "${_dir}" -type f -name "index.theme" -print0 | xargs -0 -i dirname {} | tr " " "\n" | sort | uniq)
239         fi
240     done
241
242     local _theme_name
243     for _dir in "${_icon_theme_dir_list[@]}"; do
244         _theme_name="$(crudini --get "${_dir}/index.theme" 'Icon Theme' "Name" 2> /dev/null ;:)"
245         if [[ -z "${_theme_name}" ]]; then
246             continue
247         else
248             _gtk_theme_name_list+=("${_theme_name}")
249         fi
250     done
251     
252     printf "%s\n" "${_gtk_theme_name_list[@]}" | sort | uniq
253 }
254
255 get_xorg_session(){
256     find "/usr/share/xsessions" -type f -print0 -name "*.desktop" | xargs -0 -I{} bash -c 'basename {} | sed "s|.desktop||g"'
257 }
258
259 get_wayland_session(){
260     find "/usr/share/wayland-sessions" -type f  -print0 -name "*.desktop" | xargs -0 -I{} bash -c 'basename {} | sed "s|.desktop||g"'
261 }
262
263 # 質問を行う関数
264 # Returns only the selected result to standard output
265 # ask_question -d <デフォルト値> -p <質問文> <選択肢1> <選択肢2> ...
266 ask_question(){
267     local arg OPTARG OPTIND
268     local _default="" _choice_list _count _choice _question
269     while getopts "d:p:" arg; do
270         case "${arg}" in
271             d) _default="${OPTARG}" ;;
272             p) _question="${OPTARG}" ;;
273             *) exit 1 ;;
274         esac
275     done
276     shift $((OPTIND - 1))
277     _choice_list=("${@}")
278
279     # 選択肢に関するエラー
280     if (( ${#_choice_list[@]} < 0 )); then
281         msg_error "An exception error has occurred."
282         exit 1
283     fi
284
285     # 選択肢が1つしか無いならばそのまま値を返す
286     if (( ${#_choice_list[@]} <= 1 )); then
287         echo "${_choice_list[*]}"
288         return 0
289     fi
290
291     if [[ -v _question ]] && [[ ! "${_question}" = "" ]]; then
292         echo -e "${_question}" >&2
293     fi
294
295     for (( _count=1; _count<=${#_choice_list[@]}; _count++)); do
296         _choice="${_choice_list[$(( _count - 1 ))]}"
297         if [[ ! "${_default}" = "" ]] && [[ "${_choice}" = "${_default}" ]]; then
298             echo " * ${_count}: ${_choice}" >&2
299         else
300             echo "   ${_count}: ${_choice}" >&2
301         fi
302         unset _choice
303     done
304     echo -n "(1 ~ ${#_choice_list[@]}) > " >&2
305     read -r _input
306
307     # 回答を解析
308     if check_int "${_input}"; then
309         # 数字が入力された
310         if (( 1 <= _input)) && (( _input <= ${#_choice_list[@]} )); then
311             _choice="${_choice_list[$(( _input - 1 ))]}"
312         else
313             return 1
314         fi
315     else
316         # 文字が入力された
317         if printf "%s\n" "${_choice_list[@]}" | grep -x "${_input}" 1>/dev/null 2>&1; then
318             _choice="${_input}"
319         else
320             return 1
321         fi
322     fi
323     echo "${_choice}"
324     return 0
325 }
326
327 # デスクトップセッションを聞く
328 ask_session(){
329     local _session
330     if (( $(get_xorg_session | wc -l) <= 1 )); then
331         _session="$(get_xorg_session)"
332     elif [[ "${NON_INTERACTIVE}" = true ]]; then
333         # 非対話モード
334         # ~/.dmrcの値を設定します
335         _session="$(grep -E '^Session=' "${HOME}/.dmrc" 2> /dev/null | cut -d '=' -f 2)"
336         if [[ -z "${autologin_session}" ]]; then
337             msg_error "Failed to set the session."
338             msg_error "Not specified and ~/.dmrc does not exist either."
339             exit 1
340         fi
341     else
342         while read -r line; do
343             _session_list+=("${line}")
344         done < <(get_xorg_session)
345         if ! session="$(ask_question -p "Select the desktop session to autologin" "${_session_list[@]}")"; then
346             msg_error "Please enter the correct session name."
347             exit 1
348         fi
349         if [[ -f "/usr/share/xsessions/${session}.desktop" ]]; then
350             _session="${session}"
351         else
352             msg_error "Please enter the correct session name."
353             exit 1
354         fi
355     fi
356     echo "${_session}"
357 }
358
359 # セッションが利用可能かどうか確認する
360 # check_session <session>
361 check_session(){
362     if [[ ! -f "/usr/share/xsessions/${1}.desktop" ]]; then
363         # 存在しないセッションが指定された場合
364         msg_error "This is a session (${1}) that does not exist."
365         exit 1
366     fi
367 }
368
369 # セッションのバイナリを取得する
370 # get_session <session name>
371 get_session(){
372     check_session "${1}"
373     local session_exec="$(crudini --get "/usr/share/xsessions/${1}.desktop" "Desktop Entry" "Exec")"
374     if [[ ! -f "${session_exec}" ]]; then
375         session_exec="$(type -p "${session_exec}")"
376     fi
377     echo -n "${session_exec}"
378     return 0
379 }
380
381 # ユーザーをグループに追加する
382 # add_user_to_group <user> <group>
383 add_user_to_group(){
384     if ! getent passwd "${1}" 1> /dev/null 2>&1; then
385         echo "${1} is a non-existent user."
386         exit 1
387     fi
388
389     if ! getent group "${2}" 1> /dev/null 2>&1; then
390         LANG=C groupadd -r "${2}"
391     fi
392     LANG=C gpasswd -a "${1}" "${2}"
393 }
394
395 # MIMEファイルタイプを返す
396 # get_filetype <file>
397 get_filetype(){
398     file -inb "${1}" | cut -d ";" -f 1
399 }
400
401 # MIMEファイルタイプを判別する
402
403 # check_filetype <ファイルタイプ> <ファイルパス>
404 check_filetype(){
405     local _type="${1}" _path="${2}"
406
407     # ファイルタイプに/が含まれているかどうか
408     if echo "${_type}" | grep -E "^.+/.+$" >/dev/null 2<&1; then
409         # 含まれていたらファイルタイプを完全一致で判定する\
410         if [[ "${_type}" = "$(get_filetype "${_path}")" ]]; then
411             return 0
412         fi
413     else
414         # 含まれていなかったらファイルタイプをメインタイプのみで判定する
415         if [[ "${_type}" = "$(get_filetype "${_path}" | cut -d "/" -f 1 )" ]]; then
416             return 0
417         fi
418     fi
419     # 正常終了しなかったので異常終了
420     return 1
421 }
422
423
424 #== LightDM用の汎用関数 ==#
425 # キーが設定されている設定ファイル
426 lightdm_get_source_file(){
427     local key="${1}"
428     local source_name="$(lightdm --show-config 2>&1 | grep -E "^[A-Z]  ${key}=" | cut -d ' ' -f 1)"
429     local source_path="$(lightdm --show-config 2>&1 | grep -x -A "$(lightdm --show-config 2>&1 | wc -l)" "Sources:" | grep -xv "Sources" | grep -E "^${source_name}  " | sed "s|^${source_name}  ||g")"
430     if [[ -n "${source_path}" ]]; then
431         echo -n "${source_path}"
432     else
433         echo -n ""
434     fi
435 }
436
437
438 # 設定ファイルの値を変更する
439 lightdm_set_config(){
440     local key="${1}" value="${2}" file=${3-${DISPLAY_MANAGER_CONFIG["lightdm"]}}
441     if [[ "${WRITE_ALL_FILES}" = true ]] && [[ -n "$(lightdm_get_source_file "${1}")" ]]; then
442         crudini --set "$(lightdm_get_source_file "${1}")" 'Seat:*' "${key}" "${value}"
443     else
444         crudini --set "${file}" 'Seat:*' "${key}" "${value}"
445     fi
446
447     if [[ ! "$(lightdm_get_value "${key}")" = "${value}" ]]; then
448         msg_error "Failed to change the setting value. A value has already been set for $(lightdm_get_source_file "${1}")"
449         msg_error "lightdm-config does not manipulate other configuration files for safety. Comment out the settings in that file."
450     fi
451 }
452
453 # 設定ファイルのキーを削除する
454 lightdm_remove_key(){
455     local key="${1}" _config
456     if grep -E "^ ?${key}.+" "${DISPLAY_MANAGER_CONFIG["lightdm"]}" 1>/dev/null 2>&1; then
457         sed -i -r "s|^ ?${key} ?=.+||g" "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
458         sed -i '/^$/d' "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
459     fi
460 }
461
462 # 設定ファイルを作成
463 lightdm_init_configs(){
464     check_root
465     if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lightdm"]}" ]]; then
466         mkdir -p "$(dirname "${DISPLAY_MANAGER_CONFIG["lightdm"]}")"
467         touch "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
468         echo "[Seat:*]" > "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
469     fi
470 }
471
472 # 現在設定されている値を取得する
473 lightdm_get_value(){
474     local _current_value="$(lightdm --show-config 2>&1 | grep -E "^[A-Z]  ${1}=" | sed "s|^[A-Z]  ||g" | cut -d "=" -f "2")"
475     if [[ "${_current_value}" ]]; then
476         echo -n "${_current_value}"
477         return 0
478     else
479         echo -n ""
480         return 0
481     fi
482 }
483
484 #== LightDM用コマンド ==#
485 # greeter-changeコマンド
486 command_lightdm_greeter_change() {
487     # 引数チェック
488     if [[ -z "${1}" ]] || [[ "${1}" = "" ]]; then
489         msg_error "Please specify Greeter."
490         exit 1
491     fi
492
493     # 指定されたGreeterが正しいか確認
494     if ! printf "%s\n" "${LIGHTDM_GREETERS[@]}" | grep -x "${1}" > /dev/null 2>&2; then
495         msg_error "The greeter (${1}) doesn't exist."
496         exit 1
497     else
498         lightdm_set_config "greeter-session" "${1}"
499     fi
500 }
501
502 # greeter-createコマンド
503 command_lightdm_greeter_create(){
504     if [[ -z "${1}" ]] || [[ "${1}" = "" ]]; then
505         msg_error "Please specify Greeter."
506         exit 1
507     fi
508     if [[ ! -f "${1}" ]]; then
509         msg_error "${1} does not exist."
510         exit 1
511     fi
512     if [[ ! -x "${1}" ]]; then
513         msg_error "hoge is not an executable file."
514         exit 1
515     fi
516
517     local path="${1}"
518     local filename="$(basename "${1}")"
519
520     if [[ -f "/usr/share/xgreeters/${filename}.desktop" ]]; then
521         msg_error "Greeter with the same name already exists."
522         exit 1
523     fi
524     cat > "/usr/share/xgreeters/${filename}.desktop"  <<EOF
525 [Desktop Entry]
526 Name=LightDM custom Greeter ${filename}
527 Comment=LightDM Greeter
528 Exec=${path}
529 Type=Application
530 EOF
531 }
532
533 # greeter-listコマンド
534 command_lightdm_greeter_list() {
535     echo "Available Lightdm greeter list:"
536     local _greeter
537     for _greeter in "${LIGHTDM_GREETERS[@]}"; do
538         if [[ "${_greeter}" = "${LIGHTDM_CURRENT_GREETER}" ]]; then
539             echo " * ${_greeter}"
540         else
541             echo "   ${_greeter}"
542         fi
543     done
544 }
545
546 # greeterコマンド
547 run_greeter_wizard(){
548     # グリーターの数を確認
549     if (( ${#LIGHTDM_GREETERS[@]} < 1 )); then
550         msg_error "LightDM Greeter was not found."
551         exit 1
552     fi
553
554     # 質問する
555     local _greeter
556     if ! _greeter="$(ask_question -p "Please select the greeter to use." -d "${LIGHTDM_CURRENT_GREETER}" "${LIGHTDM_GREETERS[@]}")"; then
557         run_greeter_wizard
558         exit 0
559     fi
560
561     # 結果に応じて処理を実行
562     if [[ -n "${_greeter}" ]]; then
563         command_lightdm_greeter_change "${_greeter}"
564     else
565         run_greeter_wizard
566         exit 0
567     fi
568
569     if [[ ! "${LIGHTDM_CURRENT_GREETER}" = "${_greeter}" ]]; then
570         echo "Changed greeter to ${_greeter}"
571     fi
572 }
573
574 # removeコマンド
575 command_lightdm_remove(){
576     if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lightdm"]}" ]]; then
577         return 0
578     else
579         local _yes_or_no
580         echo -ne "Are you sure you want to delete all settings?\nThis change is irreversible.\n (y or n) > "
581         read -r -n 1 _yes_or_no
582         if [[ "${_yes_or_no}" = "y" ]]; then
583             mv "${DISPLAY_MANAGER_CONFIG["lightdm"]}" "${DISPLAY_MANAGER_CONFIG["lightdm"]}.disabled"
584         fi
585     fi
586 }
587
588 # greeter-edit
589 command_lightdm_greeter_edit(){
590     if [[ "${NON_INTERACTIVE}" = true ]]; then
591         msg_error "You cannot use this command in non-interactive mode."
592         exit 1
593     fi
594     local _greeter="${1:-${LIGHTDM_CURRENT_GREETER}}"
595     if [[ -z "${GREETER_CONFIG["${_greeter}"]+SET}" ]]; then
596         msg_error "This Greeter is not currently supported."
597         msg_error "Please report the problem here."
598         msg_error "https://github.com/FascodeNet/lightdm-config/issues"
599         exit 1
600     else
601         if [[ -z "${1}" ]] || [[ "${1}" = "" ]]; then
602             msg_warn "Greeter was not specified. Open the currently configured Greeter configuration file."
603             echo -n "(Enter to continue) > "
604             read -r
605         fi
606         set -u
607         bash -c "${USE_EDITOR} ${GREETER_CONFIG["${_greeter}"]}"
608         exit
609     fi
610 }
611
612 # edit
613 command_lightdm_edit(){
614     if [[ "${NON_INTERACTIVE}" = true ]]; then
615         msg_error "You cannot use this command in non-interactive mode."
616         exit 1
617     fi
618     for _config in "${LIGHTDM_LOADED_CONFIG[@]}"; do
619         echo -ne "Edit ${_config} ? (y or n)> "
620         read -r -n 1 _yes_or_no
621         echo
622         if [[ "${_yes_or_no}" = "y" ]]; then
623             bash -c "${USE_EDITOR} ${_config}"
624         fi
625     done
626 }
627
628 # autologin
629 command_lightdm_auto_login(){
630     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
631         # 既に自動ログインが設定されているかを確認
632         local autologin_user="$(lightdm_get_value autologin-user)"
633         if [[ -n "${autologin_user}" ]]; then
634             # autologinを無効化
635             for _autologin in "autologin-guest" "autologin-user" "autologin-user-timeout" "autologin-in-background" "autologin-session"; do
636                 remove_key "${_autologin}"
637             done
638             echo "Canceled automatic login of ${autologin_user}"
639         fi
640     else
641         local autologin_user="${1}" autologin_session
642         if [[ -v 2 ]]; then
643             autologin_session="${2}"
644         fi
645
646         # セッションを設定 (WayLandのセッションは現在サポートされていません)
647         if [[ -z "${autologin_session+SET}" ]]; then
648             autologin_session="$(ask_session)"
649         else
650             # 既に値が設定済み
651             check_session "${autologin_session}"
652         fi
653
654         # autologin グループを設定
655         add_user_to_group "${autologin_user}" "autologin"
656
657         # 設定を書き込み
658         lightdm_set_config "autologin-guest" "false"
659         lightdm_set_config "autologin-user" "${autologin_user}"
660         lightdm_set_config "autologin-user-timeout" "0"
661         lightdm_set_config "autologin-in-background" "false"
662         lightdm_set_config "autologin-session" "${autologin_session}"
663
664         echo "${autologin_user} will automatically log in with ${autologin_session}"
665     fi
666
667 }
668
669 # show-config
670 command_lightdm_show_config(){
671    lightdm --show-config 2>&1 
672 }
673
674 #== GDM用の汎用関数 ==#
675 gdm_init_configs(){
676     check_root
677     if [[ ! -f "/etc/dconf/profile/gdm" ]]; then
678         mkdir -p "/etc/dconf/profile"
679         touch "/etc/dconf/profile/gdm"
680         echo -e "user-db:user\nsystem-db:gdm\nfile-db:/usr/share/gdm/greeter-dconf-defaults" > "/etc/dconf/profile/gdm"
681     fi
682
683     local _file
684     for _file in "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}"; do
685         if [[ ! -f "${_file}" ]]; then
686             mkdir -p "$(dirname "${_file}")"
687             touch "${_file}"
688         fi
689     done
690 }
691
692 # gdm_dconf_set_config <dconf path> <key> <value>
693 gdm_dconf_set_config(){
694     if check_int "${3}" || check_bool "${3}"; then
695         crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${1}" "${2}" "${3}"
696     else
697         crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${1}" "${2}" "\"${3}\""
698     fi
699     gdm_update
700 }
701
702 # gdm_dconf_get_value <dconf path> <key>
703 gdm_dconf_get_value(){
704     find "/etc/dconf/db/gdm.d/" -type f -print0 | xargs -0i cat {} | crudini --get - "${1}" "${2}" | sed "s|^[\"\']||g" | sed "s|[\"\']$||g"
705 }
706
707 # gdm_custom_get_value <section> <key>
708 gdm_custom_get_value(){
709     crudini --get "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}"
710 }
711
712 # gdm_custom_set_config <section> <key> <value>
713 gdm_custom_set_config(){
714     if check_int "${3}" || check_bool "${3}"; then
715         crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}" "${3}"
716     else
717         crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}" "\"${3}\""
718     fi
719     gdm_update
720 }
721
722 gdm_update(){
723     dconf update
724 }
725
726
727 #== GDM用コマンド ==#
728 command_gdm_logo(){
729     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
730         msg_error "Please specify the image of background"
731         exit 1
732     fi
733     if [[ ! -f "${1}" ]]; then
734         msg_error "${1} was not found."
735         exit 1
736     fi
737
738     local _backgrounf_file="/usr/share/backgrounds/gdm/background"
739     mkdir -p "$(dirname "${_backgrounf_file}")"
740     cp "${1}" "${_backgrounf_file}"
741     chmod 644 "${_backgrounf_file}"
742     
743     gdm_dconf_set_config "org/gnome/login-screen" "logo" "${_backgrounf_file}"
744 }
745
746 command_gdm_cursor_wizard(){
747     # カーソル一覧を取得
748     local cursor_themes _current_theme="$(gdm_dconf_get_value "org/gnome/desktop/interface" "cursor-theme")"
749     while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
750
751     # 一覧を生成
752     if ! _cursor_theme="$(ask_question -d "${_current_theme}" -p "Please select the cursor theme to use." "${cursor_themes[@]}")"; then
753         run_greeter_wizard
754         exit 0
755     fi
756
757     if [[ -n "${_cursor_theme}" ]]; then
758         command_gdm_cursor_change "${_cursor_theme}"
759     else
760         command_gdm_cursor_wizard
761         exit 0
762     fi
763
764     if [[ ! "${_current_theme}" = "${_cursor_theme}" ]]; then
765         echo "Changed cursor to ${_cursor_theme}"
766     fi
767 }
768
769 command_gdm_cursor_change(){
770     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
771         msg_error "Please specify the cursor theme"
772         exit 1
773     fi
774     local cursor_themes
775     while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
776     if ! printf "%s\n" "${cursor_themes[@]}" | grep -x "${1}" 1>/dev/null 2>&1; then
777         msg_error "The cursor theme (${1}) was not found"
778         exit 1
779     fi
780     gdm_dconf_set_config "org/gnome/desktop/interface" "cursor-theme" "${1}"
781 }
782
783 command_gdm_sound(){
784     local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")"
785     if ! check_bool "${_arg}"; then
786         msg_error "Please specify true or false"
787         exit 1
788     fi
789     gdm_dconf_set_config "org/gnome/desktop/sound" "event-sounds" "${_arg}"
790 }
791
792 command_gdm_tap(){
793     local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")"
794     if ! check_bool "${_arg}"; then
795         msg_error "Please specify true or false"
796         exit 1
797     fi
798     gdm_dconf_set_config "org/gnome/desktop/peripherals/touchpad" "tap-to-click" "${_arg}"
799 }
800
801 # autologin
802 command_gdm_auto_login(){
803     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
804         # 既に自動ログインが設定されているかを確認
805         local autologin="$(gdm_custom_get_value daemon AutomaticLoginEnable)"
806         if [[ "${autologin}" = "True" ]]; then
807             gdm_custom_set_config "daemon" "AutomaticLoginEnable" "False"
808             echo "Canceled automatic login of $(gdm_custom_get_value "daemon" "AutomaticLogin")"
809         fi
810     else
811         local autologin_user="${1}" autologin_session
812         if [[ -v 2 ]]; then
813             autologin_session="${2}"
814         fi
815
816         # セッションを設定 (WayLandのセッションは現在サポートされていません)
817         if [[ -z "${autologin_session+SET}" ]]; then
818             autologin_session="$(ask_session)"
819         else
820             # 既に値が設定済み
821             check_session "${autologin_session}"
822         fi
823
824         # autologin グループを設定
825         add_user_to_group "${autologin_user}" "autologin"
826
827         # 設定を書き込み
828         gdm_custom_set_config "daemon" "AutomaticLoginEnable" "True"
829         gdm_custom_set_config "daemon" "AutomaticLogin" "${autologin_user}"
830         
831         # セッションを指定
832         crudini --set "/var/lib/AccountsService/users/${autologin_user}" "User" "Session" "${autologin_session}"
833         crudini --set "/var/lib/AccountsService/users/${autologin_user}" "User" "XSession" "${autologin_session}"
834
835         echo "${autologin_user} will automatically log in with ${autologin_session}"
836     fi
837
838 }
839
840 # accessibility コマンド
841 command_gdm_accessibility(){
842     local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")"
843     if ! check_bool "${_arg}"; then
844         msg_error "Please specify true or false"
845         exit 1
846     fi
847     gdm_dconf_set_config "org/gnome/desktop/interface" "toolkit-accessibility" "${_arg}"
848 }
849
850 # root-login コマンド
851 command_gdm_root_login(){
852     local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")"
853     if ! check_bool "${_arg}"; then
854         msg_error "Please specify true or false"
855         exit 1
856     fi
857     gdm_custom_set_config "daemon" "AllowRoot" "${_arg}"
858 }
859
860 #== Webkit2用の汎用関数 ==#
861 webkit2_init_configs(){
862     check_root
863     if [[ ! -f "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" ]]; then
864         mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-webkit2-greeter"]}")"
865         touch "${GREETER_CONFIG["lightdm-webkit2-greeter"]}"
866     fi
867 }
868
869 # webkit2_get_value <section> <key>
870 webkit2_get_value(){
871     crudini --get "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" "${1}" "${2}"
872 }
873
874 # webkit2_set_config <section> <key> <value>
875 webkit2_set_config(){
876     crudini --set "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" "${1}" "${2}" "${3}"
877 }
878
879 #== webkit2用コマンド ==#
880 command_webkit2_theme_wizard(){
881     local _theme_list
882     while read -r line; do
883         _theme_list+=("${line}")
884     done < <(ls /usr/share/lightdm-webkit/themes)
885
886     local _current_theme=$(webkit2_get_value greeter webkit_theme | sed "s|\"||g")
887     local _theme
888     if ! _theme="$(ask_question -d "${_current_theme}" -p "Please select the theme to use." "${_theme_list[@]}")"; then
889         run_greeter_wizard
890         exit 0
891     fi
892     if [[ -n "${_theme}" ]]; then
893         command_webkit2_theme_change "${_theme}"
894         echo "Changed the theme to ${_theme}"
895     else
896         command_webkit2_theme_wizard
897         exit 0
898     fi
899     
900 }
901
902 command_webkit2_theme_change(){
903     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
904         msg_error "Please specify the theme name"
905         exit 1
906     fi
907     if [[ ! -d "/usr/share/lightdm-webkit/themes/${1}" ]]; then
908         msg_error "The specified theme (${1}) does not exist"
909         exit 1
910     fi
911
912     webkit2_set_config "greeter" "webkit_theme" "${1}"
913 }
914
915 #== Qtquick用の汎用関数 ==#
916 qtquick_init_configs(){
917     check_root
918     if [[ ! -f "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" ]] || [[ -z "$(cat "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")" ]]; then
919         mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")"
920         touch "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
921         #echo -e "{\n\n}\n" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
922         qtquick_set_config background_path "file:///hoge/fuga.png"
923         qtquick_set_config theme "qrc:/Login.qml"
924     fi
925 }
926
927 #qtquick_get_value <key>
928 qtquick_get_value(){
929     jq ".${1}" < "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
930 }
931
932 # command_qtquick_back <key> <value>
933 qtquick_set_config(){
934     local _tempfile="/tmp/$(basename "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")-$(base64 < "/dev/urandom" | fold -w 10 | head -n 1)"
935     cp "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" "${_tempfile}"
936     #cat "${_tempfile}" | jq -r ".${1}|=\"${2}\"" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
937     jq -r ".${1}|=\"${2}\"" < "${_tempfile}" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
938     chmod 644 "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
939 }
940
941 #== Qtquick用コマンド ==#
942 command_qtquick_back(){
943     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
944         msg_error "Please specify the image of background"
945         exit 1
946     fi
947     if [[ ! -f "${1}" ]]; then
948         msg_error "${1} was not found."
949         exit 1
950     fi
951
952     local _backgrounf_file="/usr/share/backgrounds/lightdm/qtquick-greeter"
953     mkdir -p "$(dirname "${_backgrounf_file}")"
954     cp "${1}" "${_backgrounf_file}"
955     chmod 644 "${_backgrounf_file}"
956     
957     qtquick_set_config "background_path" "file://${_backgrounf_file}"
958 }
959
960 #== slick用の汎用関数 ==#
961 slick_get_value(){
962     crudini --get "${GREETER_CONFIG["lightdm-slick-greeter"]}" "Greeter" "${1}"
963 }
964
965 slick_set_config(){
966     crudini --set "${GREETER_CONFIG["lightdm-slick-greeter"]}" "Greeter" "${1}" "${2}"
967 }
968
969 slick_init_configs(){
970     check_root
971     if [[ ! -f "${GREETER_CONFIG["lightdm-slick-greeter"]}" ]]; then
972         mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-slick-greeter"]}")"
973         touch "${GREETER_CONFIG["lightdm-slick-greeter"]}"
974         echo "[Greeter]" > "${GREETER_CONFIG["lightdm-slick-greeter"]}"
975     fi
976 }
977
978 #== Slick用コマンド ==#
979 command_slick_grid(){
980     local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")"
981     if ! check_bool "${_arg}"; then
982         msg_error "Please specify true or false"
983         exit 1
984     fi
985     slick_set_config "draw-grid" "${_arg}"
986 }
987
988 command_slick_back(){
989     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
990         msg_error "Please specify the image of background"
991         exit 1
992     fi
993     if [[ ! -f "${1}" ]]; then
994         msg_error "${1} was not found."
995         exit 1
996     fi
997
998     local _backgrounf_file="/usr/share/backgrounds/lightdm/slick-greeter"
999     mkdir -p "$(dirname "${_backgrounf_file}")"
1000     cp "${1}" "${_backgrounf_file}"
1001     chmod 644 "${_backgrounf_file}"
1002     
1003     slick_set_config "background" "${_backgrounf_file}"
1004 }
1005
1006
1007 command_slick_gtk_wizard(){
1008     local gtk_themes
1009     while read -r line; do gtk_themes+=("${line}"); done < <(get_gtk_theme)
1010
1011     # 質問する
1012     local _theme
1013     echo "Please select the theme to use."
1014     if ! _theme="$(ask_question "${gtk_themes[@]}")"; then
1015         command_slick_gtk_wizard
1016         exit 0
1017     fi
1018
1019     # 結果に応じて処理を実行
1020     if [[ -n "${_theme}" ]]; then
1021         command_slick_gtk_change "${_theme}"
1022     else
1023         command_slick_gtk_wizard
1024         exit 0
1025     fi
1026     echo "Changed theme to ${_theme}"
1027
1028 }
1029
1030 command_slick_gtk_change(){
1031     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
1032         msg_error "Please specify the theme"
1033         exit 1
1034     fi
1035     if [[ ! -d "/usr/share/themes/${1}" ]]; then
1036         msg_error "${1} was not found."
1037         exit 1
1038     fi
1039     slick_set_config "theme-name" "${1}"
1040 }
1041
1042 command_slick_icon_wizard(){
1043     local icons
1044     while read -r line; do icons+=("${line}"); done < <(get_icon_theme)
1045
1046     local _icon
1047     echo "Please select the icon theme to use."
1048     if ! _icon="$(ask_question "${icons[@]}")"; then
1049         command_slick_icon_wizard
1050         exit 0
1051     fi
1052
1053     if [[ -n "${_icon}" ]]; then
1054         slick_set_config "icon-theme-name" "${_icon}"
1055     else
1056         command_slick_icon_wizard
1057         exit 0
1058     fi
1059     echo "Changed icon theme to ${_icon}"
1060 }
1061
1062
1063 #== SDDM用の汎用関数 ==#
1064 # sddm_get_value <section> <key> <valye>
1065 sddm_get_value(){
1066     crudini --set "${DISPLAY_MANAGER_CONFIG["sddm"]}" "${1}" "${2}"
1067 }
1068
1069 # sddm_set_config <section> <key> <value>
1070 sddm_set_config(){
1071     crudini --set "${DISPLAY_MANAGER_CONFIG["sddm"]}" "${1}" "${2}" "${3}"
1072 }
1073
1074 # sddm_remove_key <section> <key>
1075 sddm_remove_key(){
1076     crudini --del "${DISPLAY_MANAGER_CONFIG["sddm"]}" "${1}" "${2}"
1077 }
1078
1079
1080 sddm_init_configs(){
1081     check_root
1082     if [[ ! -f "${DISPLAY_MANAGER_CONFIG["sddm"]}" ]]; then
1083         mkdir -p "$(dirname "${DISPLAY_MANAGER_CONFIG["sddm"]}")"
1084         sddm --example-config > "${DISPLAY_MANAGER_CONFIG["sddm"]}"
1085     fi
1086 }
1087
1088 #== SDDM用コマンド ==#
1089 command_sddm_auto_login(){
1090     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
1091         # 既に自動ログインが設定されているかを確認
1092         local autologin_user="$(sddm_get_value Autologin User)"
1093         if [[ -n "${autologin_user}" ]]; then
1094             sddm_remove_key "Autologin" "User"
1095             echo "Canceled automatic login of ${autologin_user}"
1096         fi
1097     else
1098         local autologin_user="${1}" autologin_session
1099         if [[ -v 2 ]]; then
1100             autologin_session="${2}"
1101         fi
1102
1103         # セッションを設定 (WayLandのセッションは現在サポートされていません)
1104         if [[ -z "${autologin_session+SET}" ]]; then
1105             autologin_session="$(ask_session)"
1106         else
1107             # 既に値が設定済み
1108             check_session "${autologin_session}"
1109         fi
1110
1111         # autologin グループを設定
1112         add_user_to_group "${autologin_user}" "autologin"
1113
1114         # 設定を書き込み
1115         sddm_set_config "Autologin" "User" "${autologin_user}"
1116         sddm_set_config "Autologin" "Session" "${autologin_session}"
1117
1118         echo "${autologin_user} will automatically log in with ${autologin_session}"
1119     fi
1120 }
1121
1122 command_sddm_cursor_wizard(){
1123     # カーソル一覧を取得
1124     local cursor_themes _current_theme="$(sddm_get_value "Theme" "CursorTheme")"
1125     while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
1126
1127     # 一覧を生成
1128     if ! _cursor_theme="$(ask_question -d "${_current_theme}" -p "Please select the cursor theme to use." "${cursor_themes[@]}")"; then
1129         command_sddm_cursor_wizard
1130         exit 0
1131     fi
1132
1133     if [[ -n "${_cursor_theme}" ]]; then
1134         command_sddm_cursor_change "${_cursor_theme}"
1135     else
1136         command_sddm_cursor_change
1137         exit 0
1138     fi
1139
1140     if [[ ! "${_current_theme}" = "${_cursor_theme}" ]]; then
1141         echo "Changed cursor to ${_cursor_theme}"
1142     fi
1143 }
1144
1145 command_sddm_cursor_change(){
1146     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
1147         msg_error "Please specify the cursor theme"
1148         exit 1
1149     fi
1150     local cursor_themes
1151     while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
1152     if ! printf "%s\n" "${cursor_themes[@]}" | grep -x "${1}" 1>/dev/null 2>&1; then
1153         msg_error "The cursor theme (${1}) was not found"
1154         exit 1
1155     fi
1156     sddm_set_config "Theme" "CursorTheme" "${1}"
1157 }
1158
1159 command_sddm_numlock(){
1160     local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")"
1161     if ! check_bool "${_arg}"; then
1162         msg_error "Please specify true or false"
1163         exit 1
1164     fi
1165     local _value
1166     if [[ "${_arg}" = true ]]; then
1167         _value="on"
1168     else
1169         _value="none"
1170     fi
1171     sddm_set_config "General" "Numlock" "${_value}"
1172 }
1173
1174 command_sddm_tty(){
1175     if ! check_int "${1}" || (( "${1}" < 1 )); then
1176         msg_error "Please enter an integer greater than 1"
1177         exit 1
1178     fi
1179     sddm_set_config "X11" "MinimumVT" "${1}"
1180 }
1181
1182 command_sddm_theme_wizard(){
1183     local _theme_list
1184     while read -r line; do
1185         _theme_list+=("${line}")
1186     done < <(find "/usr/share/sddm/themes/" -maxdepth 1 -mindepth 1 -type d -print0 | xargs -0 -I{} basename {})
1187
1188     local _theme _current_theme=$(sddm_get_value "Theme" "Current")
1189     if ! _theme="$(ask_question -d "${_current_theme}" -p "Please select the theme to use." "${_theme_list[@]}")"; then
1190         command_sddm_theme_wizard
1191         exit 0
1192     fi
1193     if [[ -n "${_theme}" ]]; then
1194         command_sddm_theme_change "${_theme}"
1195         echo "Changed the theme to ${_theme}"
1196     else
1197         command_sddm_theme_wizard
1198         exit 0
1199     fi
1200     
1201 }
1202
1203 command_sddm_theme_change(){
1204     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
1205         msg_error "Please specify the theme name"
1206         exit 1
1207     fi
1208     if [[ ! -d "/usr/share/sddm/themes/${1}" ]]; then
1209         msg_error "The specified theme (${1}) does not exist"
1210         exit 1
1211     fi
1212
1213     sddm_set_config "Theme" "Current" "${1}"
1214 }
1215
1216 #== LXDM用の汎用関数 ==#
1217 # sddm_get_value <section> <key> <valye>
1218 lxdm_get_value(){
1219     crudini --set "${DISPLAY_MANAGER_CONFIG["lxdm"]}" "${1}" "${2}"
1220 }
1221
1222 # sddm_set_config <section> <key> <value>
1223 lxdm_set_config(){
1224     crudini --set "${DISPLAY_MANAGER_CONFIG["lxdm"]}" "${1}" "${2}" "${3}"
1225 }
1226
1227 # sddm_remove_key <section> <key>
1228 lxdm_remove_key(){
1229     crudini --del "${DISPLAY_MANAGER_CONFIG["lxdm"]}" "${1}" "${2}"
1230 }
1231
1232
1233 lxdm_init_configs(){
1234     check_root
1235     if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lxdm"]}" ]]; then
1236         mkdir -p "$(dirname "${DISPLAY_MANAGER_CONFIG["lxdm"]}")"
1237         touch "${DISPLAY_MANAGER_CONFIG["lxdm"]}"
1238     fi
1239 }
1240
1241 #== LXDM用コマンド ==#
1242 command_lxdm_auto_login(){
1243     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
1244         # 既に自動ログインが設定されているかを確認
1245         local autologin_user="$(lxdm_get_value "base" "autologin")"
1246         if [[ -n "${autologin_user}" ]]; then
1247             sddm_remove_key "base" "autologin"
1248             echo "Canceled automatic login of ${autologin_user}"
1249         fi
1250     else
1251         local autologin_user="${1}" autologin_session
1252         if [[ -v 2 ]]; then
1253             autologin_session="${2}"
1254         fi
1255
1256         # セッションを設定 (WayLandのセッションは現在サポートされていません)
1257         if [[ -z "${autologin_session+SET}" ]]; then
1258             autologin_session="$(ask_session)"
1259         else
1260             # 既に値が設定済み
1261             check_session "${autologin_session}"
1262         fi
1263
1264         # autologin グループを設定
1265         add_user_to_group "${autologin_user}" "autologin"
1266
1267         # 自動ログインするユーザーを書き込み
1268         sddm_set_config "base" "autologin" "${autologin_user}"
1269
1270         # デフォルトセッションを設定
1271         command_lxdm_session_change "${autologin_session}"
1272
1273         echo "${autologin_user} will automatically log in with ${autologin_session}"
1274     fi
1275 }
1276
1277 command_lxdm_session_wizard(){
1278     command_lxdm_session_change "$(ask_session)"
1279 }
1280
1281 command_lxdm_session_change(){
1282     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
1283         msg_error "Please specify the session name"
1284         exit 1
1285     fi
1286     local session="${1}"
1287     check_session "${session}"
1288     local session_exec="$(get_session "${session}")"
1289     lxdm_set_config "base" "session" "${session_exec}"
1290 }
1291
1292 command_lxdm_remove_last(){
1293     rm -rf "/var/lib/lxdm/lxdm.conf"
1294     echo "Removed last configs"
1295 }
1296
1297 comamnd_lxdm_edit_script(){
1298     local _filelist=(
1299         "LoginReady : executed with root privileges when LXDM is ready to show the login window"
1300         "PreLogin   : run as root before logging a user in"
1301         "PostLogin  : run as the logged-in user right after they have logged in"
1302         "PostLogout : run as the logged-in user right after they have logged out"
1303         "PreReboot  : run as root before rebooting with LXDM"
1304         "PreShutdown: run as root before poweroff with LXDM"
1305     )
1306     if ! file=$(ask_question -p "Select the script you want to edit" "${_filelist[@]}" | cut -d ":" -f 1 | tr -d " "); then
1307         comamnd_lxdm_edit_script
1308         exit 0
1309     fi
1310     bash -c "${USE_EDITOR} ${file}"
1311 }
1312
1313 command_lxdm_back(){
1314     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
1315         msg_error "Please specify the image of background"
1316         exit 1
1317     fi
1318     if [[ ! -f "${1}" ]]; then
1319         msg_error "${1} was not found."
1320         exit 1
1321     fi
1322
1323     local _backgrounf_file="/usr/share/backgrounds/lxdm/background"
1324     mkdir -p "$(dirname "${_backgrounf_file}")"
1325     cp "${1}" "${_backgrounf_file}"
1326     chmod 644 "${_backgrounf_file}"
1327     
1328     lxdm_set_config "display" "bg" "file://${_backgrounf_file}"
1329 }
1330
1331 #== 設定ファイルのパス ==#
1332 declare -A GREETER_CONFIG=(
1333     ["lightdm-webkit2-greeter"]="/etc/lightdm/lightdm-webkit2-greeter.conf"
1334     ["lightdm-slick-greeter"]="/etc/lightdm/slick-greeter.conf"
1335     ["lightdm-gtk-greeter"]="/etc/lightdm/lightdm-gtk-greeter.conf"
1336     ["io.elementary.greeter"]="/etc/lightdm/io.elementary.greeter.conf"
1337     ["lightdm-mini-greeter"]="/etc/lightdm/lightdm-mini-greeter.conf"
1338     ["lightdm-qtquick-greeter"]="/etc/lightdm/lightdm-qtquick-greeter.json"
1339 )
1340
1341 declare -A DISPLAY_MANAGER_CONFIG=(
1342     ["lightdm"]="/etc/lightdm/lightdm.conf.d/00-dmc-lightdm.conf"
1343     ["gdm-dconf"]="/etc/dconf/db/gdm.d/00-dmc-gdm"
1344     ["gdm-custom"]="/etc/gdm/custom.conf"
1345     ["sddm"]="/etc/sddm.conf.d/sddm.conf"
1346     ["lxdm"]="/etc/lxdm/lxdm.conf"
1347 )
1348
1349 declare -A MAIN_BINARY=(
1350     ["lightdm"]="/usr/bin/lightdm"
1351     ["gdm"]="/usr/bin/gdm"
1352     ["sddm"]="/usr/bin/sddm"
1353     ["webkit2"]="/usr/bin/lightdm-webkit2-greeter"
1354     ["slick"]="/usr/bin/slick-greeter"
1355     ["gtk"]="/usr/bin/lightdm-gtk-greeter"
1356     ["elementary"]="/usr/bin/io.elementary.greeter"
1357     ["mini"]="/usr/bin/lightdm-mini-greeter"
1358     ["qtquick"]="/usr/bin/lightdm-qtquick-greeter"
1359     ["lxdm"]="/usr/bin/lxdm"
1360 )
1361
1362
1363 #== CONFIGS ==#
1364
1365 # LightDM - Greeterのディレクトリ
1366 LIGHTDM_GREETERS_DIR="$(lightdm_get_value "greeters-directory")"
1367 : "${LIGHTDM_GREETERS_DIR:="/usr/share/xgreeters"}"
1368
1369 # LightDM - Greeter一覧
1370 #LIGHTDM_GREETERS=( $( )
1371 while read -r line; do
1372     LIGHTDM_GREETERS+=("${line}")
1373 done < <( (find "${LIGHTDM_GREETERS_DIR}" -print0 -type f | xargs -0 -i basename {} | grep -E ".desktop$" | sed "s|.desktop$||g" | grep -xv "xgreeters") 2> /dev/null )
1374
1375 # LightDM - 現在設定されているGreeter
1376 LIGHTDM_CURRENT_GREETER="$(lightdm --show-config 2>&1 | grep "greeter-session" | cut -d "=" -f 2)"
1377 : "${LIGHTDM_CURRENT_GREETER:="lightdm-gtk-greeter"}"
1378
1379 # LightDM - 読み込まれた設定ファイルの一覧
1380 while read -r line; do
1381     LIGHTDM_LOADED_CONFIG+=("${line}")
1382 done < <(printf "%s\n" "$(lightdm --show-config 2>&1 | grep -x -A "$(lightdm --show-config 2>&1 | wc -l)" "Sources:" | grep -v "Sources" | sed 's|^[A-Z]  ||g')"  | tr -d " ")
1383
1384 # Global - エディタ
1385 USE_EDITOR="${EDITOR:-vi}"
1386
1387 # Global - 現在のディスプレイマネージャ名
1388 CURRENT_DM="$(basename "$(readlink "/etc/systemd/system/display-manager.service")" | sed "s|.service$||g")"
1389
1390 # モード
1391 DISPLAY_MANAGER="${CURRENT_DM}"
1392 : "${DISPLAY_MANAGER:="lightdm"}"
1393
1394 # dmc config
1395 NON_INTERACTIVE=false
1396 WRITE_ALL_FILES=false
1397 NOROOT=false
1398 NO_CHECK_TARGET=false
1399
1400 #== 引数解析 ==#
1401 ARGUMENT="${*}"
1402 OPTS="m:e:h"
1403 OPTL="mode:,editor:,help,non-interactive,noroot,write-all-files,no-check-target"
1404 # shellcheck disable=SC2086
1405 if ! OPT="$(getopt -o ${OPTS} -l ${OPTL} -- ${ARGUMENT})"; then
1406     exit 1
1407 fi
1408
1409 eval set -- "${OPT}"
1410 unset OPT OPTS OPTL
1411
1412 while true; do
1413     case "${1}" in
1414         -m | --mode)
1415             DISPLAY_MANAGER="${2}"
1416             shift 2
1417             ;;
1418         -e | --editor)
1419             USE_EDITOR="${2}"
1420             shift 2
1421             ;;
1422         -h | --help)
1423             script_usage
1424             exit 0
1425             ;;
1426         --non-interactive)
1427             NON_INTERACTIVE=true
1428             shift 1
1429             ;;
1430         --noroot)
1431             NOROOT=true
1432             shift 1
1433             ;;
1434         --no-check-target)
1435             NO_CHECK_TARGET=true
1436             shift 1
1437             ;;
1438         --write-all-files)
1439             WRITE_ALL_FILES=true
1440             shift 1
1441             ;;
1442         --)
1443             shift 1
1444             break
1445             ;;
1446     esac
1447 done
1448
1449 # コマンドの引数を解析
1450 COMMAND="${1:-null}"
1451 if (( "${#}" >= 1 )); then
1452     shift 1
1453 fi
1454 COMMAND_ARGS="${*}"
1455 : "${COMMAND_ARGS-""}" # サブコマンドの引数が何も指定されなかった場合に空文字を代入
1456
1457 if [[ "${COMMAND}" = "null" ]]; then
1458     script_usage
1459     exit 1
1460 fi
1461
1462 # メインバイナリの確認を実行
1463 if [[ "${NO_CHECK_TARGET}" = false ]]; then
1464     check_main_binary
1465 fi
1466
1467 # コマンドとモードに応じて関数を実行する
1468 case "${COMMAND}" in
1469     "autologin")
1470         check_command_dm "lightdm" "gdm" "sddm" "lxdm"
1471         case "${DISPLAY_MANAGER}" in
1472             "lightdm")
1473                 lightdm_init_configs
1474                 command_lightdm_auto_login "${COMMAND_ARGS}"
1475                 ;;
1476             "gdm")
1477                 gdm_init_configs
1478                 command_gdm_auto_login "${COMMAND_ARGS}"
1479                 ;;
1480             "sddm")
1481                 sddm_init_configs
1482                 command_sddm_auto_login "${COMMAND_ARGS}"
1483                 ;;
1484             "lxdm")
1485                 lxdm_init_configs
1486                 command_lxdm_auto_login "${COMMAND_ARGS}"
1487                 ;;
1488         esac
1489         ;;
1490     "greeter")
1491         check_command_dm "lightdm"
1492         lightdm_init_configs
1493         run_greeter_wizard
1494         ;;
1495     "greeter-change")
1496         check_command_dm "lightdm"
1497         lightdm_init_configs
1498         command_lightdm_greeter_change "${COMMAND_ARGS}"
1499         ;;
1500     "greeter-create")
1501         check_command_dm "lightdm"
1502         lightdm_init_configs
1503         command_lightdm_greeter_create "${COMMAND_ARGS}"
1504         ;;
1505     "greeter-list")
1506         check_command_dm "lightdm"
1507         command_lightdm_greeter_list
1508         ;;
1509     "greeter-edit")
1510         check_command_dm "lightdm"
1511         check_root
1512         command_lightdm_greeter_edit "${COMMAND_ARGS}"
1513         ;;
1514     "remove")
1515         check_command_dm "lightdm"
1516         check_root
1517         command_lightdm_remove
1518         ;;
1519     "edit")
1520         check_command_dm "lightdm"
1521         check_root
1522         command_lightdm_edit
1523         ;;
1524     "show-config")
1525         check_command_dm "lightdm"
1526         command_lightdm_show_config
1527         ;;
1528     "cursor")
1529         check_command_dm "gdm" "sddm"
1530         case "${DISPLAY_MANAGER}" in
1531             gdm)
1532                 gdm_init_configs
1533                 command_gdm_cursor_wizard
1534                 ;;
1535             sddm)
1536                 sddm_init_configs
1537                 command_sddm_cursor_wizard
1538                 ;;
1539         esac
1540         ;;
1541     "cursor-change")
1542         check_command_dm "gdm" "sddm"
1543         case "${DISPLAY_MANAGER}" in
1544             gdm)
1545                 gdm_init_configs
1546                 command_gdm_cursor_change "${COMMAND_ARGS}"
1547                 ;;
1548             sddm)
1549                 sddm_init_configs
1550                 command_sddm_cursor_change "${COMMAND_ARGS}"
1551                 ;;
1552         esac
1553         ;;
1554     "sound")
1555         check_command_dm "gdm"
1556         gdm_init_configs
1557         command_gdm_sound "${COMMAND_ARGS}"
1558         ;;
1559     "logo")
1560         check_command_dm "gdm" "slick"
1561         case "${DISPLAY_MANAGER}" in
1562             "gdm")
1563                 gdm_init_configs
1564                 command_gdm_logo "${COMMAND_ARGS}"
1565                 ;;
1566             "slick")
1567                 slick_init_configs
1568                 command_slick_logo "${COMMAND_ARGS}"
1569                 ;;
1570         esac
1571         ;;
1572     "tap")
1573         check_command_dm "gdm"
1574         gdm_init_configs
1575         command_gdm_tap "${COMMAND_ARGS}"
1576         ;;
1577     "accessibility")
1578         check_command_dm "gdm"
1579         gdm_init_configs
1580         command_gdm_accessibility "${COMMAND_ARGS}"
1581         ;;
1582     "root-login")
1583         check_command_dm "gdm"
1584         gdm_init_configs
1585         command_gdm_root_login "${COMMAND_ARGS}"
1586         ;;
1587     "theme")
1588         check_command_dm "webkit2" "sddm"
1589         case "${DISPLAY_MANAGER}" in
1590             "webkit2")
1591                 webkit2_init_configs
1592                 command_webkit2_theme_wizard
1593                 ;;
1594             "sddm")
1595                 sddm_init_configs
1596                 command_sddm_theme_wizard
1597                 ;;
1598         esac
1599         ;;
1600     "theme-change")
1601         check_command_dm "webkit2" "sddm"
1602         case "${DISPLAY_MANAGER}" in
1603             "webkit2")
1604                 webkit2_init_configs
1605                 command_webkit2_theme_change "${COMMAND_ARGS}"
1606                 ;;
1607             "sddm")
1608                 sddm_init_configs
1609                 command_sddm_theme_change
1610                 ;;
1611         esac
1612         ;;
1613     "gtk")
1614         check_command_dm "slick"
1615         slick_init_configs
1616         command_slick_gtk_wizard
1617         ;;
1618     "gtk-change")
1619         check_command_dm "slick"
1620         slick_init_configs
1621         command_slick_gtk_change
1622         msg_error "Not yet implemented."
1623         ;;
1624     "back")
1625         check_command_dm "qtquick" "slick" "lxdm"
1626         case "${DISPLAY_MANAGER}" in
1627             "qtquick")
1628                 qtquick_init_configs
1629                 command_qtquick_back "${COMMAND_ARGS}"
1630                 ;;
1631             "slick")
1632                 slick_init_configs
1633                 command_slick_back "${COMMAND_ARGS}"
1634                 ;;
1635             "back")
1636                 lxdm_init_configs
1637                 command_lxdm_back "${COMMAND_ARGS}"
1638                 ;;
1639         esac
1640         ;;
1641     "grid")
1642         check_command_dm "slick"
1643         slick_init_configs
1644         command_slick_grid "${COMMAND_ARGS}"
1645         ;;
1646     "icon")
1647         check_command_dm "slick"
1648         slick_init_configs
1649         command_slick_icon_wizard
1650         ;;
1651     "other-monitor")
1652         check_command_dm "slick"
1653         slick_init_configs
1654         command_slick_other_monitor "${COMMAND_ARGS}"
1655         ;;
1656     "numlock")
1657         check_command_dm "sddm"
1658         sddm_init_configs
1659         command_sddm_numlock "${COMMAND_ARGS}"
1660         ;;
1661     "tty")
1662         check_command_dm "sddm"
1663         sddm_init_configs
1664         command_sddm_tty "${COMMAND_ARGS}"
1665         ;;
1666     "session")
1667         check_command_dm "lxdm"
1668         lxdm_init_configs
1669         command_lxdm_session_wizard
1670         ;;
1671     "session-change")
1672         check_command_dm "lxdm"
1673         lxdm_init_configs
1674         command_lxdm_session_change "${COMMAND_ARGS}"
1675         ;;
1676     "remove-last")
1677         check_command_dm "lxdm"
1678         lxdm_init_configs
1679         command_lxdm_remove_last
1680         ;;
1681     "edit-script")
1682         check_command_dm "lxdm"
1683         lxdm_init_configs
1684         comamnd_lxdm_edit_script
1685         ;;
1686     *)
1687         msg_error "This command cannot be used in any mode"
1688         exit 1
1689         ;;
1690 esac