Remmina - The GTK+ Remote Desktop Client  v1.4.2
Remmina is a remote desktop client written in GTK+, aiming to be useful for system administrators and travellers, who need to work with lots of remote computers in front of either large monitors or tiny netbooks. Remmina supports multiple network protocols in an integrated and consistent user interface. Currently RDP, VNC, NX, XDMCP and SSH are supported.
remmina_pref.c
Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2009-2011 Vic Lee
4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
5  * Copyright (C) 2016-2020 Antenore Gatta, Giovanni Panozzo
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  * In addition, as a special exception, the copyright holders give
23  * permission to link the code of portions of this program with the
24  * OpenSSL library under certain conditions as described in each
25  * individual source file, and distribute linked combinations
26  * including the two.
27  * You must obey the GNU General Public License in all respects
28  * for all of the code used other than OpenSSL. * If you modify
29  * file(s) with this exception, you may extend this exception to your
30  * version of the file(s), but you are not obligated to do so. * If you
31  * do not wish to do so, delete this exception statement from your
32  * version. * If you delete this exception statement from all source
33  * files in the program, then also delete it here.
34  *
35  */
36 
37 #include "config.h"
38 
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <sys/time.h>
43 #include <sys/utsname.h>
44 
45 #include <glib/gstdio.h>
46 #include <gdk/gdkkeysyms.h>
47 #include <gtk/gtk.h>
48 
49 #include "remmina_sodium.h"
50 
51 #include "remmina_public.h"
52 #include "remmina_string_array.h"
53 #include "remmina_pref.h"
55 
56 const gchar *default_resolutions = "640x480,800x600,1024x768,1152x864,1280x960,1400x1050";
57 const gchar *default_keystrokes = "Send hello world§hello world\\n";
58 
60 static GHashTable *remmina_keymap_table = NULL;
61 
62 /* We could customize this further if there are more requirements */
63 static const gchar *default_keymap_data = "# Please check gdk/gdkkeysyms.h for a full list of all key names or hex key values\n"
64  "\n"
65  "[Map Meta Keys]\n"
66  "Super_L = Meta_L\n"
67  "Super_R = Meta_R\n"
68  "Meta_L = Super_L\n"
69  "Meta_R = Super_R\n";
70 
71 static void remmina_pref_gen_secret(void)
72 {
73  TRACE_CALL(__func__);
74  guchar s[32];
75  gint i;
76  GTimeVal gtime;
77  GKeyFile *gkeyfile;
78  gchar *content;
79  gsize length;
80 
81  g_get_current_time(&gtime);
82  srand(gtime.tv_sec);
83 
84  for (i = 0; i < 32; i++) {
85  s[i] = (guchar)(rand() % 256);
86  }
87  remmina_pref.secret = g_base64_encode(s, 32);
88 
89  gkeyfile = g_key_file_new();
90  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
91  g_key_file_set_string(gkeyfile, "remmina_pref", "secret", remmina_pref.secret);
92  content = g_key_file_to_data(gkeyfile, &length, NULL);
93  g_file_set_contents(remmina_pref_file, content, length, NULL);
94 
95  g_key_file_free(gkeyfile);
96  g_free(content);
97 }
98 
99 static guint remmina_pref_get_keyval_from_str(const gchar *str)
100 {
101  TRACE_CALL(__func__);
102  guint k;
103 
104  if (!str)
105  return 0;
106 
107  k = gdk_keyval_from_name(str);
108  if (!k) {
109  if (sscanf(str, "%x", &k) < 1)
110  k = 0;
111  }
112  return k;
113 }
114 
115 static void remmina_pref_init_keymap(void)
116 {
117  TRACE_CALL(__func__);
118  GKeyFile *gkeyfile;
119  gchar **groups;
120  gchar **gptr;
121  gchar **keys;
122  gchar **kptr;
123  gsize nkeys;
124  gchar *value;
125  guint *table;
126  guint *tableptr;
127  guint k1, k2;
128 
130  g_hash_table_destroy(remmina_keymap_table);
131  remmina_keymap_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
132 
133  gkeyfile = g_key_file_new();
134  if (!g_key_file_load_from_file(gkeyfile, remmina_keymap_file, G_KEY_FILE_NONE, NULL)) {
135  if (!g_key_file_load_from_data(gkeyfile, default_keymap_data, strlen(default_keymap_data), G_KEY_FILE_NONE,
136  NULL)) {
137  g_print("Failed to initialize keymap table\n");
138  g_key_file_free(gkeyfile);
139  return;
140  }
141  }
142 
143  groups = g_key_file_get_groups(gkeyfile, NULL);
144  gptr = groups;
145  while (*gptr) {
146  keys = g_key_file_get_keys(gkeyfile, *gptr, &nkeys, NULL);
147  table = g_new0(guint, nkeys * 2 + 1);
148  g_hash_table_insert(remmina_keymap_table, g_strdup(*gptr), table);
149 
150  kptr = keys;
151  tableptr = table;
152  while (*kptr) {
154  if (k1) {
155  value = g_key_file_get_string(gkeyfile, *gptr, *kptr, NULL);
157  g_free(value);
158  *tableptr++ = k1;
159  *tableptr++ = k2;
160  }
161  kptr++;
162  }
163  g_strfreev(keys);
164  gptr++;
165  }
166  g_strfreev(groups);
167  g_key_file_free(gkeyfile);
168 }
169 
171 static gboolean remmina_pref_file_do_copy(const char *src_path, const char *dst_path)
172 {
173  GFile *src = g_file_new_for_path(src_path), *dst = g_file_new_for_path(dst_path);
174  /* We don’t overwrite the target if it exists, because overwrite is not set */
175  const gboolean ok = g_file_copy(src, dst, G_FILE_COPY_NONE, NULL, NULL, NULL, NULL);
176 
177  g_object_unref(dst);
178  g_object_unref(src);
179 
180  return ok;
181 }
182 
183 void remmina_pref_file_load_colors(GKeyFile *gkeyfile, RemminaColorPref *color_pref)
184 {
185  const struct {
186  const char *name;
187  char **setting;
188  char *fallback;
189  } colors[] = {
190  { "background", &color_pref->background, "#d5ccba" },
191  { "cursor", &color_pref->cursor, "#45373c" },
192  { "foreground", &color_pref->foreground, "#45373c" },
193  { "color0", &color_pref->color0, "#20111b" },
194  { "color1", &color_pref->color1, "#be100e" },
195  { "color2", &color_pref->color2, "#858162" },
196  { "color3", &color_pref->color3, "#eaa549" },
197  { "color4", &color_pref->color4, "#426a79" },
198  { "color5", &color_pref->color5, "#97522c" },
199  { "color6", &color_pref->color6, "#989a9c" },
200  { "color7", &color_pref->color7, "#968c83" },
201  { "color8", &color_pref->color8, "#5e5252" },
202  { "color9", &color_pref->color9, "#be100e" },
203  { "color10", &color_pref->color10, "#858162" },
204  { "color11", &color_pref->color11, "#eaa549" },
205  { "color12", &color_pref->color12, "#426a79" },
206  { "color13", &color_pref->color13, "#97522c" },
207  { "color14", &color_pref->color14, "#989a9c" },
208  { "color15", &color_pref->color15, "#d5ccba" },
209  };
210 
211  int i;
212  for (i = 0; i < (sizeof(colors) / sizeof(colors[0])); i++) {
213  if (g_key_file_has_key(gkeyfile, "ssh_colors", colors[i].name, NULL))
214  *colors[i].setting = g_key_file_get_string(gkeyfile, "ssh_colors", colors[i].name,
215  NULL);
216  else
217  *colors[i].setting = colors[i].fallback;
218  }
219 }
220 
222 {
223  TRACE_CALL(__func__);
224  GKeyFile *gkeyfile;
225  gchar *remmina_dir;
226  const gchar *filename = "remmina.pref";
227  const gchar *colors_filename = "remmina.colors";
228  gchar *remmina_colors_file;
229  GDir *dir;
230  gchar *legacy = ".remmina";
231  int i;
232 
233  remmina_dir = g_build_path( "/", g_get_user_config_dir(), "remmina", NULL);
234  /* Create the XDG_CONFIG_HOME directory */
235  g_mkdir_with_parents(remmina_dir, 0750);
236 
237  g_free(remmina_dir), remmina_dir = NULL;
238  /* Legacy ~/.remmina we copy the existing remmina.pref file inside
239  * XDG_CONFIG_HOME */
240  remmina_dir = g_build_path("/", g_get_home_dir(), legacy, NULL);
241  if (g_file_test(remmina_dir, G_FILE_TEST_IS_DIR)) {
242  dir = g_dir_open(remmina_dir, 0, NULL);
244  g_build_path( "/", remmina_dir, filename, NULL),
245  g_build_path( "/", g_get_user_config_dir(),
246  "remmina", filename, NULL));
247  }
248 
249  /* /usr/local/etc/remmina */
250  const gchar * const *dirs = g_get_system_config_dirs();
251  g_free(remmina_dir), remmina_dir = NULL;
252  for (i = 0; dirs[i] != NULL; ++i) {
253  remmina_dir = g_build_path( "/", dirs[i], "remmina", NULL);
254  if (g_file_test(remmina_dir, G_FILE_TEST_IS_DIR)) {
255  dir = g_dir_open(remmina_dir, 0, NULL);
256  while ((filename = g_dir_read_name(dir)) != NULL) {
258  g_build_path( "/", remmina_dir, filename, NULL),
259  g_build_path( "/", g_get_user_config_dir(),
260  "remmina", filename, NULL));
261  }
262  g_free(remmina_dir), remmina_dir = NULL;
263  }
264  }
265 
266  /* The last case we use the home ~/.config/remmina */
267  if (remmina_dir != NULL)
268  g_free(remmina_dir), remmina_dir = NULL;
269  remmina_dir = g_build_path( "/", g_get_user_config_dir(),
270  "remmina", NULL);
271 
272  remmina_pref_file = g_strdup_printf("%s/remmina.pref", remmina_dir);
273  /* remmina.colors */
274  remmina_colors_file = g_strdup_printf("%s/%s", remmina_dir, colors_filename);
275 
276  remmina_keymap_file = g_strdup_printf("%s/remmina.keymap", remmina_dir);
277 
278  gkeyfile = g_key_file_new();
279  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
280 
281  if (g_key_file_has_key(gkeyfile, "remmina_pref", "save_view_mode", NULL))
282  remmina_pref.save_view_mode = g_key_file_get_boolean(gkeyfile, "remmina_pref", "save_view_mode", NULL);
283  else
285 
286  if (g_key_file_has_key(gkeyfile, "remmina_pref", "use_master_password", NULL))
287  remmina_pref.use_master_password = g_key_file_get_boolean(gkeyfile, "remmina_pref", "use_master_password", NULL);
288  else
290 
291  if (g_key_file_has_key(gkeyfile, "remmina_pref", "unlock_timeout", NULL))
292  remmina_pref.unlock_timeout = g_key_file_get_integer(gkeyfile, "remmina_pref", "unlock_timeout", NULL);
293  else
295 
296  if (g_key_file_has_key(gkeyfile, "remmina_pref", "unlock_password", NULL))
297  remmina_pref.unlock_password = g_key_file_get_string(gkeyfile, "remmina_pref", "unlock_password", NULL);
298  else
299  remmina_pref.unlock_password = g_strdup("");
300 
301 
302  if (g_key_file_has_key(gkeyfile, "remmina_pref", "fullscreen_on_auto", NULL))
303  remmina_pref.fullscreen_on_auto = g_key_file_get_boolean(gkeyfile, "remmina_pref", "fullscreen_on_auto", NULL);
304  else
306 
307  if (g_key_file_has_key(gkeyfile, "remmina_pref", "floating_toolbar_placement", NULL))
308  remmina_pref.floating_toolbar_placement = g_key_file_get_integer(gkeyfile, "remmina_pref", "floating_toolbar_placement", NULL);
309  else
311 
312  if (g_key_file_has_key(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", NULL))
313  remmina_pref.prevent_snap_welcome_message = g_key_file_get_boolean(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", NULL);
314  else
316 
317  if (g_key_file_has_key(gkeyfile, "remmina_pref", "last_quickconnect_protocol", NULL))
318  remmina_pref.last_quickconnect_protocol = g_key_file_get_string(gkeyfile, "remmina_pref", "last_quickconnect_protocol", NULL);
319  else
321 
322  if (g_key_file_has_key(gkeyfile, "remmina_pref", "toolbar_placement", NULL))
323  remmina_pref.toolbar_placement = g_key_file_get_integer(gkeyfile, "remmina_pref", "toolbar_placement", NULL);
324  else
326 
327  if (g_key_file_has_key(gkeyfile, "remmina_pref", "always_show_tab", NULL))
328  remmina_pref.always_show_tab = g_key_file_get_boolean(gkeyfile, "remmina_pref", "always_show_tab", NULL);
329  else
331 
332  if (g_key_file_has_key(gkeyfile, "remmina_pref", "hide_connection_toolbar", NULL))
333  remmina_pref.hide_connection_toolbar = g_key_file_get_boolean(gkeyfile, "remmina_pref",
334  "hide_connection_toolbar", NULL);
335  else
337 
338  if (g_key_file_has_key(gkeyfile, "remmina_pref", "hide_searchbar", NULL))
339  remmina_pref.hide_searchbar = g_key_file_get_boolean(gkeyfile, "remmina_pref",
340  "hide_searchbar", NULL);
341  else
343 
344  if (g_key_file_has_key(gkeyfile, "remmina_pref", "default_action", NULL))
345  remmina_pref.default_action = g_key_file_get_integer(gkeyfile, "remmina_pref", "default_action", NULL);
346  else
348 
349  if (g_key_file_has_key(gkeyfile, "remmina_pref", "scale_quality", NULL))
350  remmina_pref.scale_quality = g_key_file_get_integer(gkeyfile, "remmina_pref", "scale_quality", NULL);
351  else
352  remmina_pref.scale_quality = GDK_INTERP_HYPER;
353 
354  if (g_key_file_has_key(gkeyfile, "remmina_pref", "hide_toolbar", NULL))
355  remmina_pref.hide_toolbar = g_key_file_get_boolean(gkeyfile, "remmina_pref", "hide_toolbar", NULL);
356  else
357  remmina_pref.hide_toolbar = FALSE;
358 
359  if (g_key_file_has_key(gkeyfile, "remmina_pref", "small_toolbutton", NULL))
360  remmina_pref.small_toolbutton = g_key_file_get_boolean(gkeyfile, "remmina_pref", "small_toolbutton", NULL);
361  else
363 
364  if (g_key_file_has_key(gkeyfile, "remmina_pref", "view_file_mode", NULL))
365  remmina_pref.view_file_mode = g_key_file_get_integer(gkeyfile, "remmina_pref", "view_file_mode", NULL);
366  else
368 
369  if (g_key_file_has_key(gkeyfile, "remmina_pref", "resolutions", NULL))
370  remmina_pref.resolutions = g_key_file_get_string(gkeyfile, "remmina_pref", "resolutions", NULL);
371  else
373 
374  if (g_key_file_has_key(gkeyfile, "remmina_pref", "keystrokes", NULL))
375  remmina_pref.keystrokes = g_key_file_get_string(gkeyfile, "remmina_pref", "keystrokes", NULL);
376  else
378 
379  if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_width", NULL))
380  remmina_pref.main_width = MAX(600, g_key_file_get_integer(gkeyfile, "remmina_pref", "main_width", NULL));
381  else
382  remmina_pref.main_width = 600;
383 
384  if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_height", NULL))
385  remmina_pref.main_height = MAX(400, g_key_file_get_integer(gkeyfile, "remmina_pref", "main_height", NULL));
386  else
388 
389  if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_maximize", NULL))
390  remmina_pref.main_maximize = g_key_file_get_boolean(gkeyfile, "remmina_pref", "main_maximize", NULL);
391  else
392  remmina_pref.main_maximize = FALSE;
393 
394  if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_sort_column_id", NULL))
395  remmina_pref.main_sort_column_id = g_key_file_get_integer(gkeyfile, "remmina_pref", "main_sort_column_id",
396  NULL);
397  else
399 
400  if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_sort_order", NULL))
401  remmina_pref.main_sort_order = g_key_file_get_integer(gkeyfile, "remmina_pref", "main_sort_order", NULL);
402  else
404 
405  if (g_key_file_has_key(gkeyfile, "remmina_pref", "expanded_group", NULL))
406  remmina_pref.expanded_group = g_key_file_get_string(gkeyfile, "remmina_pref", "expanded_group", NULL);
407  else
408  remmina_pref.expanded_group = g_strdup("");
409 
410  if (g_key_file_has_key(gkeyfile, "remmina_pref", "toolbar_pin_down", NULL))
411  remmina_pref.toolbar_pin_down = g_key_file_get_boolean(gkeyfile, "remmina_pref", "toolbar_pin_down", NULL);
412  else
414 
415  if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_loglevel", NULL))
416  remmina_pref.ssh_loglevel = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_loglevel", NULL);
417  else
418  remmina_pref.ssh_loglevel = DEFAULT_SSH_LOGLEVEL;
419 
420  if (g_key_file_has_key(gkeyfile, "remmina_pref", "deny_screenshot_clipboard", NULL))
421  remmina_pref.deny_screenshot_clipboard = g_key_file_get_boolean(gkeyfile, "remmina_pref", "deny_screenshot_clipboard", NULL);
422  else
424 
425  if (g_key_file_has_key(gkeyfile, "remmina_pref", "datadir_path", NULL))
426  remmina_pref.datadir_path = g_key_file_get_string(gkeyfile, "remmina_pref", "datadir_path", NULL);
427  else
428  remmina_pref.datadir_path = g_strdup("");
429 
430  if (g_key_file_has_key(gkeyfile, "remmina_pref", "remmina_file_name", NULL)) {
431  remmina_pref.remmina_file_name = g_key_file_get_string(gkeyfile, "remmina_pref", "remmina_file_name", NULL);
432  }else{
433  remmina_pref.remmina_file_name = g_strdup("%G_%P_%N_%h");
434  }
435 
436  if (g_key_file_has_key(gkeyfile, "remmina_pref", "screenshot_path", NULL)) {
437  remmina_pref.screenshot_path = g_key_file_get_string(gkeyfile, "remmina_pref", "screenshot_path", NULL);
438  }else{
439  remmina_pref.screenshot_path = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES);
440  if (remmina_pref.screenshot_path == NULL)
441  remmina_pref.screenshot_path = g_get_home_dir();
442  }
443 
444  if (g_key_file_has_key(gkeyfile, "remmina_pref", "screenshot_name", NULL)) {
445  remmina_pref.screenshot_name = g_key_file_get_string(gkeyfile, "remmina_pref", "screenshot_name", NULL);
446  }else{
447  remmina_pref.screenshot_name = g_strdup("remmina_%p_%h_%Y%m%d-%H%M%S");
448  }
449 
450  if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_parseconfig", NULL))
451  remmina_pref.ssh_parseconfig = g_key_file_get_boolean(gkeyfile, "remmina_pref", "ssh_parseconfig", NULL);
452  else
453  remmina_pref.ssh_parseconfig = DEFAULT_SSH_PARSECONFIG;
454 
455  if (g_key_file_has_key(gkeyfile, "remmina_pref", "sshtunnel_port", NULL))
456  remmina_pref.sshtunnel_port = g_key_file_get_integer(gkeyfile, "remmina_pref", "sshtunnel_port", NULL);
457  else
458  remmina_pref.sshtunnel_port = DEFAULT_SSHTUNNEL_PORT;
459 
460  if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_keepidle", NULL))
461  remmina_pref.ssh_tcp_keepidle = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepidle", NULL);
462  else
463  remmina_pref.ssh_tcp_keepidle = SSH_SOCKET_TCP_KEEPIDLE;
464 
465  if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_keepintvl", NULL))
466  remmina_pref.ssh_tcp_keepintvl = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepintvl", NULL);
467  else
468  remmina_pref.ssh_tcp_keepintvl = SSH_SOCKET_TCP_KEEPINTVL;
469 
470  if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_keepcnt", NULL))
471  remmina_pref.ssh_tcp_keepcnt = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepcnt", NULL);
472  else
473  remmina_pref.ssh_tcp_keepcnt = SSH_SOCKET_TCP_KEEPCNT;
474 
475  if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_usrtimeout", NULL))
476  remmina_pref.ssh_tcp_usrtimeout = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_usrtimeout", NULL);
477  else
478  remmina_pref.ssh_tcp_usrtimeout = SSH_SOCKET_TCP_USER_TIMEOUT;
479 
480  if (g_key_file_has_key(gkeyfile, "remmina_pref", "applet_new_ontop", NULL))
481  remmina_pref.applet_new_ontop = g_key_file_get_boolean(gkeyfile, "remmina_pref", "applet_new_ontop", NULL);
482  else
484 
485  if (g_key_file_has_key(gkeyfile, "remmina_pref", "applet_hide_count", NULL))
486  remmina_pref.applet_hide_count = g_key_file_get_boolean(gkeyfile, "remmina_pref", "applet_hide_count", NULL);
487  else
489 
490  if (g_key_file_has_key(gkeyfile, "remmina_pref", "applet_enable_avahi", NULL))
491  remmina_pref.applet_enable_avahi = g_key_file_get_boolean(gkeyfile, "remmina_pref", "applet_enable_avahi",
492  NULL);
493  else
495 
496  if (g_key_file_has_key(gkeyfile, "remmina_pref", "disable_tray_icon", NULL))
497  remmina_pref.disable_tray_icon = g_key_file_get_boolean(gkeyfile, "remmina_pref", "disable_tray_icon", NULL);
498  else
500 
501  if (g_key_file_has_key(gkeyfile, "remmina_pref", "dark_tray_icon", NULL))
502  remmina_pref.dark_tray_icon = g_key_file_get_boolean(gkeyfile, "remmina_pref", "dark_tray_icon", NULL);
503  else
505 
506  if (g_key_file_has_key(gkeyfile, "remmina_pref", "recent_maximum", NULL))
507  remmina_pref.recent_maximum = g_key_file_get_integer(gkeyfile, "remmina_pref", "recent_maximum", NULL);
508  else
510 
511  if (g_key_file_has_key(gkeyfile, "remmina_pref", "default_mode", NULL))
512  remmina_pref.default_mode = g_key_file_get_integer(gkeyfile, "remmina_pref", "default_mode", NULL);
513  else
515 
516  if (g_key_file_has_key(gkeyfile, "remmina_pref", "tab_mode", NULL))
517  remmina_pref.tab_mode = g_key_file_get_integer(gkeyfile, "remmina_pref", "tab_mode", NULL);
518  else
520 
521  if (g_key_file_has_key(gkeyfile, "remmina_pref", "fullscreen_toolbar_visibility", NULL))
522  remmina_pref.fullscreen_toolbar_visibility = g_key_file_get_integer(gkeyfile, "remmina_pref", "fullscreen_toolbar_visibility", NULL);
523  else
525 
526  if (g_key_file_has_key(gkeyfile, "remmina_pref", "auto_scroll_step", NULL))
527  remmina_pref.auto_scroll_step = g_key_file_get_integer(gkeyfile, "remmina_pref", "auto_scroll_step", NULL);
528  else
530 
531  if (g_key_file_has_key(gkeyfile, "remmina_pref", "hostkey", NULL))
532  remmina_pref.hostkey = g_key_file_get_integer(gkeyfile, "remmina_pref", "hostkey", NULL);
533  else
534  remmina_pref.hostkey = GDK_KEY_Control_R;
535 
536  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_fullscreen", NULL))
537  remmina_pref.shortcutkey_fullscreen = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_fullscreen",
538  NULL);
539  else
541 
542  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_autofit", NULL))
543  remmina_pref.shortcutkey_autofit = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_autofit",
544  NULL);
545  else
546  remmina_pref.shortcutkey_autofit = GDK_KEY_1;
547 
548  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_nexttab", NULL))
549  remmina_pref.shortcutkey_nexttab = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_nexttab",
550  NULL);
551  else
552  remmina_pref.shortcutkey_nexttab = GDK_KEY_Right;
553 
554  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_prevtab", NULL))
555  remmina_pref.shortcutkey_prevtab = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_prevtab",
556  NULL);
557  else
558  remmina_pref.shortcutkey_prevtab = GDK_KEY_Left;
559 
560  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_scale", NULL))
561  remmina_pref.shortcutkey_scale = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_scale", NULL);
562  else
563  remmina_pref.shortcutkey_scale = GDK_KEY_s;
564 
565  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_viewonly", NULL))
566  remmina_pref.shortcutkey_viewonly = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_viewonly", NULL);
567  else
569 
570  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_grab", NULL))
571  remmina_pref.shortcutkey_grab = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_grab", NULL);
572  else
573  remmina_pref.shortcutkey_grab = GDK_KEY_Control_R;
574 
575  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_minimize", NULL))
576  remmina_pref.shortcutkey_minimize = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize", NULL);
577  else
578  remmina_pref.shortcutkey_minimize = GDK_KEY_F9;
579 
580  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_screenshot", NULL))
581  remmina_pref.shortcutkey_screenshot = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_screenshot", NULL);
582  else
583  remmina_pref.shortcutkey_screenshot = GDK_KEY_F12;
584 
585  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_disconnect", NULL))
586  remmina_pref.shortcutkey_disconnect = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_disconnect",
587  NULL);
588  else
590 
591  if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_toolbar", NULL))
592  remmina_pref.shortcutkey_toolbar = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_toolbar",
593  NULL);
594  else
595  remmina_pref.shortcutkey_toolbar = GDK_KEY_t;
596 
597  if (g_key_file_has_key(gkeyfile, "remmina_pref", "secret", NULL))
598  remmina_pref.secret = g_key_file_get_string(gkeyfile, "remmina_pref", "secret", NULL);
599  else
600  remmina_pref.secret = NULL;
601 
602  if (g_key_file_has_key(gkeyfile, "remmina_pref", "uid", NULL))
603  remmina_pref.uid = g_key_file_get_string(gkeyfile, "remmina_pref", "uid", NULL);
604  else
605  remmina_pref.uid = NULL;
606 
607  if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_font", NULL))
608  remmina_pref.vte_font = g_key_file_get_string(gkeyfile, "remmina_pref", "vte_font", NULL);
609  else
611 
612  if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_allow_bold_text", NULL))
613  remmina_pref.vte_allow_bold_text = g_key_file_get_boolean(gkeyfile, "remmina_pref", "vte_allow_bold_text",
614  NULL);
615  else
617 
618  if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_lines", NULL))
619  remmina_pref.vte_lines = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_lines", NULL);
620  else
621  remmina_pref.vte_lines = 512;
622 
623  if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_copy", NULL))
624  remmina_pref.vte_shortcutkey_copy = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_copy",
625  NULL);
626  else
628 
629  if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_paste", NULL))
630  remmina_pref.vte_shortcutkey_paste = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_paste",
631  NULL);
632  else
634 
635  if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_select_all", NULL))
636  remmina_pref.vte_shortcutkey_select_all = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_select_all",
637  NULL);
638  else
640 
641  /* If we have a color scheme file, we switch to it, GIO will merge it in the
642  * remmina.pref file */
643  if (g_file_test(remmina_colors_file, G_FILE_TEST_IS_REGULAR)) {
644  gkeyfile = g_key_file_new();
645  g_key_file_load_from_file(gkeyfile, remmina_colors_file, G_KEY_FILE_NONE, NULL);
646  g_remove(remmina_colors_file);
647  }
648 
650 
651  if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL))
652  remmina_pref.periodic_usage_stats_permitted = g_key_file_get_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL);
653  else
655 
656  if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL))
657  remmina_pref.periodic_usage_stats_last_sent = g_key_file_get_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL);
658  else
660 
661  if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix", NULL))
662  remmina_pref.periodic_usage_stats_uuid_prefix = g_key_file_get_string(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix", NULL);
663  else
665 
666  if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_last_get", NULL))
667  remmina_pref.periodic_rmnews_last_get = g_key_file_get_int64(gkeyfile, "remmina_news", "periodic_rmnews_last_get", NULL);
668  else
670 
671  if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_get_count", NULL))
672  remmina_pref.periodic_rmnews_get_count = g_key_file_get_int64(gkeyfile, "remmina_news", "periodic_rmnews_get_count", NULL);
673  else
675 
676  if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_uuid_prefix", NULL))
677  remmina_pref.periodic_rmnews_uuid_prefix = g_key_file_get_string(gkeyfile, "remmina_news", "periodic_rmnews_uuid_prefix", NULL);
678  else
680 
681  /* Default settings */
682  if (!g_key_file_has_key(gkeyfile, "remmina", "name", NULL)) {
683  g_key_file_set_string(gkeyfile, "remmina", "name", "");
684  g_key_file_set_integer(gkeyfile, "remmina", "ignore-tls-errors", 1);
685  g_key_file_set_integer(gkeyfile, "remmina", "enable-plugins", 1);
687  }
688 
689  g_key_file_free(gkeyfile);
690 
691  if (remmina_pref.secret == NULL)
693 
695 }
696 
697 gboolean remmina_pref_is_rw(void)
698 {
699  TRACE_CALL(__func__);
700  if (access(remmina_pref_file, W_OK) == 0)
701  return TRUE;
702  else
703  return FALSE;
704  return FALSE;
705 }
706 
707 gboolean remmina_pref_save(void)
708 {
709  TRACE_CALL(__func__);
710 
711  if (remmina_pref_is_rw() == FALSE) {
712  g_debug ("remmina.pref is not writable, returning");
713  return FALSE;
714  }
715  GKeyFile *gkeyfile;
716  GError *error = NULL;
717  gchar *content;
718  gsize length;
719 
720  gkeyfile = g_key_file_new();
721 
722  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
723 
724  g_key_file_set_string(gkeyfile, "remmina_pref", "datadir_path", remmina_pref.datadir_path);
725  g_key_file_set_string(gkeyfile, "remmina_pref", "remmina_file_name", remmina_pref.remmina_file_name);
726  g_key_file_set_string(gkeyfile, "remmina_pref", "screenshot_path", remmina_pref.screenshot_path);
727  g_key_file_set_string(gkeyfile, "remmina_pref", "remmina_file_name", remmina_pref.remmina_file_name);
728  g_key_file_set_boolean(gkeyfile, "remmina_pref", "deny_screenshot_clipboard", remmina_pref.deny_screenshot_clipboard);
729  g_key_file_set_boolean(gkeyfile, "remmina_pref", "save_view_mode", remmina_pref.save_view_mode);
730 #if SODIUM_VERSION_INT >= 90200
731  g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_master_password", remmina_pref.use_master_password);
732  g_key_file_set_integer(gkeyfile, "remmina_pref", "unlock_timeout", remmina_pref.unlock_timeout);
733  g_key_file_set_string(gkeyfile, "remmina_pref", "unlock_password", remmina_pref.unlock_password);
734 #else
735  g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_master_password", FALSE);
736  g_key_file_set_integer(gkeyfile, "remmina_pref", "unlock_timeout", 0);
737  g_key_file_set_string(gkeyfile, "remmina_pref", "unlock_password", g_strdup(""));
738 #endif
739  g_key_file_set_integer(gkeyfile, "remmina_pref", "floating_toolbar_placement", remmina_pref.floating_toolbar_placement);
740  g_key_file_set_integer(gkeyfile, "remmina_pref", "toolbar_placement", remmina_pref.toolbar_placement);
741  g_key_file_set_boolean(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", remmina_pref.prevent_snap_welcome_message);
742  g_key_file_set_string(gkeyfile, "remmina_pref", "last_quickconnect_protocol", remmina_pref.last_quickconnect_protocol);
743  g_key_file_set_boolean(gkeyfile, "remmina_pref", "fullscreen_on_auto", remmina_pref.fullscreen_on_auto);
744  g_key_file_set_boolean(gkeyfile, "remmina_pref", "always_show_tab", remmina_pref.always_show_tab);
745  g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_connection_toolbar", remmina_pref.hide_connection_toolbar);
746  g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_searchbar", remmina_pref.hide_searchbar);
747  g_key_file_set_integer(gkeyfile, "remmina_pref", "default_action", remmina_pref.default_action);
748  g_key_file_set_integer(gkeyfile, "remmina_pref", "scale_quality", remmina_pref.scale_quality);
749  g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_loglevel", remmina_pref.ssh_loglevel);
750  g_key_file_set_boolean(gkeyfile, "remmina_pref", "ssh_parseconfig", remmina_pref.ssh_parseconfig);
751  g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_toolbar", remmina_pref.hide_toolbar);
752  g_key_file_set_boolean(gkeyfile, "remmina_pref", "small_toolbutton", remmina_pref.small_toolbutton);
753  g_key_file_set_integer(gkeyfile, "remmina_pref", "view_file_mode", remmina_pref.view_file_mode);
754  g_key_file_set_string(gkeyfile, "remmina_pref", "resolutions", remmina_pref.resolutions);
755  g_key_file_set_string(gkeyfile, "remmina_pref", "keystrokes", remmina_pref.keystrokes);
756  g_key_file_set_integer(gkeyfile, "remmina_pref", "main_width", remmina_pref.main_width);
757  g_key_file_set_integer(gkeyfile, "remmina_pref", "main_height", remmina_pref.main_height);
758  g_key_file_set_boolean(gkeyfile, "remmina_pref", "main_maximize", remmina_pref.main_maximize);
759  g_key_file_set_integer(gkeyfile, "remmina_pref", "main_sort_column_id", remmina_pref.main_sort_column_id);
760  g_key_file_set_integer(gkeyfile, "remmina_pref", "main_sort_order", remmina_pref.main_sort_order);
761  g_key_file_set_string(gkeyfile, "remmina_pref", "expanded_group", remmina_pref.expanded_group);
762  g_key_file_set_boolean(gkeyfile, "remmina_pref", "toolbar_pin_down", remmina_pref.toolbar_pin_down);
763  g_key_file_set_integer(gkeyfile, "remmina_pref", "sshtunnel_port", remmina_pref.sshtunnel_port);
764  g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepidle", remmina_pref.ssh_tcp_keepidle);
765  g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepintvl", remmina_pref.ssh_tcp_keepintvl);
766  g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepcnt", remmina_pref.ssh_tcp_keepcnt);
767  g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_usrtimeout", remmina_pref.ssh_tcp_usrtimeout);
768  g_key_file_set_boolean(gkeyfile, "remmina_pref", "applet_new_ontop", remmina_pref.applet_new_ontop);
769  g_key_file_set_boolean(gkeyfile, "remmina_pref", "applet_hide_count", remmina_pref.applet_hide_count);
770  g_key_file_set_boolean(gkeyfile, "remmina_pref", "applet_enable_avahi", remmina_pref.applet_enable_avahi);
771  g_key_file_set_boolean(gkeyfile, "remmina_pref", "disable_tray_icon", remmina_pref.disable_tray_icon);
772  g_key_file_set_boolean(gkeyfile, "remmina_pref", "dark_tray_icon", remmina_pref.dark_tray_icon);
773  g_key_file_set_integer(gkeyfile, "remmina_pref", "recent_maximum", remmina_pref.recent_maximum);
774  g_key_file_set_integer(gkeyfile, "remmina_pref", "default_mode", remmina_pref.default_mode);
775  g_key_file_set_integer(gkeyfile, "remmina_pref", "tab_mode", remmina_pref.tab_mode);
776  g_key_file_set_integer(gkeyfile, "remmina_pref", "fullscreen_toolbar_visibility", remmina_pref.fullscreen_toolbar_visibility);
777  g_key_file_set_integer(gkeyfile, "remmina_pref", "auto_scroll_step", remmina_pref.auto_scroll_step);
778  g_key_file_set_integer(gkeyfile, "remmina_pref", "hostkey", remmina_pref.hostkey);
779  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_fullscreen", remmina_pref.shortcutkey_fullscreen);
780  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_autofit", remmina_pref.shortcutkey_autofit);
781  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_nexttab", remmina_pref.shortcutkey_nexttab);
782  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_prevtab", remmina_pref.shortcutkey_prevtab);
783  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_scale", remmina_pref.shortcutkey_scale);
784  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_grab", remmina_pref.shortcutkey_grab);
785  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_viewonly", remmina_pref.shortcutkey_viewonly);
786  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_screenshot", remmina_pref.shortcutkey_screenshot);
787  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize", remmina_pref.shortcutkey_minimize);
788  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_disconnect", remmina_pref.shortcutkey_disconnect);
789  g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_toolbar", remmina_pref.shortcutkey_toolbar);
790  g_key_file_set_string(gkeyfile, "remmina_pref", "vte_font", remmina_pref.vte_font ? remmina_pref.vte_font : "");
791  g_key_file_set_boolean(gkeyfile, "remmina_pref", "vte_allow_bold_text", remmina_pref.vte_allow_bold_text);
792  g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_lines", remmina_pref.vte_lines);
793  g_key_file_set_string(gkeyfile, "ssh_colors", "background", remmina_pref.color_pref.background ? remmina_pref.color_pref.background : "");
794  g_key_file_set_string(gkeyfile, "ssh_colors", "cursor", remmina_pref.color_pref.cursor ? remmina_pref.color_pref.cursor : "");
795  g_key_file_set_string(gkeyfile, "ssh_colors", "foreground", remmina_pref.color_pref.foreground ? remmina_pref.color_pref.foreground : "");
796  g_key_file_set_string(gkeyfile, "ssh_colors", "color0", remmina_pref.color_pref.color0 ? remmina_pref.color_pref.color0 : "");
797  g_key_file_set_string(gkeyfile, "ssh_colors", "color1", remmina_pref.color_pref.color1 ? remmina_pref.color_pref.color1 : "");
798  g_key_file_set_string(gkeyfile, "ssh_colors", "color2", remmina_pref.color_pref.color2 ? remmina_pref.color_pref.color2 : "");
799  g_key_file_set_string(gkeyfile, "ssh_colors", "color3", remmina_pref.color_pref.color3 ? remmina_pref.color_pref.color3 : "");
800  g_key_file_set_string(gkeyfile, "ssh_colors", "color4", remmina_pref.color_pref.color4 ? remmina_pref.color_pref.color4 : "");
801  g_key_file_set_string(gkeyfile, "ssh_colors", "color5", remmina_pref.color_pref.color5 ? remmina_pref.color_pref.color5 : "");
802  g_key_file_set_string(gkeyfile, "ssh_colors", "color6", remmina_pref.color_pref.color6 ? remmina_pref.color_pref.color6 : "");
803  g_key_file_set_string(gkeyfile, "ssh_colors", "color7", remmina_pref.color_pref.color7 ? remmina_pref.color_pref.color7 : "");
804  g_key_file_set_string(gkeyfile, "ssh_colors", "color8", remmina_pref.color_pref.color8 ? remmina_pref.color_pref.color8 : "");
805  g_key_file_set_string(gkeyfile, "ssh_colors", "color9", remmina_pref.color_pref.color9 ? remmina_pref.color_pref.color9 : "");
806  g_key_file_set_string(gkeyfile, "ssh_colors", "color10", remmina_pref.color_pref.color10 ? remmina_pref.color_pref.color10 : "");
807  g_key_file_set_string(gkeyfile, "ssh_colors", "color11", remmina_pref.color_pref.color11 ? remmina_pref.color_pref.color11 : "");
808  g_key_file_set_string(gkeyfile, "ssh_colors", "color12", remmina_pref.color_pref.color12 ? remmina_pref.color_pref.color12 : "");
809  g_key_file_set_string(gkeyfile, "ssh_colors", "color13", remmina_pref.color_pref.color13 ? remmina_pref.color_pref.color13 : "");
810  g_key_file_set_string(gkeyfile, "ssh_colors", "color14", remmina_pref.color_pref.color14 ? remmina_pref.color_pref.color14 : "");
811  g_key_file_set_string(gkeyfile, "ssh_colors", "color15", remmina_pref.color_pref.color15 ? remmina_pref.color_pref.color15 : "");
812 
813  g_key_file_set_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", remmina_pref.periodic_usage_stats_permitted);
814  g_key_file_set_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", remmina_pref.periodic_usage_stats_last_sent);
815  g_key_file_set_string(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix",
817  g_key_file_set_int64(gkeyfile, "remmina_news", "periodic_rmnews_last_get", remmina_pref.periodic_rmnews_last_get);
818  g_key_file_set_integer(gkeyfile, "remmina_news", "periodic_rmnews_get_count", remmina_pref.periodic_rmnews_get_count);
819  g_key_file_set_string(gkeyfile, "remmina_news", "periodic_rmnews_uuid_prefix",
821 
822  /* Default settings */
823  g_key_file_set_string(gkeyfile, "remmina", "name", "");
824  g_key_file_set_integer(gkeyfile, "remmina", "ignore-tls-errors", 1);
825 
826  content = g_key_file_to_data(gkeyfile, &length, NULL);
827  g_file_set_contents(remmina_pref_file, content, length, &error);
828 
829  if (error != NULL)
830  {
831  g_warning ("remmina_pref_save error: %s", error->message);
832  g_clear_error (&error);
833  g_key_file_free(gkeyfile);
834  g_free(content);
835  return FALSE;
836  }
837  g_key_file_free(gkeyfile);
838  g_free(content);
839  return TRUE;
840 }
841 
842 void remmina_pref_add_recent(const gchar *protocol, const gchar *server)
843 {
844  TRACE_CALL(__func__);
845  RemminaStringArray *array;
846  GKeyFile *gkeyfile;
847  gchar key[20];
848  gchar *val;
849  gchar *content;
850  gsize length;
851 
852  if (remmina_pref.recent_maximum <= 0 || server == NULL || server[0] == 0)
853  return;
854 
855  /* Load original value into memory */
856  gkeyfile = g_key_file_new();
857 
858  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
859 
860  g_snprintf(key, sizeof(key), "recent_%s", protocol);
861  array = remmina_string_array_new_from_allocated_string(g_key_file_get_string(gkeyfile, "remmina_pref", key, NULL));
862 
863  /* Add the new value */
864  remmina_string_array_remove(array, server);
865  while (array->len >= remmina_pref.recent_maximum) {
867  }
868  remmina_string_array_add(array, server);
869 
870  /* Save */
871  val = remmina_string_array_to_string(array);
872  g_key_file_set_string(gkeyfile, "remmina_pref", key, val);
873  g_free(val);
874 
875  content = g_key_file_to_data(gkeyfile, &length, NULL);
876  g_file_set_contents(remmina_pref_file, content, length, NULL);
877 
878  g_key_file_free(gkeyfile);
879  g_free(content);
880 }
881 
882 gchar*
883 remmina_pref_get_recent(const gchar *protocol)
884 {
885  TRACE_CALL(__func__);
886  GKeyFile *gkeyfile;
887  gchar key[20];
888  gchar *val;
889 
890  gkeyfile = g_key_file_new();
891 
892  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
893 
894  g_snprintf(key, sizeof(key), "recent_%s", protocol);
895  val = g_key_file_get_string(gkeyfile, "remmina_pref", key, NULL);
896 
897  g_key_file_free(gkeyfile);
898 
899  return val;
900 }
901 
903 {
904  TRACE_CALL(__func__);
905  GKeyFile *gkeyfile;
906  gchar **keys;
907  gint i;
908  gchar *content;
909  gsize length;
910 
911  gkeyfile = g_key_file_new();
912 
913  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
914  keys = g_key_file_get_keys(gkeyfile, "remmina_pref", NULL, NULL);
915  if (keys) {
916  for (i = 0; keys[i]; i++) {
917  if (strncmp(keys[i], "recent_", 7) == 0) {
918  g_key_file_set_string(gkeyfile, "remmina_pref", keys[i], "");
919  }
920  }
921  g_strfreev(keys);
922  }
923 
924  content = g_key_file_to_data(gkeyfile, &length, NULL);
925  g_file_set_contents(remmina_pref_file, content, length, NULL);
926 
927  g_key_file_free(gkeyfile);
928  g_free(content);
929 }
930 
931 guint remmina_pref_keymap_get_keyval(const gchar *keymap, guint keyval)
932 {
933  TRACE_CALL(__func__);
934  guint *table;
935  gint i;
936 
937  if (!keymap || keymap[0] == '\0')
938  return keyval;
939 
940  table = (guint*)g_hash_table_lookup(remmina_keymap_table, keymap);
941  if (!table)
942  return keyval;
943  for (i = 0; table[i] > 0; i += 2) {
944  if (table[i] == keyval)
945  return table[i + 1];
946  }
947  return keyval;
948 }
949 
950 gchar**
952 {
953  TRACE_CALL(__func__);
954  GList *list;
955  guint len;
956  gchar **keys;
957  guint i;
958 
959  list = g_hash_table_get_keys(remmina_keymap_table);
960  len = g_list_length(list);
961 
962  keys = g_new0(gchar*, (len + 1) * 2 + 1);
963  keys[0] = g_strdup("");
964  keys[1] = g_strdup("");
965  for (i = 0; i < len; i++) {
966  keys[(i + 1) * 2] = g_strdup((gchar*)g_list_nth_data(list, i));
967  keys[(i + 1) * 2 + 1] = g_strdup((gchar*)g_list_nth_data(list, i));
968  }
969  g_list_free(list);
970 
971  return keys;
972 }
973 
975 {
976  TRACE_CALL(__func__);
977  /* Paranoid programming */
978  if (remmina_pref.scale_quality < 0) {
980  }
982 }
983 
985 {
986  TRACE_CALL(__func__);
987  return remmina_pref.ssh_loglevel;
988 }
989 
991 {
992  TRACE_CALL(__func__);
994 }
995 
997 {
998  TRACE_CALL(__func__);
1000 }
1001 
1003 {
1004  TRACE_CALL(__func__);
1006 }
1007 
1009 {
1010  TRACE_CALL(__func__);
1012 }
1013 
1015 {
1016  TRACE_CALL(__func__);
1018 }
1019 
1021 {
1022  TRACE_CALL(__func__);
1024 }
1025 
1026 void remmina_pref_set_value(const gchar *key, const gchar *value)
1027 {
1028  TRACE_CALL(__func__);
1029  GKeyFile *gkeyfile;
1030  gchar *content;
1031  gsize length;
1032 
1033  gkeyfile = g_key_file_new();
1034  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
1035  g_key_file_set_string(gkeyfile, "remmina_pref", key, value);
1036  content = g_key_file_to_data(gkeyfile, &length, NULL);
1037  g_file_set_contents(remmina_pref_file, content, length, NULL);
1038 
1039  g_key_file_free(gkeyfile);
1040  g_free(content);
1041 }
1042 
1043 gchar* remmina_pref_get_value(const gchar *key)
1044 {
1045  TRACE_CALL(__func__);
1046  GKeyFile *gkeyfile;
1047  gchar *value;
1048 
1049  gkeyfile = g_key_file_new();
1050  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
1051  value = g_key_file_get_string(gkeyfile, "remmina_pref", key, NULL);
1052  g_key_file_free(gkeyfile);
1053 
1054  return value;
1055 }
1056 
1057 gboolean remmina_pref_get_boolean(const gchar *key)
1058 {
1059  TRACE_CALL(__func__);
1060  GKeyFile *gkeyfile;
1061  gboolean value;
1062 
1063  gkeyfile = g_key_file_new();
1064  g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
1065  value = g_key_file_get_boolean(gkeyfile, "remmina_pref", key, NULL);
1066  g_key_file_free(gkeyfile);
1067 
1068  return value;
1069 }
guint shortcutkey_fullscreen
Definition: remmina_pref.h:152
gint floating_toolbar_placement
Definition: remmina_pref.h:186
gboolean hide_searchbar
Definition: remmina_pref.h:133
gint remmina_pref_get_scale_quality(void)
Definition: remmina_pref.c:974
guint shortcutkey_minimize
Definition: remmina_pref.h:161
static void remmina_pref_gen_secret(void)
Definition: remmina_pref.c:71
gchar ** remmina_pref_keymap_groups(void)
Definition: remmina_pref.c:951
const gchar * default_keystrokes
Definition: remmina_pref.c:57
static const gchar * default_keymap_data
Definition: remmina_pref.c:63
gint default_action
Definition: remmina_pref.h:123
gchar * remmina_pref_file
Definition: rcw.c:72
G_BEGIN_DECLS typedef GPtrArray RemminaStringArray
gint remmina_pref_get_sshtunnel_port(void)
Definition: remmina_pref.c:996
gchar * keystrokes
Definition: remmina_pref.h:128
static gboolean remmina_pref_file_do_copy(const char *src_path, const char *dst_path)
Definition: remmina_pref.c:171
guint shortcutkey_screenshot
Definition: remmina_pref.h:160
guint shortcutkey_prevtab
Definition: remmina_pref.h:154
gboolean ssh_parseconfig
Definition: remmina_pref.h:144
gint ssh_tcp_keepintvl
Definition: remmina_pref.h:147
gchar * last_quickconnect_protocol
Definition: remmina_pref.h:189
gboolean dark_tray_icon
Definition: remmina_pref.h:141
gint remmina_pref_get_ssh_loglevel(void)
Definition: remmina_pref.c:984
gint auto_scroll_step
Definition: remmina_pref.h:125
guint vte_shortcutkey_copy
Definition: remmina_pref.h:169
static guint remmina_pref_get_keyval_from_str(const gchar *str)
Definition: remmina_pref.c:99
gchar * remmina_pref_get_recent(const gchar *protocol)
Definition: remmina_pref.c:883
guint shortcutkey_autofit
Definition: remmina_pref.h:153
gchar * secret
Definition: remmina_pref.h:192
gboolean use_master_password
Definition: remmina_pref.h:119
gchar * remmina_string_array_to_string(RemminaStringArray *array)
gint scale_quality
Definition: remmina_pref.h:124
void remmina_pref_add_recent(const gchar *protocol, const gchar *server)
Definition: remmina_pref.c:842
void remmina_pref_set_value(const gchar *key, const gchar *value)
gboolean deny_screenshot_clipboard
Definition: remmina_pref.h:116
gchar * resolutions
Definition: remmina_pref.h:127
guint vte_shortcutkey_select_all
Definition: remmina_pref.h:171
gint main_sort_order
Definition: remmina_pref.h:183
gboolean vte_allow_bold_text
Definition: remmina_pref.h:166
gchar * remmina_pref_get_value(const gchar *key)
gboolean disable_tray_icon
Definition: remmina_pref.h:140
gint recent_maximum
Definition: remmina_pref.h:126
gboolean remmina_pref_get_ssh_parseconfig(void)
Definition: remmina_pref.c:990
static GHashTable * remmina_keymap_table
Definition: remmina_pref.c:60
gchar * vte_font
Definition: remmina_pref.h:165
const gchar * screenshot_path
Definition: remmina_pref.h:115
void remmina_string_array_remove_index(RemminaStringArray *array, gint i)
GtkTreeView * table
gint unlock_timeout
Definition: remmina_pref.h:122
gchar * periodic_usage_stats_uuid_prefix
Definition: remmina_pref.h:202
gint toolbar_placement
Definition: remmina_pref.h:187
gboolean prevent_snap_welcome_message
Definition: remmina_pref.h:188
gchar * expanded_group
Definition: remmina_pref.h:184
gchar * periodic_rmnews_uuid_prefix
Definition: remmina_pref.h:208
const gchar * unlock_password
Definition: remmina_pref.h:120
guint vte_shortcutkey_paste
Definition: remmina_pref.h:170
guint shortcutkey_disconnect
Definition: remmina_pref.h:162
gint ssh_tcp_usrtimeout
Definition: remmina_pref.h:149
gboolean small_toolbutton
Definition: remmina_pref.h:174
guint shortcutkey_grab
Definition: remmina_pref.h:158
gboolean always_show_tab
Definition: remmina_pref.h:131
gboolean toolbar_pin_down
Definition: remmina_pref.h:185
gint main_sort_column_id
Definition: remmina_pref.h:182
guint shortcutkey_scale
Definition: remmina_pref.h:157
gboolean main_maximize
Definition: remmina_pref.h:181
RemminaStringArray * remmina_string_array_new_from_allocated_string(gchar *strs)
glong periodic_rmnews_get_count
Definition: remmina_pref.h:207
gboolean periodic_usage_stats_permitted
Definition: remmina_pref.h:200
gboolean remmina_pref_get_boolean(const gchar *key)
gint view_file_mode
Definition: remmina_pref.h:175
gint remmina_pref_get_ssh_tcp_keepcnt(void)
void remmina_pref_clear_recent(void)
Definition: remmina_pref.c:902
const gchar * default_resolutions
Definition: remmina_pref.c:56
guint shortcutkey_nexttab
Definition: remmina_pref.h:155
gboolean applet_hide_count
Definition: remmina_pref.h:139
gint ssh_tcp_keepidle
Definition: remmina_pref.h:146
guint remmina_pref_keymap_get_keyval(const gchar *keymap, guint keyval)
Definition: remmina_pref.c:931
gboolean hide_toolbar
Definition: remmina_pref.h:173
void remmina_string_array_remove(RemminaStringArray *array, const gchar *str)
RemminaPref remmina_pref
Definition: rcw.c:73
gboolean applet_enable_avahi
Definition: remmina_pref.h:177
const gchar * remmina_file_name
Definition: remmina_pref.h:114
void remmina_pref_init(void)
Definition: remmina_pref.c:221
gchar * remmina_keymap_file
Definition: remmina_pref.c:59
guint shortcutkey_toolbar
Definition: remmina_pref.h:163
glong periodic_usage_stats_last_sent
Definition: remmina_pref.h:201
gboolean remmina_pref_save(void)
Definition: remmina_pref.c:707
gchar * remmina_colors_file
gint ssh_tcp_keepcnt
Definition: remmina_pref.h:148
gboolean applet_new_ontop
Definition: remmina_pref.h:138
const gchar * screenshot_name
Definition: remmina_pref.h:117
gboolean hide_connection_toolbar
Definition: remmina_pref.h:132
static void remmina_pref_init_keymap(void)
Definition: remmina_pref.c:115
gint sshtunnel_port
Definition: remmina_pref.h:145
const gchar * datadir_path
Definition: remmina_pref.h:113
gboolean remmina_pref_is_rw(void)
Definition: remmina_pref.c:697
void remmina_string_array_add(RemminaStringArray *array, const gchar *str)
RemminaColorPref color_pref
Definition: remmina_pref.h:197
glong periodic_rmnews_last_get
Definition: remmina_pref.h:206
void remmina_pref_file_load_colors(GKeyFile *gkeyfile, RemminaColorPref *color_pref)
Definition: remmina_pref.c:183
guint shortcutkey_viewonly
Definition: remmina_pref.h:159
gboolean fullscreen_on_auto
Definition: remmina_pref.h:130
gboolean save_view_mode
Definition: remmina_pref.h:118
gint fullscreen_toolbar_visibility
Definition: remmina_pref.h:136
gint remmina_pref_get_ssh_tcp_usrtimeout(void)
gint remmina_pref_get_ssh_tcp_keepidle(void)
gint remmina_pref_get_ssh_tcp_keepintvl(void)