OSDN Git Service

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