OSDN Git Service

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