OSDN Git Service

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