1 /*
2 Skins engine.
3 Interface functions
4
5 Copyright (C) 2009-2021
6 Free Software Foundation, Inc.
7
8 Written by:
9 Slava Zanko <slavazanko@gmail.com>, 2009
10 Egmont Koblinger <egmont@gmail.com>, 2010
11
12 This file is part of the Midnight Commander.
13
14 The Midnight Commander is free software: you can redistribute it
15 and/or modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation, either version 3 of the License,
17 or (at your option) any later version.
18
19 The Midnight Commander is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 #include <config.h>
29 #include <stdlib.h>
30
31 #include "internal.h"
32 #include "lib/util.h"
33
34 #include "lib/tty/color.h" /* tty_use_256colors(); */
35
36 /*** global variables ****************************************************************************/
37
38 mc_skin_t mc_skin__default;
39
40 /*** file scope macro definitions ****************************************************************/
41
42 /*** file scope type declarations ****************************************************************/
43
44 /*** file scope variables ************************************************************************/
45
46 static gboolean mc_skin_is_init = FALSE;
47
48 /* --------------------------------------------------------------------------------------------- */
49 /*** file scope functions ************************************************************************/
50 /* --------------------------------------------------------------------------------------------- */
51
52 static void
mc_skin_hash_destroy_value(gpointer data)53 mc_skin_hash_destroy_value (gpointer data)
54 {
55 mc_skin_color_t *mc_skin_color = (mc_skin_color_t *) data;
56 g_free (mc_skin_color->fgcolor);
57 g_free (mc_skin_color->bgcolor);
58 g_free (mc_skin_color->attrs);
59 g_free (mc_skin_color);
60 }
61
62 /* --------------------------------------------------------------------------------------------- */
63
64 static char *
mc_skin_get_default_name(void)65 mc_skin_get_default_name (void)
66 {
67 char *tmp_str;
68
69 /* from command line */
70 if (mc_global.tty.skin != NULL)
71 return g_strdup (mc_global.tty.skin);
72
73 /* from envirovement variable */
74 tmp_str = getenv ("MC_SKIN");
75 if (tmp_str != NULL)
76 return g_strdup (tmp_str);
77
78 /* from config. Or 'default' if no present in config */
79 return mc_config_get_string (mc_global.main_config, CONFIG_APP_SECTION, "skin", "default");
80 }
81
82 /* --------------------------------------------------------------------------------------------- */
83
84 static void
mc_skin_reinit(void)85 mc_skin_reinit (void)
86 {
87 mc_skin_deinit ();
88 mc_skin__default.name = mc_skin_get_default_name ();
89 mc_skin__default.colors = g_hash_table_new_full (g_str_hash, g_str_equal,
90 g_free, mc_skin_hash_destroy_value);
91 }
92
93 /* --------------------------------------------------------------------------------------------- */
94
95 static void
mc_skin_try_to_load_default(void)96 mc_skin_try_to_load_default (void)
97 {
98 mc_skin_reinit ();
99 g_free (mc_skin__default.name);
100 mc_skin__default.name = g_strdup ("default");
101 if (!mc_skin_ini_file_load (&mc_skin__default))
102 {
103 mc_skin_reinit ();
104 mc_skin_set_hardcoded_skin (&mc_skin__default);
105 }
106
107 }
108
109 /* --------------------------------------------------------------------------------------------- */
110 /*** public functions ****************************************************************************/
111 /* --------------------------------------------------------------------------------------------- */
112
113 gboolean
mc_skin_init(const gchar * skin_override,GError ** mcerror)114 mc_skin_init (const gchar * skin_override, GError ** mcerror)
115 {
116 gboolean is_good_init = TRUE;
117 GError *error = NULL;
118
119 mc_return_val_if_error (mcerror, FALSE);
120
121 mc_skin__default.have_256_colors = FALSE;
122 mc_skin__default.have_true_colors = FALSE;
123
124 mc_skin__default.name =
125 skin_override != NULL ? g_strdup (skin_override) : mc_skin_get_default_name ();
126
127 mc_skin__default.colors = g_hash_table_new_full (g_str_hash, g_str_equal,
128 g_free, mc_skin_hash_destroy_value);
129 if (!mc_skin_ini_file_load (&mc_skin__default))
130 {
131 mc_propagate_error (mcerror, 0,
132 _("Unable to load '%s' skin.\nDefault skin has been loaded"),
133 mc_skin__default.name);
134 mc_skin_try_to_load_default ();
135 is_good_init = FALSE;
136 }
137 mc_skin_colors_old_configure (&mc_skin__default);
138
139 if (!mc_skin_ini_file_parse (&mc_skin__default))
140 {
141 mc_propagate_error (mcerror, 0,
142 _("Unable to parse '%s' skin.\nDefault skin has been loaded"),
143 mc_skin__default.name);
144
145 mc_skin_try_to_load_default ();
146 mc_skin_colors_old_configure (&mc_skin__default);
147 (void) mc_skin_ini_file_parse (&mc_skin__default);
148 is_good_init = FALSE;
149 }
150 if (is_good_init && mc_skin__default.have_true_colors && !tty_use_truecolors (&error))
151 {
152 mc_propagate_error (mcerror, 0,
153 _
154 ("Unable to use '%s' skin with true colors support:\n%s\nDefault skin has been loaded"),
155 mc_skin__default.name, error->message);
156 g_error_free (error);
157 mc_skin_try_to_load_default ();
158 mc_skin_colors_old_configure (&mc_skin__default);
159 (void) mc_skin_ini_file_parse (&mc_skin__default);
160 is_good_init = FALSE;
161 }
162 if (is_good_init && mc_skin__default.have_256_colors && !tty_use_256colors (&error))
163 {
164 mc_propagate_error (mcerror, 0,
165 _
166 ("Unable to use '%s' skin with 256 colors support\non non-256 colors terminal.\nDefault skin has been loaded"),
167 mc_skin__default.name);
168 mc_skin_try_to_load_default ();
169 mc_skin_colors_old_configure (&mc_skin__default);
170 (void) mc_skin_ini_file_parse (&mc_skin__default);
171 is_good_init = FALSE;
172 }
173 mc_skin_is_init = TRUE;
174 return is_good_init;
175 }
176
177 /* --------------------------------------------------------------------------------------------- */
178
179 void
mc_skin_deinit(void)180 mc_skin_deinit (void)
181 {
182 tty_color_free_all_tmp ();
183 tty_color_free_all_non_tmp ();
184
185 MC_PTR_FREE (mc_skin__default.name);
186 g_hash_table_destroy (mc_skin__default.colors);
187 mc_skin__default.colors = NULL;
188
189 MC_PTR_FREE (mc_skin__default.description);
190
191 mc_config_deinit (mc_skin__default.config);
192 mc_skin__default.config = NULL;
193
194 mc_skin_is_init = FALSE;
195 }
196
197 /* --------------------------------------------------------------------------------------------- */
198
199 gchar *
mc_skin_get(const gchar * group,const gchar * key,const gchar * default_value)200 mc_skin_get (const gchar * group, const gchar * key, const gchar * default_value)
201 {
202 if (mc_global.tty.ugly_line_drawing)
203 {
204 return g_strdup (default_value);
205 }
206 return mc_config_get_string (mc_skin__default.config, group, key, default_value);
207 }
208
209 /* --------------------------------------------------------------------------------------------- */
210