diff options
Diffstat (limited to 'plugins/rdp/rdp_settings.c')
-rw-r--r-- | plugins/rdp/rdp_settings.c | 759 |
1 files changed, 759 insertions, 0 deletions
diff --git a/plugins/rdp/rdp_settings.c b/plugins/rdp/rdp_settings.c new file mode 100644 index 0000000..7a3d4aa --- /dev/null +++ b/plugins/rdp/rdp_settings.c @@ -0,0 +1,759 @@ +/* + * Remmina - The GTK+ Remote Desktop Client + * Copyright (C) 2010-2011 Vic Lee + * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo + * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. * If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. * If you + * do not wish to do so, delete this exception statement from your + * version. * If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#include "rdp_settings.h" +#include <freerdp/locale/keyboard.h> + +static guint keyboard_layout = 0; +static guint rdp_keyboard_layout = 0; +static gchar *rdp_keyboard_remapping_list = NULL; + +static void remmina_rdp_settings_kbd_init(void) +{ + TRACE_CALL(__func__); +#if FREERDP_CHECK_VERSION(2, 3, 0) + rdp_keyboard_remapping_list = g_strdup( + remmina_plugin_service->pref_get_value("rdp_kbd_remap")); + REMMINA_PLUGIN_DEBUG("rdp_keyboard_remapping_list: %s", rdp_keyboard_remapping_list); + keyboard_layout = freerdp_keyboard_init_ex(rdp_keyboard_layout, rdp_keyboard_remapping_list); +#else + keyboard_layout = freerdp_keyboard_init(rdp_keyboard_layout); +#endif +} + +void remmina_rdp_settings_init(void) +{ + TRACE_CALL(__func__); + gchar *value; + + value = remmina_plugin_service->pref_get_value("rdp_keyboard_layout"); + + if (value && value[0]) + rdp_keyboard_layout = strtoul(value, NULL, 16); + + g_free(value); + + remmina_rdp_settings_kbd_init(); +} + +guint remmina_rdp_settings_get_keyboard_layout(void) +{ + TRACE_CALL(__func__); + return keyboard_layout; +} + +#define REMMINA_TYPE_PLUGIN_RDPSET_GRID (remmina_rdp_settings_grid_get_type()) +#define REMMINA_RDPSET_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), REMMINA_TYPE_PLUGIN_RDPSET_GRID, RemminaPluginRdpsetGrid)) +#define REMMINA_RDPSET_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), REMMINA_TYPE_PLUGIN_RDPSET_GRID, RemminaPluginRdpsetGridClass)) +#define REMMINA_IS_PLUGIN_RDPSET_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), REMMINA_TYPE_PLUGIN_RDPSET_GRID)) +#define REMMINA_IS_PLUGIN_RDPSET_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), REMMINA_TYPE_PLUGIN_RDPSET_GRID)) +#define REMMINA_RDPSET_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), REMMINA_TYPE_PLUGIN_RDPSET_GRID, RemminaPluginRdpsetGridClass)) + +typedef struct _RemminaPluginRdpsetGrid { + GtkGrid grid; + + GtkWidget * keyboard_layout_label; + GtkWidget * keyboard_layout_combo; + GtkListStore * keyboard_layout_store; + + GtkWidget * quality_combo; + GtkListStore * quality_store; + GtkWidget * wallpaper_check; + GtkWidget * windowdrag_check; + GtkWidget * menuanimation_check; + GtkWidget * theme_check; + GtkWidget * cursorshadow_check; + GtkWidget * cursorblinking_check; + GtkWidget * fontsmoothing_check; + GtkWidget * composition_check; + GtkWidget * use_client_keymap_check; + GtkWidget * disable_smooth_scrolling_check; + GtkWidget * reconnect_attempts; + GtkWidget * kbd_remap; + + /* FreeRDP /scale-desktop: Scaling of desktop app */ + GtkWidget * desktop_scale_factor_spin; + /* FreeRDP /scale-device: Scaling of appstore app */ + GtkListStore * device_scale_factor_store; + GtkWidget * device_scale_factor_combo; + /* FreeRDP /orientation: Orientation of display */ + GtkListStore * desktop_orientation_store; + GtkWidget * desktop_orientation_combo; + + guint quality_values[10]; +} RemminaPluginRdpsetGrid; + +typedef struct _RemminaPluginRdpsetGridClass { + GtkGridClass parent_class; +} RemminaPluginRdpsetGridClass; + +GType remmina_rdp_settings_grid_get_type(void) G_GNUC_CONST; + +G_DEFINE_TYPE(RemminaPluginRdpsetGrid, remmina_rdp_settings_grid, GTK_TYPE_GRID) + +static void remmina_rdp_settings_grid_class_init(RemminaPluginRdpsetGridClass *klass) +{ + TRACE_CALL(__func__); +} + +static void remmina_rdp_settings_grid_destroy(GtkWidget *widget, gpointer data) +{ + TRACE_CALL(__func__); + gchar *s; + guint new_layout; + GtkTreeIter iter; + RemminaPluginRdpsetGrid *grid; + gint val; + + grid = REMMINA_RDPSET_GRID(widget); + + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->keyboard_layout_combo), &iter)) { + gtk_tree_model_get(GTK_TREE_MODEL(grid->keyboard_layout_store), &iter, 0, &new_layout, -1); + + if (new_layout != rdp_keyboard_layout) { + rdp_keyboard_layout = new_layout; + s = g_strdup_printf("%X", new_layout); + remmina_plugin_service->pref_set_value("rdp_keyboard_layout", s); + g_free(s); + + remmina_rdp_settings_kbd_init(); + } + } + + remmina_plugin_service->pref_set_value("rdp_use_client_keymap", + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->use_client_keymap_check)) ? "1" : "0"); + + remmina_plugin_service->pref_set_value("rdp_disable_smooth_scrolling", + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->disable_smooth_scrolling_check)) ? "1" : "0"); + + remmina_plugin_service->pref_set_value("rdp_reconnect_attempts", + gtk_entry_get_text(GTK_ENTRY(grid->reconnect_attempts))); + + remmina_plugin_service->pref_set_value("rdp_kbd_remap", + gtk_entry_get_text(GTK_ENTRY(grid->kbd_remap))); + + s = g_strdup_printf("%X", grid->quality_values[0]); + remmina_plugin_service->pref_set_value("rdp_quality_0", s); + g_free(s); + + s = g_strdup_printf("%X", grid->quality_values[1]); + remmina_plugin_service->pref_set_value("rdp_quality_1", s); + g_free(s); + + s = g_strdup_printf("%X", grid->quality_values[2]); + remmina_plugin_service->pref_set_value("rdp_quality_2", s); + g_free(s); + + s = g_strdup_printf("%X", grid->quality_values[9]); + remmina_plugin_service->pref_set_value("rdp_quality_9", s); + g_free(s); + + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->device_scale_factor_combo), &iter)) + gtk_tree_model_get(GTK_TREE_MODEL(grid->device_scale_factor_store), &iter, 0, &val, -1); + else + val = 0; + s = g_strdup_printf("%d", val); + remmina_plugin_service->pref_set_value("rdp_deviceScaleFactor", s); + g_free(s); + + val = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin)); + s = g_strdup_printf("%d", val); + remmina_plugin_service->pref_set_value("rdp_desktopScaleFactor", s); + g_free(s); + + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->desktop_orientation_combo), &iter)) + gtk_tree_model_get(GTK_TREE_MODEL(grid->desktop_orientation_store), &iter, 0, &val, -1); + else + val = 0; + s = g_strdup_printf("%d", val); + remmina_plugin_service->pref_set_value("rdp_desktopOrientation", s); + g_free(s); +} + +static void remmina_rdp_settings_grid_load_layout(RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + gchar *s; + GtkTreeIter iter; + RDP_KEYBOARD_LAYOUT *layouts; + + gtk_list_store_append(grid->keyboard_layout_store, &iter); + gtk_list_store_set(grid->keyboard_layout_store, &iter, 0, 0, 1, _("<Auto-detect>"), -1); + + if (rdp_keyboard_layout == 0) + gtk_combo_box_set_active(GTK_COMBO_BOX(grid->keyboard_layout_combo), 0); + + gtk_label_set_text(GTK_LABEL(grid->keyboard_layout_label), "-"); + +#if FREERDP_VERSION_MAJOR >= 3 + size_t layout_count = 0; + layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD | RDP_KEYBOARD_LAYOUT_TYPE_VARIANT, &layout_count); + + for (DWORD i = 0; i < layout_count; i++) { + s = g_strdup_printf("%08X - %s", layouts[i].code, layouts[i].name); + gtk_list_store_append(grid->keyboard_layout_store, &iter); + gtk_list_store_set(grid->keyboard_layout_store, &iter, 0, layouts[i].code, 1, s, -1); + + if (rdp_keyboard_layout == layouts[i].code) + gtk_combo_box_set_active(GTK_COMBO_BOX(grid->keyboard_layout_combo), i + 1); + + if (keyboard_layout == layouts[i].code) + gtk_label_set_text(GTK_LABEL(grid->keyboard_layout_label), s); + + g_free(s); + } + + freerdp_keyboard_layouts_free(layouts, layout_count); +#else + layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD | RDP_KEYBOARD_LAYOUT_TYPE_VARIANT); + + for (DWORD i = 0; layouts[i].code; i++) { + s = g_strdup_printf("%08X - %s", layouts[i].code, layouts[i].name); + gtk_list_store_append(grid->keyboard_layout_store, &iter); + gtk_list_store_set(grid->keyboard_layout_store, &iter, 0, layouts[i].code, 1, s, -1); + + if (rdp_keyboard_layout == layouts[i].code) + gtk_combo_box_set_active(GTK_COMBO_BOX(grid->keyboard_layout_combo), i + 1); + + if (keyboard_layout == layouts[i].code) + gtk_label_set_text(GTK_LABEL(grid->keyboard_layout_label), s); + + g_free(s); + } + + freerdp_keyboard_layouts_free(layouts); +#endif +} + +static void remmina_rdp_settings_grid_load_devicescalefactor_combo(RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + GtkTreeIter iter; + + gtk_list_store_append(grid->device_scale_factor_store, &iter); + gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 0, 1, _("<Not set>"), -1); + gtk_list_store_append(grid->device_scale_factor_store, &iter); + gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 100, 1, "100%", -1); + gtk_list_store_append(grid->device_scale_factor_store, &iter); + gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 140, 1, "140%", -1); + gtk_list_store_append(grid->device_scale_factor_store, &iter); + gtk_list_store_set(grid->device_scale_factor_store, &iter, 0, 180, 1, "180%", -1); +} + +static void remmina_rdp_settings_grid_load_desktoporientation_combo(RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + GtkTreeIter iter; + + gtk_list_store_append(grid->desktop_orientation_store, &iter); + gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 0, 1, "0°", -1); + gtk_list_store_append(grid->desktop_orientation_store, &iter); + gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 90, 1, "90°", -1); + gtk_list_store_append(grid->desktop_orientation_store, &iter); + gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 180, 1, "180°", -1); + gtk_list_store_append(grid->desktop_orientation_store, &iter); + gtk_list_store_set(grid->desktop_orientation_store, &iter, 0, 270, 1, "270°", -1); +} + +static void remmina_rdp_settings_grid_load_quality(RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + gchar *value; + GtkTreeIter iter; + + gtk_list_store_append(grid->quality_store, &iter); + gtk_list_store_set(grid->quality_store, &iter, 0, -1, 1, _("<Choose a quality level to edit…>"), -1); + gtk_list_store_append(grid->quality_store, &iter); + gtk_list_store_set(grid->quality_store, &iter, 0, 0, 1, _("Poor (fastest)"), -1); + gtk_list_store_append(grid->quality_store, &iter); + gtk_list_store_set(grid->quality_store, &iter, 0, 1, 1, _("Medium"), -1); + gtk_list_store_append(grid->quality_store, &iter); + gtk_list_store_set(grid->quality_store, &iter, 0, 2, 1, _("Good"), -1); + gtk_list_store_append(grid->quality_store, &iter); + gtk_list_store_set(grid->quality_store, &iter, 0, 9, 1, _("Best (slowest)"), -1); + + memset(grid->quality_values, 0, sizeof(grid->quality_values)); + + value = remmina_plugin_service->pref_get_value("rdp_quality_0"); + grid->quality_values[0] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_0); + g_free(value); + + value = remmina_plugin_service->pref_get_value("rdp_quality_1"); + grid->quality_values[1] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_1); + g_free(value); + + value = remmina_plugin_service->pref_get_value("rdp_quality_2"); + grid->quality_values[2] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_2); + g_free(value); + + value = remmina_plugin_service->pref_get_value("rdp_quality_9"); + grid->quality_values[9] = (value && value[0] ? strtoul(value, NULL, 16) : DEFAULT_QUALITY_9); + g_free(value); +} + +static void remmina_rdp_settings_appscale_on_changed(GtkComboBox *widget, RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + GtkTreeIter iter; + guint i = 0; + + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->device_scale_factor_combo), &iter)) + gtk_tree_model_get(GTK_TREE_MODEL(grid->device_scale_factor_store), &iter, 0, &i, -1); + if (i == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(grid->desktop_scale_factor_spin), FALSE); + gtk_spin_button_set_range(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), 0, 0); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), 0); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(grid->desktop_scale_factor_spin), TRUE); + gtk_spin_button_set_range(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), 100, 500); + // gtk_spin_button_set_value(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), i); + } +} + +static void remmina_rdp_settings_quality_on_changed(GtkComboBox *widget, RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + guint v; + guint i = 0; + GtkTreeIter iter; + gboolean sensitive; + + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->quality_combo), &iter)) { + gtk_tree_model_get(GTK_TREE_MODEL(grid->quality_store), &iter, 0, &i, -1); + sensitive = (i != -1); + + if (sensitive) + v = grid->quality_values[i]; + else + v = 0x3f; /* All checkboxes disabled */ + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->wallpaper_check), (v & 1) == 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->windowdrag_check), (v & 2) == 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->menuanimation_check), (v & 4) == 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->theme_check), (v & 8) == 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->cursorshadow_check), (v & 0x20) == 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->cursorblinking_check), (v & 0x40) == 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->fontsmoothing_check), (v & 0x80) != 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grid->composition_check), (v & 0x100) != 0); + + + gtk_widget_set_sensitive(GTK_WIDGET(grid->wallpaper_check), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(grid->windowdrag_check), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(grid->menuanimation_check), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(grid->theme_check), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(grid->cursorshadow_check), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(grid->cursorblinking_check), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(grid->fontsmoothing_check), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(grid->composition_check), sensitive); + } +} + +static void remmina_rdp_settings_quality_option_on_toggled(GtkToggleButton *togglebutton, RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + guint v; + guint i = 0; + GtkTreeIter iter; + + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(grid->quality_combo), &iter)) { + gtk_tree_model_get(GTK_TREE_MODEL(grid->quality_store), &iter, 0, &i, -1); + if (i != -1) { + v = 0; + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->wallpaper_check)) ? 0 : 1); + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->windowdrag_check)) ? 0 : 2); + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->menuanimation_check)) ? 0 : 4); + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->theme_check)) ? 0 : 8); + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->cursorshadow_check)) ? 0 : 0x20); + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->cursorblinking_check)) ? 0 : 0x40); + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->fontsmoothing_check)) ? 0x80 : 0); + v |= (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(grid->composition_check)) ? 0x100 : 0); + grid->quality_values[i] = v; + } + } +} + +static void remmina_rdp_settings_set_combo_active_item(GtkComboBox *combo, int itemval) +{ + GtkTreeIter iter; + int i; + GtkTreeModel *m; + gboolean valid; + + m = gtk_combo_box_get_model(combo); + if (!m) + return; + + valid = gtk_tree_model_get_iter_first(m, &iter); + while (valid) { + gtk_tree_model_get(m, &iter, 0, &i, -1); + if (i == itemval) + gtk_combo_box_set_active_iter(combo, &iter); + valid = gtk_tree_model_iter_next(m, &iter); + } +} + +static void remmina_rdp_settings_grid_init(RemminaPluginRdpsetGrid *grid) +{ + TRACE_CALL(__func__); + gchar *s; + GtkWidget *widget; + GtkCellRenderer *renderer; + int desktopOrientation, desktopScaleFactor, deviceScaleFactor; + + /* Create the grid */ + g_signal_connect(G_OBJECT(grid), "destroy", G_CALLBACK(remmina_rdp_settings_grid_destroy), NULL); + gtk_grid_set_row_homogeneous(GTK_GRID(grid), FALSE); + gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE); + gtk_container_set_border_width(GTK_CONTAINER(grid), 8); + gtk_grid_set_row_spacing(GTK_GRID(grid), 4); + gtk_grid_set_column_spacing(GTK_GRID(grid), 4); + + /* Create the content */ + widget = gtk_label_new(_("Keyboard layout")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(GTK_WIDGET(widget), 6); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 18); + gtk_widget_set_margin_top(GTK_WIDGET(widget), 18); + gtk_grid_attach(GTK_GRID(grid), widget, 0, 0, 1, 1); + + grid->keyboard_layout_store = gtk_list_store_new(2, G_TYPE_UINT, G_TYPE_STRING); + widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->keyboard_layout_store)); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 0, 2, 1); + + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1); + grid->keyboard_layout_combo = widget; + + widget = gtk_label_new("-"); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 1, 2, 1); + grid->keyboard_layout_label = widget; + + remmina_rdp_settings_grid_load_layout(grid); + + widget = gtk_check_button_new_with_label(_("Use client keyboard mapping")); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 2, 1, 1); + grid->use_client_keymap_check = widget; + + s = remmina_plugin_service->pref_get_value("rdp_use_client_keymap"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), + s && s[0] == '1' ? TRUE : FALSE); + g_free(s); + + widget = gtk_label_new(_("Keyboard scancode remapping")); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 3, 1, 1); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + widget = gtk_entry_new(); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_END); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 3, 1, 1); + gtk_entry_set_width_chars(GTK_ENTRY(widget), 32); +#if FREERDP_CHECK_VERSION(2, 3, 0) + /* This is the default, but we set it to make things crystal clear */ + gtk_widget_set_sensitive (widget, TRUE); + gtk_widget_set_tooltip_text(widget, _("List of key=value,… pairs to remap scancodes. E.g. 0x56=0x29,0x29=0x56")); +#else + gtk_widget_set_sensitive (widget, FALSE); + gtk_widget_set_tooltip_text(widget, _("FreeRDP > 2.3.0 is required to map scancodes")); +#endif + s = remmina_plugin_service->pref_get_value("rdp_kbd_remap"); + if (s && s[0]) + gtk_entry_set_text(GTK_ENTRY(widget), s); + g_free(s); + grid->kbd_remap = widget; + + widget = gtk_label_new(_("Quality settings")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(GTK_WIDGET(widget), 6); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 18); + gtk_grid_attach(GTK_GRID(grid), widget, 0, 4, 1, 1); + + grid->quality_store = gtk_list_store_new(2, G_TYPE_UINT, G_TYPE_STRING); + widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->quality_store)); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 4, 2, 1); + + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1); + g_signal_connect(G_OBJECT(widget), "changed", + G_CALLBACK(remmina_rdp_settings_quality_on_changed), grid); + grid->quality_combo = widget; + + remmina_rdp_settings_grid_load_quality(grid); + + widget = gtk_check_button_new_with_label(_("Wallpaper")); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 5, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->wallpaper_check = widget; + + widget = gtk_check_button_new_with_label(_("Window drag")); + gtk_widget_show(widget); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 5, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->windowdrag_check = widget; + + widget = gtk_check_button_new_with_label(_("Menu animation")); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 6, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->menuanimation_check = widget; + + widget = gtk_check_button_new_with_label(_("Theme")); + gtk_widget_show(widget); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 6, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->theme_check = widget; + + widget = gtk_check_button_new_with_label(_("Cursor shadow")); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 7, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->cursorshadow_check = widget; + + widget = gtk_check_button_new_with_label(_("Cursor blinking")); + gtk_widget_show(widget); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 7, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->cursorblinking_check = widget; + + widget = gtk_check_button_new_with_label(_("Font smoothing")); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 8, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->fontsmoothing_check = widget; + + widget = gtk_check_button_new_with_label(_("Composition")); + gtk_widget_show(widget); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 8, 1, 1); + g_signal_connect(G_OBJECT(widget), "toggled", + G_CALLBACK(remmina_rdp_settings_quality_option_on_toggled), grid); + grid->composition_check = widget; + + gtk_combo_box_set_active(GTK_COMBO_BOX(grid->quality_combo), 0); + + + widget = gtk_label_new(_("Remote scale factor")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(GTK_WIDGET(widget), 6); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 18); + gtk_grid_attach(GTK_GRID(grid), widget, 0, 9, 1, 1); + + grid->device_scale_factor_store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING); + grid->desktop_orientation_store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING); + + remmina_rdp_settings_get_orientation_scale_prefs(&desktopOrientation, &desktopScaleFactor, &deviceScaleFactor); + remmina_rdp_settings_grid_load_devicescalefactor_combo(grid); + remmina_rdp_settings_grid_load_desktoporientation_combo(grid); + + widget = gtk_label_new(_("Desktop scale factor %")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 9, 1, 1); + + widget = gtk_spin_button_new_with_range(0, 10000, 1); + gtk_widget_show(widget); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 9, 1, 1); + grid->desktop_scale_factor_spin = widget; + + widget = gtk_label_new(_("Device scale factor %")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 10, 1, 1); + + widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->device_scale_factor_store)); + gtk_widget_show(widget); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 10, 1, 1); + + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1); + grid->device_scale_factor_combo = widget; + + remmina_rdp_settings_set_combo_active_item(GTK_COMBO_BOX(grid->device_scale_factor_combo), deviceScaleFactor); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(grid->desktop_scale_factor_spin), (gdouble)desktopScaleFactor); + + g_signal_connect(G_OBJECT(widget), "changed", + G_CALLBACK(remmina_rdp_settings_appscale_on_changed), grid); + remmina_rdp_settings_appscale_on_changed(GTK_COMBO_BOX(grid->device_scale_factor_combo), grid); + + widget = gtk_label_new(_("Desktop orientation")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(GTK_WIDGET(widget), 6); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 18); + gtk_grid_attach(GTK_GRID(grid), widget, 0, 11, 1, 1); + + widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(grid->desktop_orientation_store)); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 11, 2, 1); + + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 1); + grid->desktop_orientation_combo = widget; + + remmina_rdp_settings_set_combo_active_item(GTK_COMBO_BOX(grid->desktop_orientation_combo), desktopOrientation); + + widget = gtk_label_new(_("Input device settings")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(GTK_WIDGET(widget), 6); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 18); + gtk_grid_attach(GTK_GRID(grid), widget, 0, 12, 1, 1); + + widget = gtk_check_button_new_with_label(_("Disable smooth scrolling")); + gtk_widget_show(widget); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 12, 2, 1); + grid->disable_smooth_scrolling_check = widget; + + s = remmina_plugin_service->pref_get_value("rdp_disable_smooth_scrolling"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), + s && s[0] == '1' ? TRUE : FALSE); + g_free(s); + + widget = gtk_label_new(_("General settings")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(GTK_WIDGET(widget), 6); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 18); + gtk_grid_attach(GTK_GRID(grid), widget, 0, 13, 1, 1); + widget = gtk_label_new(_("Reconnect attempts number")); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_widget_set_margin_start(GTK_WIDGET(widget), 6); + gtk_grid_attach(GTK_GRID(grid), widget, 1, 13, 1, 1); + widget = gtk_entry_new(); + gtk_widget_show(widget); + gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_END); + gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(grid), widget, 2, 13, 1, 1); + gtk_entry_set_input_purpose(GTK_ENTRY(widget), GTK_INPUT_PURPOSE_NUMBER); + gtk_entry_set_input_hints(GTK_ENTRY(widget), GTK_INPUT_HINT_NONE); + gtk_widget_set_tooltip_text(widget, _("The maximum number of reconnect attempts upon an RDP disconnect (default: 20)")); + s = remmina_plugin_service->pref_get_value("rdp_reconnect_attempts"); + if (s && s[0]) + gtk_entry_set_text(GTK_ENTRY(widget), s); + g_free(s); + grid->reconnect_attempts = widget; + +} + +GtkWidget *remmina_rdp_settings_new(RemminaPrefPlugin* plugin) +{ + TRACE_CALL(__func__); + GtkWidget *widget; + + widget = GTK_WIDGET(g_object_new(REMMINA_TYPE_PLUGIN_RDPSET_GRID, NULL)); + gtk_widget_show(widget); + + return widget; +} + +void remmina_rdp_settings_get_orientation_scale_prefs(int *desktopOrientation, int *desktopScaleFactor, int *deviceScaleFactor) +{ + TRACE_CALL(__func__); + + /* See https://msdn.microsoft.com/en-us/library/cc240510.aspx */ + + int orientation, dpsf, desf; + gchar *s; + + *desktopOrientation = *desktopScaleFactor = *deviceScaleFactor = 0; + + s = remmina_plugin_service->pref_get_value("rdp_desktopOrientation"); + orientation = s ? atoi(s) : 0; + g_free(s); + if (orientation != 90 && orientation != 180 && orientation != 270) + orientation = 0; + *desktopOrientation = orientation; + + s = remmina_plugin_service->pref_get_value("rdp_desktopScaleFactor"); + dpsf = s ? atoi(s) : 0; + g_free(s); + if (dpsf < 100 || dpsf > 500) + return; + + s = remmina_plugin_service->pref_get_value("rdp_deviceScaleFactor"); + desf = s ? atoi(s) : 0; + g_free(s); + if (desf != 100 && desf != 140 && desf != 180) + return; + + *desktopScaleFactor = dpsf; + *deviceScaleFactor = desf; +} |