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.
rdp_settings.c
Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2010-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 
38 #include "rdp_plugin.h"
39 #include "rdp_settings.h"
40 #include <freerdp/locale/keyboard.h>
41 
42 static guint keyboard_layout = 0;
43 static guint rdp_keyboard_layout = 0;
44 
46 {
47  TRACE_CALL(__func__);
48  keyboard_layout = freerdp_keyboard_init(rdp_keyboard_layout);
49 }
50 
52 {
53  TRACE_CALL(__func__);
54  gchar* value;
55 
56  value = remmina_plugin_service->pref_get_value("rdp_keyboard_layout");
57 
58  if (value && value[0])
59  rdp_keyboard_layout = strtoul(value, NULL, 16);
60 
61  g_free(value);
62 
64 }
65 
67 {
68  TRACE_CALL(__func__);
69  return keyboard_layout;
70 }
71 
72 #define REMMINA_TYPE_PLUGIN_RDPSET_GRID (remmina_rdp_settings_grid_get_type())
73 #define REMMINA_RDPSET_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), REMMINA_TYPE_PLUGIN_RDPSET_GRID, RemminaPluginRdpsetGrid))
74 #define REMMINA_RDPSET_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), REMMINA_TYPE_PLUGIN_RDPSET_GRID, RemminaPluginRdpsetGridClass))
75 #define REMMINA_IS_PLUGIN_RDPSET_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), REMMINA_TYPE_PLUGIN_RDPSET_GRID))
76 #define REMMINA_IS_PLUGIN_RDPSET_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), REMMINA_TYPE_PLUGIN_RDPSET_GRID))
77 #define REMMINA_RDPSET_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), REMMINA_TYPE_PLUGIN_RDPSET_GRID, RemminaPluginRdpsetGridClass))
78 
79 typedef struct _RemminaPluginRdpsetGrid {
80  GtkGrid grid;
81 
84  GtkListStore* keyboard_layout_store;
85 
86  GtkWidget* quality_combo;
87  GtkListStore* quality_store;
88  GtkWidget* wallpaper_check;
89  GtkWidget* windowdrag_check;
90  GtkWidget* menuanimation_check;
91  GtkWidget* theme_check;
92  GtkWidget* cursorshadow_check;
94  GtkWidget* fontsmoothing_check;
95  GtkWidget* composition_check;
97 
98  /* FreeRDP /scale-desktop: Scaling of desktop app */
100  /* FreeRDP /scale-device: Scaling of appstore app */
103  /* FreeRDP /orientation: Orientation of display */
106 
107  guint quality_values[10];
109 
111  GtkGridClass parent_class;
113 
114 GType remmina_rdp_settings_grid_get_type(void) G_GNUC_CONST;
115 
116 G_DEFINE_TYPE(RemminaPluginRdpsetGrid, remmina_rdp_settings_grid, GTK_TYPE_GRID)
117 
118 static void remmina_rdp_settings_grid_class_init(RemminaPluginRdpsetGridClass* klass)
119 {
120  TRACE_CALL(__func__);
121 }
122 
123 static void remmina_rdp_settings_grid_destroy(GtkWidget* widget, gpointer data)
124 {
125  TRACE_CALL(__func__);
126  gchar* s;
127  guint new_layout;
128  GtkTreeIter iter;
130  gint val;
131 
132  grid = REMMINA_RDPSET_GRID(widget);
133 
134  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->keyboard_layout_combo), &iter)) {
135  gtk_tree_model_get(GTK_TREE_MODEL(grid->keyboard_layout_store), &iter, 0, &new_layout, -1);
136 
137  if (new_layout != rdp_keyboard_layout) {
138  rdp_keyboard_layout = new_layout;
139  s = g_strdup_printf("%X", new_layout);
140  remmina_plugin_service->pref_set_value("rdp_keyboard_layout", s);
141  g_free(s);
142 
144  }
145  }
146 
147  remmina_plugin_service->pref_set_value("rdp_use_client_keymap",
148  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->use_client_keymap_check)) ? "1" : "0");
149 
150  s = g_strdup_printf("%X", grid->quality_values[0]);
151  remmina_plugin_service->pref_set_value("rdp_quality_0", s);
152  g_free(s);
153 
154  s = g_strdup_printf("%X", grid->quality_values[1]);
155  remmina_plugin_service->pref_set_value("rdp_quality_1", s);
156  g_free(s);
157 
158  s = g_strdup_printf("%X", grid->quality_values[2]);
159  remmina_plugin_service->pref_set_value("rdp_quality_2", s);
160  g_free(s);
161 
162  s = g_strdup_printf("%X", grid->quality_values[9]);
163  remmina_plugin_service->pref_set_value("rdp_quality_9", s);
164  g_free(s);
165 
166  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->device_scale_factor_combo), &iter)) {
167  gtk_tree_model_get(GTK_TREE_MODEL(grid->device_scale_factor_store), &iter, 0, &val, -1);
168  } else {
169  val = 0;
170  }
171  s = g_strdup_printf("%d", val);
172  remmina_plugin_service->pref_set_value("rdp_deviceScaleFactor", s);
173  g_free(s);
174 
175  val = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin));
176  s = g_strdup_printf("%d", val);
177  remmina_plugin_service->pref_set_value("rdp_desktopScaleFactor", s);
178  g_free(s);
179 
180  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->desktop_orientation_combo), &iter)) {
181  gtk_tree_model_get(GTK_TREE_MODEL(grid->desktop_orientation_store), &iter, 0, &val, -1);
182  } else {
183  val = 0;
184  }
185  s = g_strdup_printf("%d", val);
186  remmina_plugin_service->pref_set_value("rdp_desktopOrientation", s);
187  g_free(s);
188 
189 }
190 
192 {
193  TRACE_CALL(__func__);
194  gint i;
195  gchar* s;
196  GtkTreeIter iter;
197  RDP_KEYBOARD_LAYOUT* layouts;
198 
199  gtk_list_store_append(grid->keyboard_layout_store, &iter);
200  gtk_list_store_set(grid->keyboard_layout_store, &iter, 0, 0, 1, _("<Auto detect>"), -1);
201 
202  if (rdp_keyboard_layout == 0)
203  gtk_combo_box_set_active(GTK_COMBO_BOX(grid->keyboard_layout_combo), 0);
204 
205  gtk_label_set_text(GTK_LABEL(grid->keyboard_layout_label), "-");
206 
207  layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD | RDP_KEYBOARD_LAYOUT_TYPE_VARIANT);
208 
209  for (i = 0; layouts[i].code; i++) {
210  s = g_strdup_printf("%08X - %s", layouts[i].code, layouts[i].name);
211  gtk_list_store_append(grid->keyboard_layout_store, &iter);
212  gtk_list_store_set(grid->keyboard_layout_store, &iter, 0, layouts[i].code, 1, s, -1);
213 
214  if (rdp_keyboard_layout == layouts[i].code)
215  gtk_combo_box_set_active(GTK_COMBO_BOX(grid->keyboard_layout_combo), i + 1);
216 
217  if (keyboard_layout == layouts[i].code)
218  gtk_label_set_text(GTK_LABEL(grid->keyboard_layout_label), s);
219 
220  g_free(s);
221  }
222 
223  free(layouts);
224 }
225 
226 
228 {
229  TRACE_CALL(__func__);
230  GtkTreeIter iter;
231 
232  gtk_list_store_append(grid->device_scale_factor_store, &iter);
233  gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 0, 1, _("<Not set>"), -1);
234  gtk_list_store_append(grid->device_scale_factor_store, &iter);
235  gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 100, 1, "100%", -1);
236  gtk_list_store_append(grid->device_scale_factor_store, &iter);
237  gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 140, 1, "140%", -1);
238  gtk_list_store_append(grid->device_scale_factor_store, &iter);
239  gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 180, 1, "180%", -1);
240 
241 }
242 
244 {
245  TRACE_CALL(__func__);
246  GtkTreeIter iter;
247 
248  gtk_list_store_append(grid->desktop_orientation_store, &iter);
249  gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 0, 1, "0°", -1);
250  gtk_list_store_append(grid->desktop_orientation_store, &iter);
251  gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 90, 1, "90°", -1);
252  gtk_list_store_append(grid->desktop_orientation_store, &iter);
253  gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 180, 1, "180°", -1);
254  gtk_list_store_append(grid->desktop_orientation_store, &iter);
255  gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 270, 1, "270°", -1);
256 
257 }
258 
259 
261 {
262  TRACE_CALL(__func__);
263  gchar* value;
264  GtkTreeIter iter;
265 
266  gtk_list_store_append(grid->quality_store, &iter);
267  gtk_list_store_set(grid->quality_store, &iter, 0, -1, 1, _("<Choose a quality level to edit…>"), -1);
268  gtk_list_store_append(grid->quality_store, &iter);
269  gtk_list_store_set(grid->quality_store, &iter, 0, 0, 1, _("Poor (fastest)"), -1);
270  gtk_list_store_append(grid->quality_store, &iter);
271  gtk_list_store_set(grid->quality_store, &iter, 0, 1, 1, _("Medium"), -1);
272  gtk_list_store_append(grid->quality_store, &iter);
273  gtk_list_store_set(grid->quality_store, &iter, 0, 2, 1, _("Good"), -1);
274  gtk_list_store_append(grid->quality_store, &iter);
275  gtk_list_store_set(grid->quality_store, &iter, 0, 9, 1, _("Best (slowest)"), -1);
276 
277  memset(grid->quality_values, 0, sizeof(grid->quality_values));
278 
279  value = remmina_plugin_service->pref_get_value("rdp_quality_0");
280  grid->quality_values[0] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_0);
281  g_free(value);
282 
283  value = remmina_plugin_service->pref_get_value("rdp_quality_1");
284  grid->quality_values[1] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_1);
285  g_free(value);
286 
287  value = remmina_plugin_service->pref_get_value("rdp_quality_2");
288  grid->quality_values[2] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_2);
289  g_free(value);
290 
291  value = remmina_plugin_service->pref_get_value("rdp_quality_9");
292  grid->quality_values[9] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_9);
293  g_free(value);
294 }
295 
297 {
298  TRACE_CALL(__func__);
299  GtkTreeIter iter;
300  guint i = 0;
301 
302  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->device_scale_factor_combo), &iter)) {
303  gtk_tree_model_get(GTK_TREE_MODEL(grid->device_scale_factor_store), &iter, 0, &i, -1);
304  }
305  if (i == 0) {
306  gtk_widget_set_sensitive(GTK_WIDGET(grid->desktop_scale_factor_spin), FALSE);
307  gtk_spin_button_set_range(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), 0, 0);
308  gtk_spin_button_set_value(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), 0);
309  }else {
310  gtk_widget_set_sensitive(GTK_WIDGET(grid->desktop_scale_factor_spin), TRUE);
311  gtk_spin_button_set_range(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), 100, 500);
312  // gtk_spin_button_set_value(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), i);
313  }
314 }
315 
317 {
318  TRACE_CALL(__func__);
319  guint v;
320  guint i = 0;
321  GtkTreeIter iter;
322  gboolean sensitive;
323 
324  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->quality_combo), &iter)) {
325  gtk_tree_model_get(GTK_TREE_MODEL(grid->quality_store), &iter, 0, &i, -1);
326  sensitive = ( i != -1 );
327 
328  if (sensitive)
329  v = grid->quality_values[i];
330  else
331  v = 0x3f; /* All checkboxes disabled */
332 
333  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->wallpaper_check), (v & 1) == 0);
334  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->windowdrag_check), (v & 2) == 0);
335  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->menuanimation_check), (v & 4) == 0);
336  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->theme_check), (v & 8) == 0);
337  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->cursorshadow_check), (v & 0x20) == 0);
338  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->cursorblinking_check), (v & 0x40) == 0);
339  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->fontsmoothing_check), (v & 0x80) != 0);
340  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->composition_check), (v & 0x100) != 0);
341 
342 
343  gtk_widget_set_sensitive(GTK_WIDGET(grid->wallpaper_check), sensitive);
344  gtk_widget_set_sensitive(GTK_WIDGET(grid->windowdrag_check), sensitive);
345  gtk_widget_set_sensitive(GTK_WIDGET(grid->menuanimation_check), sensitive);
346  gtk_widget_set_sensitive(GTK_WIDGET(grid->theme_check), sensitive);
347  gtk_widget_set_sensitive(GTK_WIDGET(grid->cursorshadow_check), sensitive);
348  gtk_widget_set_sensitive(GTK_WIDGET(grid->cursorblinking_check), sensitive);
349  gtk_widget_set_sensitive(GTK_WIDGET(grid->fontsmoothing_check), sensitive);
350  gtk_widget_set_sensitive(GTK_WIDGET(grid->composition_check), sensitive);
351  }
352 }
353 
355 {
356  TRACE_CALL(__func__);
357  guint v;
358  guint i = 0;
359  GtkTreeIter iter;
360 
361  if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->quality_combo), &iter)) {
362  gtk_tree_model_get(GTK_TREE_MODEL(grid->quality_store), &iter, 0, &i, -1);
363  if (i != -1) {
364  v = 0;
365  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->wallpaper_check)) ? 0 : 1);
366  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->windowdrag_check)) ? 0 : 2);
367  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->menuanimation_check)) ? 0 : 4);
368  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->theme_check)) ? 0 : 8);
369  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->cursorshadow_check)) ? 0 : 0x20);
370  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->cursorblinking_check)) ? 0 : 0x40);
371  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->fontsmoothing_check)) ? 0x80 : 0);
372  v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->composition_check)) ? 0x100 : 0);
373  grid->quality_values[i] = v;
374  }
375  }
376 }
377 
378 static void remmina_rdp_settings_set_combo_active_item(GtkComboBox* combo, int itemval)
379 {
380  GtkTreeIter iter;
381  int i;
382  GtkTreeModel *m;
383  gboolean valid;
384 
385  m = gtk_combo_box_get_model(combo);
386  if (!m) {
387  return;
388  }
389 
390  valid = gtk_tree_model_get_iter_first(m, &iter);
391  while (valid) {
392  gtk_tree_model_get(m, &iter, 0, &i, -1);
393  if (i == itemval) {
394  gtk_combo_box_set_active_iter(combo, &iter);
395  }
396  valid = gtk_tree_model_iter_next(m, &iter);
397  }
398 
399 }
400 
402 {
403  TRACE_CALL(__func__);
404  gchar* s;
405  GtkWidget* widget;
406  GtkCellRenderer* renderer;
407  int desktopOrientation, desktopScaleFactor, deviceScaleFactor;
408 
409  /* Create the grid */
410  g_signal_connect(G_OBJECT(grid), "destroy", G_CALLBACK(remmina_rdp_settings_grid_destroy), NULL);
411  gtk_grid_set_row_homogeneous(GTK_GRID(grid), FALSE);
412  gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE);
413  gtk_container_set_border_width(GTK_CONTAINER(grid), 8);
414  gtk_grid_set_row_spacing(GTK_GRID(grid), 4);
415  gtk_grid_set_column_spacing(GTK_GRID(grid), 4);
416 
417  /* Create the content */
418  widget = gtk_label_new(_("Keyboard layout"));
419  gtk_widget_show(widget);
420  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
421  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
422  gtk_grid_attach(GTK_GRID(grid), widget, 0, 0, 1, 1);
423 
424  grid->keyboard_layout_store = gtk_list_store_new(2, G_TYPE_UINT, G_TYPE_STRING);
425  widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->keyboard_layout_store));
426  gtk_widget_show(widget);
427  gtk_grid_attach(GTK_GRID(grid), widget, 1, 0, 4, 1);
428 
429  renderer = gtk_cell_renderer_text_new();
430  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
431  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1);
432  grid->keyboard_layout_combo = widget;
433 
434  widget = gtk_label_new("-");
435  gtk_widget_show(widget);
436  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
437  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
438  gtk_grid_attach(GTK_GRID(grid), widget, 1, 1, 4, 2);
439  grid->keyboard_layout_label = widget;
440 
442 
443  widget = gtk_check_button_new_with_label(_("Use client keyboard mapping"));
444  gtk_widget_show(widget);
445  gtk_grid_attach(GTK_GRID(grid), widget, 1, 3, 3, 3);
446  grid->use_client_keymap_check = widget;
447 
448  s = remmina_plugin_service->pref_get_value("rdp_use_client_keymap");
449  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
450  s && s[0] == '1' ? TRUE : FALSE);
451  g_free(s);
452 
453  widget = gtk_label_new(_("Quality settings"));
454  gtk_widget_show(widget);
455  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
456  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
457  gtk_grid_attach(GTK_GRID(grid), widget, 0, 6, 1, 4);
458 
459  grid->quality_store = gtk_list_store_new(2, G_TYPE_UINT, G_TYPE_STRING);
460  widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->quality_store));
461  gtk_widget_show(widget);
462  gtk_grid_attach(GTK_GRID(grid), widget, 1, 6, 4, 4);
463 
464  renderer = gtk_cell_renderer_text_new();
465  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
466  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1);
467  g_signal_connect(G_OBJECT(widget), "changed",
468  G_CALLBACK(remmina_rdp_settings_quality_on_changed), grid);
469  grid->quality_combo = widget;
470 
472 
473  widget = gtk_check_button_new_with_label(_("Wallpaper"));
474  gtk_widget_show(widget);
475  gtk_grid_attach(GTK_GRID(grid), widget, 1, 10, 2, 5);
476  g_signal_connect(G_OBJECT(widget), "toggled",
478  grid->wallpaper_check = widget;
479 
480  widget = gtk_check_button_new_with_label(_("Window drag"));
481  gtk_widget_show(widget);
482  gtk_grid_attach(GTK_GRID(grid), widget, 3, 10, 3, 5);
483  g_signal_connect(G_OBJECT(widget), "toggled",
485  grid->windowdrag_check = widget;
486 
487  widget = gtk_check_button_new_with_label(_("Menu animation"));
488  gtk_widget_show(widget);
489  gtk_grid_attach(GTK_GRID(grid), widget, 1, 13, 2, 6);
490  g_signal_connect(G_OBJECT(widget), "toggled",
492  grid->menuanimation_check = widget;
493 
494  widget = gtk_check_button_new_with_label(_("Theme"));
495  gtk_widget_show(widget);
496  gtk_grid_attach(GTK_GRID(grid), widget, 3, 13, 3, 6);
497  g_signal_connect(G_OBJECT(widget), "toggled",
499  grid->theme_check = widget;
500 
501  widget = gtk_check_button_new_with_label(_("Cursor shadow"));
502  gtk_widget_show(widget);
503  gtk_grid_attach(GTK_GRID(grid), widget, 1, 16, 2, 7);
504  g_signal_connect(G_OBJECT(widget), "toggled",
506  grid->cursorshadow_check = widget;
507 
508  widget = gtk_check_button_new_with_label(_("Cursor blinking"));
509  gtk_widget_show(widget);
510  gtk_grid_attach(GTK_GRID(grid), widget, 3, 16, 3, 7);
511  g_signal_connect(G_OBJECT(widget), "toggled",
513  grid->cursorblinking_check = widget;
514 
515  widget = gtk_check_button_new_with_label(_("Font smoothing"));
516  gtk_widget_show(widget);
517  gtk_grid_attach(GTK_GRID(grid), widget, 1, 19, 2, 8);
518  g_signal_connect(G_OBJECT(widget), "toggled",
520  grid->fontsmoothing_check = widget;
521 
522  widget = gtk_check_button_new_with_label(_("Composition"));
523  gtk_widget_show(widget);
524  gtk_grid_attach(GTK_GRID(grid), widget, 3, 19, 3, 8);
525  g_signal_connect(G_OBJECT(widget), "toggled",
527  grid->composition_check = widget;
528 
529  gtk_combo_box_set_active(GTK_COMBO_BOX(grid->quality_combo), 0);
530 
531 
532  widget = gtk_label_new(_("Remote scale factor"));
533  gtk_widget_show(widget);
534  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
535  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
536  gtk_grid_attach(GTK_GRID(grid), widget, 0, 27, 1, 1);
537 
538  grid->device_scale_factor_store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
539  grid->desktop_orientation_store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
540 
541  remmina_rdp_settings_get_orientation_scale_prefs(&desktopOrientation, &desktopScaleFactor, &deviceScaleFactor);
544 
545  widget = gtk_label_new(_("Desktop scale factor %"));
546  gtk_widget_show(widget);
547  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
548  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
549  gtk_grid_attach(GTK_GRID(grid), widget, 1, 27, 1, 1);
550 
551  widget = gtk_spin_button_new_with_range(0, 10000, 1);
552  gtk_widget_show(widget);
553  gtk_grid_attach(GTK_GRID(grid), widget, 2, 27, 1, 1);
554  grid->desktop_scale_factor_spin = widget;
555 
556  widget = gtk_label_new(_("Device scale factor %"));
557  gtk_widget_show(widget);
558  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
559  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
560  gtk_grid_attach(GTK_GRID(grid), widget, 1, 28, 1, 1);
561 
562  widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->device_scale_factor_store));
563  gtk_widget_show(widget);
564  gtk_grid_attach(GTK_GRID(grid), widget, 2, 28, 1, 1);
565 
566  renderer = gtk_cell_renderer_text_new();
567  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
568  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1);
569  grid->device_scale_factor_combo = widget;
570 
571  remmina_rdp_settings_set_combo_active_item(GTK_COMBO_BOX(grid->device_scale_factor_combo), deviceScaleFactor);
572  gtk_spin_button_set_value(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), (gdouble)desktopScaleFactor);
573 
574  g_signal_connect(G_OBJECT(widget), "changed",
575  G_CALLBACK(remmina_rdp_settings_appscale_on_changed), grid);
577 
578  widget = gtk_label_new(_("Desktop orientation"));
579  gtk_widget_show(widget);
580  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
581  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
582  gtk_grid_attach(GTK_GRID(grid), widget, 0, 29, 1, 1);
583 
584  widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->desktop_orientation_store));
585  gtk_widget_show(widget);
586  gtk_grid_attach(GTK_GRID(grid), widget, 1, 29, 1, 1);
587 
588  renderer = gtk_cell_renderer_text_new();
589  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
590  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1);
591  grid->desktop_orientation_combo = widget;
592 
593  remmina_rdp_settings_set_combo_active_item(GTK_COMBO_BOX(grid->desktop_orientation_combo), desktopOrientation);
594 
595 }
596 
597 GtkWidget* remmina_rdp_settings_new(void)
598 {
599  TRACE_CALL(__func__);
600  GtkWidget* widget;
601 
602  widget = GTK_WIDGET(g_object_new(REMMINA_TYPE_PLUGIN_RDPSET_GRID, NULL));
603  gtk_widget_show(widget);
604 
605  return widget;
606 }
607 
608 void remmina_rdp_settings_get_orientation_scale_prefs(int *desktopOrientation, int *desktopScaleFactor, int *deviceScaleFactor)
609 {
610  TRACE_CALL(__func__);
611 
612  /* See https://msdn.microsoft.com/en-us/library/cc240510.aspx */
613 
614  int orientation, dpsf, desf;
615  gchar* s;
616 
617  *desktopOrientation = *desktopScaleFactor = *deviceScaleFactor = 0;
618 
619  s = remmina_plugin_service->pref_get_value("rdp_desktopOrientation");
620  orientation = s ? atoi(s) : 0;
621  g_free(s);
622  if (orientation != 90 && orientation != 180 && orientation != 270)
623  orientation = 0;
624  *desktopOrientation = orientation;
625 
626  s = remmina_plugin_service->pref_get_value("rdp_desktopScaleFactor");
627  dpsf = s ? atoi(s) : 0;
628  g_free(s);
629  if (dpsf < 100 || dpsf > 500)
630  return;
631 
632  s = remmina_plugin_service->pref_get_value("rdp_deviceScaleFactor");
633  desf = s ? atoi(s) : 0;
634  g_free(s);
635  if (desf != 100 && desf != 140 && desf != 180)
636  return;
637 
638  *desktopScaleFactor = dpsf;
639  *deviceScaleFactor = desf;
640 
641 }
GtkListStore * device_scale_factor_store
Definition: rdp_settings.c:101
GtkWidget * composition_check
Definition: rdp_settings.c:95
GtkWidget * keyboard_layout_label
Definition: rdp_settings.c:82
static void remmina_rdp_settings_grid_load_devicescalefactor_combo(RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:227
static guint keyboard_layout
Definition: rdp_settings.c:42
GtkListStore * desktop_orientation_store
Definition: rdp_settings.c:104
GtkWidget * fontsmoothing_check
Definition: rdp_settings.c:94
static guint rdp_keyboard_layout
Definition: rdp_settings.c:43
GtkListStore * quality_store
Definition: rdp_settings.c:87
static void remmina_rdp_settings_grid_init(RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:401
GType remmina_rdp_settings_grid_get_type(void)
Definition: rdp_settings.c:114
GtkWidget * cursorblinking_check
Definition: rdp_settings.c:93
static void remmina_rdp_settings_grid_load_layout(RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:191
GtkWidget * wallpaper_check
Definition: rdp_settings.c:88
void remmina_rdp_settings_get_orientation_scale_prefs(int *desktopOrientation, int *desktopScaleFactor, int *deviceScaleFactor)
Definition: rdp_settings.c:608
static void remmina_rdp_settings_quality_option_on_toggled(GtkToggleButton *togglebutton, RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:354
GtkWidget * menuanimation_check
Definition: rdp_settings.c:90
void remmina_rdp_settings_init(void)
Definition: rdp_settings.c:51
struct _RemminaPluginRdpsetGridClass RemminaPluginRdpsetGridClass
static void remmina_rdp_settings_grid_load_quality(RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:260
GtkWidget * desktop_scale_factor_spin
Definition: rdp_settings.c:99
GtkWidget * remmina_rdp_settings_new(void)
Definition: rdp_settings.c:597
void(* pref_set_value)(const gchar *key, const gchar *value)
Definition: plugin.h:206
struct _RemminaPluginRdpsetGrid RemminaPluginRdpsetGrid
GtkWidget * use_client_keymap_check
Definition: rdp_settings.c:96
G_DEFINE_TYPE(RemminaConnectionWindow, rcw, GTK_TYPE_WINDOW)
Definition: rcw.c:75
static RemminaPluginService * remmina_plugin_service
static void remmina_rdp_settings_kbd_init(void)
Definition: rdp_settings.c:45
gchar *(* pref_get_value)(const gchar *key)
Definition: plugin.h:207
GtkWidget * cursorshadow_check
Definition: rdp_settings.c:92
GtkWidget * desktop_orientation_combo
Definition: rdp_settings.c:105
static void remmina_rdp_settings_set_combo_active_item(GtkComboBox *combo, int itemval)
Definition: rdp_settings.c:378
static void remmina_rdp_settings_appscale_on_changed(GtkComboBox *widget, RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:296
static void remmina_rdp_settings_grid_destroy(GtkWidget *widget, gpointer data)
Definition: rdp_settings.c:123
GtkWidget * windowdrag_check
Definition: rdp_settings.c:89
GtkWidget * device_scale_factor_combo
Definition: rdp_settings.c:102
GtkWidget * keyboard_layout_combo
Definition: rdp_settings.c:83
static void remmina_rdp_settings_grid_load_desktoporientation_combo(RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:243
static void remmina_rdp_settings_quality_on_changed(GtkComboBox *widget, RemminaPluginRdpsetGrid *grid)
Definition: rdp_settings.c:316
GtkListStore * keyboard_layout_store
Definition: rdp_settings.c:84
guint remmina_rdp_settings_get_keyboard_layout(void)
Definition: rdp_settings.c:66