39 #include <glib/gi18n.h> 46 #ifdef HAVE_SYS_SOCKET_H 47 #include <sys/socket.h> 52 #ifdef GDK_WINDOWING_X11 55 #include <X11/Xutil.h> 56 #include <X11/Xatom.h> 67 gchar *buf, *ptr1, *ptr2;
70 combo = gtk_combo_box_text_new_with_entry();
73 if (text && text[0] !=
'\0') {
77 while (ptr1 && *ptr1 !=
'\0') {
78 ptr2 = strchr(ptr1, CHAR_DELIMITOR);
83 gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(combo), ptr1);
84 if (!found && g_strcmp0(ptr1, def) == 0) {
85 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
89 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ptr1);
90 if (!found && g_strcmp0(ptr1, def) == 0) {
91 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
103 if (!found && def && def[0] !=
'\0') {
104 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo))), def);
113 TRACE_CALL(__func__);
116 GtkCellRenderer *text_renderer;
118 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
119 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
121 text_renderer = gtk_cell_renderer_text_new();
122 gtk_cell_layout_pack_end(GTK_CELL_LAYOUT(combo), text_renderer, TRUE);
123 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), text_renderer,
"text", 1);
132 TRACE_CALL(__func__);
136 gchar *buf, *ptr1, *ptr2;
138 store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo)));
139 gtk_list_store_clear(store);
144 gtk_list_store_append(store, &iter);
145 gtk_list_store_set(store, &iter, 0,
"", 1, empty_choice, -1);
146 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
150 if (text == NULL || text[0] ==
'\0')
153 buf = g_strdup(text);
155 while (ptr1 && *ptr1 !=
'\0') {
156 ptr2 = strchr(ptr1, CHAR_DELIMITOR);
160 gtk_list_store_append(store, &iter);
161 gtk_list_store_set(store, &iter, 0, ptr1, 1, ptr1, -1);
163 if (i == 0 || g_strcmp0(ptr1, def) == 0) {
164 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
177 TRACE_CALL(__func__);
180 GtkCellRenderer *renderer;
183 store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
185 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
187 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
188 gtk_widget_set_hexpand(combo, TRUE);
191 renderer = gtk_cell_renderer_pixbuf_new();
192 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, FALSE);
193 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer,
"icon-name", 2);
195 renderer = gtk_cell_renderer_text_new();
196 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
197 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), renderer,
"text", 1);
199 g_object_set(G_OBJECT(renderer),
"xpad", 5, NULL);
207 TRACE_CALL(__func__);
214 store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo)));
216 for (i = 0; key_value_list[i]; i += (use_icon ? 3 : 2)) {
217 gtk_list_store_append(store, &iter);
224 key_value_list[i + 1] && ((
char*)key_value_list[i + 1])[0] ?
225 g_dgettext(domain, key_value_list[i + 1]) :
"", -1);
227 gtk_list_store_set(store, &iter, 2, key_value_list[i + 2], -1);
229 if (i == 0 || g_strcmp0(key_value_list[i], def) == 0) {
230 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i / (use_icon ? 3 : 2));
239 TRACE_CALL(__func__);
241 g_snprintf(buf,
sizeof(buf),
"%i", def);
247 TRACE_CALL(__func__);
251 widget = gtk_label_new(NULL);
252 gtk_widget_show(widget);
253 gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
254 gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
255 str = g_markup_printf_escaped(
"<b>%s</b>", group);
256 gtk_label_set_markup(GTK_LABEL(widget), str);
258 gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 2);
260 widget = gtk_label_new(NULL);
261 gtk_widget_show(widget);
262 gtk_grid_attach(GTK_GRID(grid), widget, 0, row + 1, 1, 1);
268 TRACE_CALL(__func__);
273 if (GTK_IS_COMBO_BOX_TEXT(combo)) {
274 return gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo));
277 if (!gtk_combo_box_get_active_iter(combo, &iter))
280 model = gtk_combo_box_get_model(combo);
281 gtk_tree_model_get(model, &iter, 0, &s, -1);
286 #if !GTK_CHECK_VERSION(3, 22, 0) 289 TRACE_CALL(__func__);
292 GtkAllocation allocation;
294 widget = GTK_WIDGET(user_data);
295 if (gtk_widget_get_window(widget) == NULL) {
301 gdk_window_get_origin(gtk_widget_get_window(widget), &tx, &ty);
302 gtk_widget_get_allocation(widget, &allocation);
310 if (gtk_widget_get_has_window(widget) ||
311 g_strcmp0(gtk_widget_get_name(widget),
"GtkToggleToolButton") == 0) {
317 *y = ty + allocation.height - 1;
325 TRACE_CALL(__func__);
326 if (!path1 || path1[0] ==
'\0')
327 return g_strdup(path2);
328 if (path1[strlen(path1) - 1] ==
'/')
329 return g_strdup_printf(
"%s%s", path1, path2);
330 return g_strdup_printf(
"%s/%s", path1, path2);
335 TRACE_CALL(__func__);
336 gchar *str, *ptr, *ptr2;
338 str = g_strdup(server);
342 ptr = strchr(str,
'[');
345 ptr2 = strchr(ptr,
']');
349 defaultport = atoi(ptr2 + 1);
352 *host = g_strdup(ptr);
360 ptr = strchr(str,
':');
362 ptr2 = strchr(ptr + 1,
':');
365 defaultport = atoi(ptr);
381 TRACE_CALL(__func__);
385 GError *error = NULL;
389 display = gdk_display_get_name(gdk_display_get_default());
391 g_snprintf(buf,
sizeof(buf),
"xauth list %s", display);
392 ret = g_spawn_command_line_sync(buf, &out, NULL, NULL, &error);
394 if ((ptr = g_strrstr(out,
"MIT-MAGIC-COOKIE-1")) == NULL) {
395 *msg = g_strdup_printf(
"xauth returns %s", out);
401 *msg = g_strndup(ptr, 32);
405 *msg = g_strdup(error->message);
412 TRACE_CALL(__func__);
416 struct sockaddr_un addr;
419 display = g_strdup(disp);
420 ptr = g_strrstr(display,
":");
424 if (display[0] ==
'\0' || strcmp(display,
"unix") == 0) {
426 sock = socket(AF_UNIX, SOCK_STREAM, 0);
428 memset(&addr, 0,
sizeof(addr));
429 addr.sun_family = AF_UNIX;
430 snprintf(addr.sun_path,
sizeof(addr.sun_path), X_UNIX_SOCKET, port);
431 if (connect(sock, (
struct sockaddr *)&addr,
sizeof(addr)) == -1) {
446 TRACE_CALL(__func__);
447 #ifdef GDK_WINDOWING_X11 448 #if GTK_CHECK_VERSION(3, 10, 0) 449 g_return_val_if_fail(GDK_IS_SCREEN(screen), 0);
450 if (GDK_IS_X11_DISPLAY(gdk_screen_get_display(screen)))
451 return gdk_x11_screen_get_current_desktop(screen);
462 guint *current_desktop;
466 g_return_val_if_fail(GDK_IS_SCREEN(screen), 0);
468 root_win = gdk_screen_get_root_window(screen);
469 display = gdk_screen_get_display(screen);
471 gdk_error_trap_push();
472 result = XGetWindowProperty(GDK_DISPLAY_XDISPLAY(display), GDK_WINDOW_XID(root_win),
473 gdk_x11_get_xatom_by_name_for_display(display,
"_NET_CURRENT_DESKTOP"),
474 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems,
475 &bytes_after, (gpointer) & current_desktop);
476 err = gdk_error_trap_pop();
478 if (err != Success || result != Success)
481 if (type == XA_CARDINAL && format == 32 && nitems > 0)
482 ret = current_desktop[0];
484 XFree(current_desktop);
497 TRACE_CALL(__func__);
498 #ifdef GDK_WINDOWING_X11 499 #if GTK_CHECK_VERSION(3, 10, 0) 501 g_return_val_if_fail(GTK_IS_WINDOW(gtkwindow), 0);
502 g_return_val_if_fail(gtk_widget_get_realized(GTK_WIDGET(gtkwindow)), 0);
503 window = gtk_widget_get_window(GTK_WIDGET(gtkwindow));
504 if (GDK_IS_X11_DISPLAY(gdk_window_get_display(window)))
505 return gdk_x11_window_get_desktop(window);
519 g_return_val_if_fail(GTK_IS_WINDOW(gtkwindow), 0);
520 g_return_val_if_fail(gtk_widget_get_realized(GTK_WIDGET(gtkwindow)), 0);
522 window = gtk_widget_get_window(GTK_WIDGET(gtkwindow));
523 display = gdk_window_get_display(window);
525 gdk_error_trap_push();
526 result = XGetWindowProperty(GDK_DISPLAY_XDISPLAY(display), GDK_WINDOW_XID(window),
527 gdk_x11_get_xatom_by_name_for_display(display,
"_NET_WM_DESKTOP"),
528 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems,
529 &bytes_after, (gpointer) & workspace);
530 err = gdk_error_trap_pop();
532 if (err != Success || result != Success)
535 if (type == XA_CARDINAL && format == 32 && nitems > 0)
551 TRACE_CALL(__func__);
552 GdkKeymapKey *keys = NULL;
556 if (gdk_keymap_get_entries_for_keyval(keymap, keyval, &keys, &length)) {
557 keycode = keys[0].keycode;
566 TRACE_CALL(__func__);
567 g_return_val_if_fail(keycode > 0, FALSE);
568 #ifdef GDK_WINDOWING_X11 569 return gdk_x11_keymap_key_is_modifier(keymap, keycode);
578 TRACE_CALL(__func__);
580 gchar *ui_path = g_strconcat(REMMINA_RUNTIME_UIDIR, G_DIR_SEPARATOR_S, filename, NULL);
581 GtkBuilder *builder = gtk_builder_new();
582 gtk_builder_add_from_file(builder, ui_path, &err);
584 g_print(
"Error adding build from file. Error: %s", err->message);
595 TRACE_CALL(__func__);
596 g_object_ref(widget);
597 gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
598 gtk_container_add(container, widget);
599 g_object_unref(widget);
605 TRACE_CALL(__func__);
615 for (i = 0; new_str[i] !=
'\0'; i++) {
616 if (new_str[i] ==
'x') {
624 if (new_str[i] <
'0' || new_str[i] >
'9') {
635 if (width == 0 || height == 0)
639 *error = g_strdup(_(
"Please enter format 'widthxheight'."));
645 const gchar *notification_title,
const gchar *notification_message)
647 TRACE_CALL(__func__);
649 GNotification *notification = g_notification_new(notification_title);
650 g_notification_set_body(notification, notification_message);
651 #if GLIB_CHECK_VERSION(2, 42, 0) 652 g_notification_set_priority(notification, G_NOTIFICATION_PRIORITY_NORMAL);
654 g_application_send_notification(g_application_get_default(), notification_id, notification);
655 g_object_unref(notification);
661 TRACE_CALL(__func__);
664 g_return_val_if_fail(
string != NULL, NULL);
665 g_return_val_if_fail(search != NULL, NULL);
667 if (replacement == NULL)
670 arr = g_strsplit(
string, search, -1);
671 if (arr != NULL && arr[0] != NULL)
672 str = g_strjoinv(replacement, arr);
674 str = g_strdup(
string);
684 TRACE_CALL(__func__);
687 string = g_strdup(new_string);
695 if (resolution_string == NULL || resolution_string[0] == 0)
697 if (sscanf(resolution_string,
"%dx%d", &lw, &lh) != 2)
708 guint rtmajor, rtminor, rtmicro;
709 rtmajor = gtk_get_major_version();
710 if (rtmajor > major) {
712 }
else if (rtmajor == major) {
713 rtminor = gtk_get_minor_version();
714 if (rtminor > minor) {
716 }
else if (rtminor == minor) {
717 rtmicro = gtk_get_micro_version();
718 if (rtmicro >= micro) {
void remmina_public_create_group(GtkGrid *grid, const gchar *group, gint row, gint rows, gint cols)
void remmina_public_gtk_widget_reparent(GtkWidget *widget, GtkContainer *container)
GtkWidget * remmina_public_create_combo_entry(const gchar *text, const gchar *def, gboolean descending)
void remmina_public_send_notification(const gchar *notification_id, const gchar *notification_title, const gchar *notification_message)
guint remmina_public_get_window_workspace(GtkWindow *gtkwindow)
gchar * remmina_public_combo_get_active_text(GtkComboBox *combo)
gboolean remmina_public_resolution_validation_func(const gchar *new_str, gchar **error)
GtkBuilder * remmina_public_gtk_builder_new_from_file(gchar *filename)
int remmina_public_split_resolution_string(const char *resolution_string, int *w, int *h)
gchar * remmina_public_combine_path(const gchar *path1, const gchar *path2)
gchar * remmina_public_str_replace_in_place(gchar *string, const gchar *search, const gchar *replacement)
GtkWidget * remmina_public_create_combo_map(const gpointer *key_value_list, const gchar *def, gboolean use_icon, const gchar *domain)
guint remmina_public_get_current_workspace(GdkScreen *screen)
GtkWidget * remmina_public_create_combo_text_d(const gchar *text, const gchar *def, const gchar *empty_choice)
GtkWidget * remmina_public_create_combo(gboolean use_icon)
void remmina_public_popup_position(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
gchar * remmina_public_str_replace(const gchar *string, const gchar *search, const gchar *replacement)
gboolean remmina_gtk_check_version(guint major, guint minor, guint micro)
gint remmina_public_open_xdisplay(const gchar *disp)
guint16 remmina_public_get_keycode_for_keyval(GdkKeymap *keymap, guint keyval)
gboolean remmina_public_get_xauth_cookie(const gchar *display, gchar **msg)
gboolean remmina_public_get_modifier_for_keycode(GdkKeymap *keymap, guint16 keycode)
void remmina_public_get_server_port(const gchar *server, gint defaultport, gchar **host, gint *port)
void remmina_public_load_combo_text_d(GtkWidget *combo, const gchar *text, const gchar *def, const gchar *empty_choice)
GtkWidget * remmina_public_create_combo_mapint(const gpointer *key_value_list, gint def, gboolean use_icon, const gchar *domain)