OSDN Git Service

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