Commit f4c1fed8 authored by llyzs's avatar llyzs Committed by llyzs

Move panel applet feature popup menu and service discovery to tray icon

git-svn-id: https://remmina.svn.sourceforge.net/svnroot/remmina/trunk@285 b6cfa94a-2857-405c-b0d6-536ef9fc39e1
parent edfafce6
......@@ -68,10 +68,14 @@ AC_ARG_ENABLE(avahi,
)
if test "x$avahi_support" != "xno"; then
PKG_CHECK_MODULES(AVAHI_UI,
avahi-ui >= 0.6.22, [
[
avahi-ui >= 0.6.22
avahi-client >= 0.6.22
], [
avahi_support="yes"
remmina_pkgs="$remmina_pkgs avahi-ui"
remmina_pkgs="$remmina_pkgs avahi-ui avahi-client"
AC_DEFINE([HAVE_LIBAVAHI_UI], [1], [Define to 1 if you have the 'avahi-ui' library (-lavahi-ui).])
AC_DEFINE([HAVE_LIBAVAHI_CLIENT], [1], [Define to 1 if you have the 'avahi-client' library (-lavahi-client).])
], avahi_support="no. libavahi-ui-dev required."
)
else
......
......@@ -38,7 +38,10 @@ remmina_SOURCES = remmina.c \
remminalog.h remminalog.c \
remminakeychooser.h remminakeychooser.c \
remminaexec.h remminaexec.c \
remminaicon.h remminaicon.c
remminaicon.h remminaicon.c \
remminaavahi.h remminaavahi.c \
remminaappletmenuitem.h remminaappletmenuitem.c \
remminaappletmenu.h remminaappletmenu.c
remmina_LDADD = @REMMINA_LIBS@ @LIBGCRYPT_LIBS@
......
......@@ -224,7 +224,7 @@ main (int argc, char* argv[])
remmina_widget_pool_init ();
remmina_sftp_plugin_register ();
remmina_ssh_plugin_register ();
remmina_icon_create ();
remmina_icon_init ();
g_set_application_name ("Remmina");
gtk_window_set_default_icon_name ("remmina");
......
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2010 Vic Lee
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <string.h>
#include "remminaappletmenuitem.h"
#include "remminaappletmenu.h"
G_DEFINE_TYPE (RemminaAppletMenu, remmina_applet_menu, GTK_TYPE_MENU)
struct _RemminaAppletMenuPriv
{
gboolean hide_count;
};
enum
{
LAUNCH_ITEM_SIGNAL,
EDIT_ITEM_SIGNAL,
LAST_SIGNAL
};
static guint remmina_applet_menu_signals[LAST_SIGNAL] = { 0 };
static void
remmina_applet_menu_destroy (RemminaAppletMenu *menu, gpointer data)
{
g_free (menu->priv);
}
static void
remmina_applet_menu_class_init (RemminaAppletMenuClass *klass)
{
remmina_applet_menu_signals[LAUNCH_ITEM_SIGNAL] =
g_signal_new ("launch-item",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (RemminaAppletMenuClass, launch_item),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
remmina_applet_menu_signals[EDIT_ITEM_SIGNAL] =
g_signal_new ("edit-item",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (RemminaAppletMenuClass, edit_item),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
}
static void
remmina_applet_menu_init (RemminaAppletMenu *menu)
{
menu->priv = g_new0 (RemminaAppletMenuPriv, 1);
g_signal_connect (G_OBJECT (menu), "destroy", G_CALLBACK (remmina_applet_menu_destroy), NULL);
}
static void
remmina_applet_menu_on_item_click (RemminaAppletMenuItem *menuitem, GdkEventButton *event, RemminaAppletMenu *menu)
{
if (event->button == 3)
{
g_signal_emit (G_OBJECT (menu), remmina_applet_menu_signals[EDIT_ITEM_SIGNAL], 0, menuitem);
}
else
{
g_signal_emit (G_OBJECT (menu), remmina_applet_menu_signals[LAUNCH_ITEM_SIGNAL], 0, menuitem);
}
}
static GtkWidget*
remmina_applet_menu_add_group (GtkWidget *menu, const gchar *group, gint position, RemminaAppletMenuItem *menuitem,
GtkWidget **groupmenuitem)
{
GtkWidget *widget;
GtkWidget *image;
GtkWidget *submenu;
widget = gtk_image_menu_item_new_with_label (group);
gtk_widget_show (widget);
g_object_set_data_full (G_OBJECT (widget), "group", g_strdup (group), g_free);
g_object_set_data (G_OBJECT (widget), "count", GINT_TO_POINTER (0));
if (groupmenuitem)
{
*groupmenuitem = widget;
}
if (position < 0)
{
gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget);
}
else
{
gtk_menu_shell_insert (GTK_MENU_SHELL (menu), widget, position);
}
image = gtk_image_new_from_icon_name ((menuitem->item_type == REMMINA_APPLET_MENU_ITEM_DISCOVERED ?
"folder-remote" : "folder"), GTK_ICON_SIZE_MENU);
gtk_widget_show (image);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget), image);
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (widget), TRUE);
submenu = gtk_menu_new ();
gtk_widget_show (submenu);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), submenu);
return submenu;
}
static void
remmina_applet_menu_increase_group_count (GtkWidget *widget)
{
gint cnt;
gchar *s;
cnt = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "count")) + 1;
g_object_set_data (G_OBJECT (widget), "count", GINT_TO_POINTER (cnt));
s = g_strdup_printf ("%s (%i)", (const gchar*)g_object_get_data (G_OBJECT (widget), "group"), cnt);
gtk_menu_item_set_label (GTK_MENU_ITEM (widget), s);
g_free (s);
}
void
remmina_applet_menu_register_item (RemminaAppletMenu *menu, RemminaAppletMenuItem *menuitem)
{
g_signal_connect (G_OBJECT (menuitem), "button-press-event",
G_CALLBACK (remmina_applet_menu_on_item_click), menu);
}
void
remmina_applet_menu_add_item (RemminaAppletMenu *menu, RemminaAppletMenuItem *menuitem)
{
GtkWidget *submenu;
GtkWidget *groupmenuitem;
GtkMenuItem *submenuitem;
gchar *s, *p1, *p2;
GList *childs, *child;
gint position;
gint cmp;
submenu = GTK_WIDGET (menu);
s = g_strdup (menuitem->group);
p1 = s;
p2 = p1 ? strchr (p1, '/') : NULL;
if (p2) *p2++ = '\0';
while (p1 && p1[0])
{
groupmenuitem = NULL;
childs = gtk_container_get_children (GTK_CONTAINER (submenu));
position = -1;
for (child = g_list_first (childs); child; child = g_list_next (child))
{
if (!GTK_IS_MENU_ITEM (child->data)) continue;
position++;
submenuitem = GTK_MENU_ITEM (child->data);
if (gtk_menu_item_get_submenu (submenuitem))
{
cmp = g_strcmp0 (p1, (gchar*)g_object_get_data (G_OBJECT (submenuitem), "group"));
if (cmp == 0)
{
/* Found existing group menu */
submenu = gtk_menu_item_get_submenu (submenuitem);
groupmenuitem = GTK_WIDGET (submenuitem);
break;
}
else if (cmp < 0)
{
submenu = remmina_applet_menu_add_group (submenu, p1, position, menuitem, &groupmenuitem);
break;
}
}
else
{
submenu = remmina_applet_menu_add_group (submenu, p1, position, menuitem, &groupmenuitem);
break;
}
}
if (!child)
{
submenu = remmina_applet_menu_add_group (submenu, p1, -1, menuitem, &groupmenuitem);
}
g_list_free (childs);
if (groupmenuitem && !menu->priv->hide_count)
{
remmina_applet_menu_increase_group_count (groupmenuitem);
}
p1 = p2;
p2 = p1 ? strchr (p1, '/') : NULL;
if (p2) *p2++ = '\0';
}
g_free (s);
childs = gtk_container_get_children (GTK_CONTAINER (submenu));
position = -1;
for (child = g_list_first (childs); child; child = g_list_next (child))
{
if (!GTK_IS_MENU_ITEM (child->data)) continue;
position++;
submenuitem = GTK_MENU_ITEM (child->data);
if (gtk_menu_item_get_submenu (submenuitem)) continue;
if (!REMMINA_IS_APPLET_MENU_ITEM (submenuitem)) continue;
cmp = g_strcmp0 (menuitem->name, REMMINA_APPLET_MENU_ITEM (submenuitem)->name);
if (cmp <= 0)
{
gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), GTK_WIDGET (menuitem), position);
break;
}
}
if (!child)
{
gtk_menu_shell_append (GTK_MENU_SHELL (submenu), GTK_WIDGET (menuitem));
}
remmina_applet_menu_register_item (menu, menuitem);
}
GtkWidget*
remmina_applet_menu_new (gboolean hide_count)
{
RemminaAppletMenu *menu;
GtkWidget *menuitem;
gchar dirname[256];
gchar filename[256];
GDir *dir;
const gchar *name;
menu = REMMINA_APPLET_MENU (g_object_new (REMMINA_TYPE_APPLET_MENU, NULL));
menu->priv->hide_count = hide_count;
g_snprintf (dirname, sizeof (dirname), "%s/.remmina", g_get_home_dir ());
dir = g_dir_open (dirname, 0, NULL);
if (dir != NULL)
{
/* Iterate all remote desktop profiles */
while ((name = g_dir_read_name (dir)) != NULL)
{
if (!g_str_has_suffix (name, ".remmina")) continue;
g_snprintf (filename, sizeof (filename), "%s/%s", dirname, name);
menuitem = remmina_applet_menu_item_new (REMMINA_APPLET_MENU_ITEM_FILE, filename);
remmina_applet_menu_add_item (menu, REMMINA_APPLET_MENU_ITEM (menuitem));
gtk_widget_show (menuitem);
}
g_dir_close (dir);
}
return GTK_WIDGET (menu);
}
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2010 Vic Lee
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __REMMINAAPPLETMENU_H__
#define __REMMINAAPPLETMENU_H__
G_BEGIN_DECLS
#define REMMINA_TYPE_APPLET_MENU (remmina_applet_menu_get_type ())
#define REMMINA_APPLET_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), REMMINA_TYPE_APPLET_MENU, RemminaAppletMenu))
#define REMMINA_APPLET_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), REMMINA_TYPE_APPLET_MENU, RemminaAppletMenuClass))
#define REMMINA_IS_APPLET_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), REMMINA_TYPE_APPLET_MENU))
#define REMMINA_IS_APPLET_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), REMMINA_TYPE_APPLET_MENU))
#define REMMINA_APPLET_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), REMMINA_TYPE_APPLET_MENU, RemminaAppletMenuClass))
typedef enum
{
REMMINA_APPLET_MENU_NEW_CONNECTION_NONE,
REMMINA_APPLET_MENU_NEW_CONNECTION_TOP,
REMMINA_APPLET_MENU_NEW_CONNECTION_BOTTOM
} RemminaAppletMenuNewConnectionType;
typedef struct _RemminaAppletMenuPriv RemminaAppletMenuPriv;
typedef struct _RemminaAppletMenu
{
GtkMenu menu;
RemminaAppletMenuPriv *priv;
} RemminaAppletMenu;
typedef struct _RemminaAppletMenuClass
{
GtkMenuClass parent_class;
void (* launch_item) (RemminaAppletMenu *menu);
void (* edit_item) (RemminaAppletMenu *menu);
} RemminaAppletMenuClass;
GType remmina_applet_menu_get_type (void) G_GNUC_CONST;
void remmina_applet_menu_register_item (RemminaAppletMenu *menu, RemminaAppletMenuItem *menuitem);
void remmina_applet_menu_add_item (RemminaAppletMenu *menu, RemminaAppletMenuItem *menuitem);
GtkWidget* remmina_applet_menu_new (gboolean hide_count);
G_END_DECLS
#endif /* __REMMINAAPPLETMENU_H__ */
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2010 Vic Lee
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <string.h>
#include <stdarg.h>
#include "remminaappletmenuitem.h"
G_DEFINE_TYPE (RemminaAppletMenuItem, remmina_applet_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
#define IS_EMPTY(s) ((!s)||(s[0]==0))
static void
remmina_applet_menu_item_destroy (RemminaAppletMenuItem *item, gpointer data)
{
g_free (item->filename);
g_free (item->name);
g_free (item->group);
g_free (item->protocol);
g_free (item->server);
}
static void
remmina_applet_menu_item_class_init (RemminaAppletMenuItemClass *klass)
{
}
static void
remmina_applet_menu_item_init (RemminaAppletMenuItem *item)
{
item->filename = NULL;
item->name = NULL;
item->group = NULL;
item->protocol = NULL;
item->server = NULL;
item->ssh_enabled = FALSE;
g_signal_connect (G_OBJECT (item), "destroy", G_CALLBACK (remmina_applet_menu_item_destroy), NULL);
}
GtkWidget*
remmina_applet_menu_item_new (RemminaAppletMenuItemType item_type, ...)
{
va_list ap;
RemminaAppletMenuItem *item;
GKeyFile *gkeyfile;
GtkWidget *widget;
const gchar *iconname;
va_start(ap, item_type);
item = REMMINA_APPLET_MENU_ITEM (g_object_new (REMMINA_TYPE_APPLET_MENU_ITEM, NULL));
item->item_type = item_type;
switch (item_type)
{
case REMMINA_APPLET_MENU_ITEM_FILE:
item->filename = g_strdup (va_arg(ap, const gchar *));
/* Load the file */
gkeyfile = g_key_file_new ();
if (!g_key_file_load_from_file (gkeyfile, item->filename, G_KEY_FILE_NONE, NULL)) return NULL;
item->name = g_key_file_get_string (gkeyfile, "remmina", "name", NULL);
item->group = g_key_file_get_string (gkeyfile, "remmina", "group", NULL);
item->protocol = g_key_file_get_string (gkeyfile, "remmina", "protocol", NULL);
item->server = g_key_file_get_string (gkeyfile, "remmina", "server", NULL);
item->ssh_enabled = g_key_file_get_boolean (gkeyfile, "remmina", "ssh_enabled", NULL);
g_key_file_free (gkeyfile);
break;
case REMMINA_APPLET_MENU_ITEM_DISCOVERED:
item->name = g_strdup (va_arg(ap, const gchar *));
item->group = g_strdup (_("Discovered"));
item->protocol = g_strdup ("VNC");
break;
case REMMINA_APPLET_MENU_ITEM_NEW:
item->name = g_strdup (_("New Connection"));
break;
}
va_end(ap);
/* Create the label */
widget = gtk_label_new (item->name);
gtk_widget_show (widget);
gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
gtk_container_add (GTK_CONTAINER (item), widget);
/* Create the image */
if (item_type == REMMINA_APPLET_MENU_ITEM_FILE || item_type == REMMINA_APPLET_MENU_ITEM_DISCOVERED)
{
if (g_strcmp0 (item->protocol, "SFTP") == 0)
{
iconname = "remmina-sftp";
}
else if (g_strcmp0 (item->protocol, "SSH") == 0)
{
iconname = "utilities-terminal";
}
else if (g_strcmp0 (item->protocol, "RDP") == 0)
{
iconname = (item->ssh_enabled ? "remmina-rdp-ssh" : "remmina-rdp");
}
else if (strncmp (item->protocol, "VNC", 3) == 0)
{
iconname = (item->ssh_enabled ? "remmina-vnc-ssh" : "remmina-vnc");
}
else if (g_strcmp0 (item->protocol, "XDMCP") == 0)
{
iconname = (item->ssh_enabled ? "remmina-xdmcp-ssh" : "remmina-xdmcp");
}
else if (g_strcmp0 (item->protocol, "NX") == 0)
{
iconname = "remmina-nx";
}
else
{
iconname = "remmina";
}
widget = gtk_image_new_from_icon_name (iconname, GTK_ICON_SIZE_MENU);
}
else
{
widget = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU);
}
gtk_widget_show (widget);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), widget);
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
if (item->server)
{
gtk_widget_set_tooltip_text (GTK_WIDGET (item), item->server);
}
return GTK_WIDGET (item);
}
gint
remmina_applet_menu_item_compare (gconstpointer a, gconstpointer b, gpointer user_data)
{
RemminaAppletMenuItem *itema, *itemb;
gint cmp;
/* Passed in parameters are pointers to pointers */
itema = REMMINA_APPLET_MENU_ITEM (*((void**)a));
itemb = REMMINA_APPLET_MENU_ITEM (*((void**)b));
/* Put ungrouped items to the last */
if (IS_EMPTY (itema->group) && !IS_EMPTY (itemb->group)) return 1;
if (!IS_EMPTY (itema->group) && IS_EMPTY (itemb->group)) return -1;
/* Put discovered items the last group */
if (itema->item_type == REMMINA_APPLET_MENU_ITEM_DISCOVERED &&
itemb->item_type != REMMINA_APPLET_MENU_ITEM_DISCOVERED) return 1;
if (itema->item_type != REMMINA_APPLET_MENU_ITEM_DISCOVERED &&
itemb->item_type == REMMINA_APPLET_MENU_ITEM_DISCOVERED) return -1;
if (itema->item_type != REMMINA_APPLET_MENU_ITEM_DISCOVERED && !IS_EMPTY (itema->group))
{
cmp = g_strcmp0 (itema->group, itemb->group);
if (cmp != 0) return cmp;
}
return g_strcmp0 (itema->name, itemb->name);
}
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2010 Vic Lee
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __REMMINAAPPLETMENUITEM_H__
#define __REMMINAAPPLETMENUITEM_H__
G_BEGIN_DECLS
#define REMMINA_TYPE_APPLET_MENU_ITEM (remmina_applet_menu_item_get_type ())
#define REMMINA_APPLET_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), REMMINA_TYPE_APPLET_MENU_ITEM, RemminaAppletMenuItem))
#define REMMINA_APPLET_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), REMMINA_TYPE_APPLET_MENU_ITEM, RemminaAppletMenuItemClass))
#define REMMINA_IS_APPLET_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), REMMINA_TYPE_APPLET_MENU_ITEM))
#define REMMINA_IS_APPLET_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), REMMINA_TYPE_APPLET_MENU_ITEM))
#define REMMINA_APPLET_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), REMMINA_TYPE_APPLET_MENU_ITEM, RemminaAppletMenuItemClass))
typedef enum
{
REMMINA_APPLET_MENU_ITEM_FILE,
REMMINA_APPLET_MENU_ITEM_NEW,
REMMINA_APPLET_MENU_ITEM_DISCOVERED
} RemminaAppletMenuItemType;
typedef struct _RemminaAppletMenuItem
{
GtkImageMenuItem image_menu_item;
RemminaAppletMenuItemType item_type;
gchar *filename;
gchar *name;
gchar *group;
gchar *protocol;
gchar *server;
gboolean ssh_enabled;
} RemminaAppletMenuItem;
typedef struct _RemminaAppletMenuItemClass
{
GtkImageMenuItemClass parent_class;
} RemminaAppletMenuItemClass;
GType remmina_applet_menu_item_get_type (void) G_GNUC_CONST;
GtkWidget* remmina_applet_menu_item_new (RemminaAppletMenuItemType item_type, ...);
gint remmina_applet_menu_item_compare (gconstpointer a, gconstpointer b, gpointer user_data);
G_END_DECLS
#endif /* __REMMINAAPPLETMENUITEM_H__ */
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2010 Vic Lee
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <gtk/gtk.h>
#include "config.h"
#include "remminaavahi.h"
#ifdef HAVE_LIBAVAHI_CLIENT
#include <avahi-client/client.h>
#include <avahi-client/lookup.h>
#include <avahi-common/simple-watch.h>
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
struct _RemminaAvahiPriv
{
AvahiSimplePoll *simple_poll;
AvahiClient *client;
AvahiServiceBrowser *sb;
guint iterate_handler;
gboolean has_event;
};
static void
remmina_avahi_resolve_callback (
AvahiServiceResolver *r,
AVAHI_GCC_UNUSED AvahiIfIndex interface,
AVAHI_GCC_UNUSED AvahiProtocol protocol,
AvahiResolverEvent event,
const char *name,
const char *type,
const char *domain,
const char *host_name,
const AvahiAddress *address,
uint16_t port,
AvahiStringList *txt,
AvahiLookupResultFlags flags,
AVAHI_GCC_UNUSED void* userdata)
{
RemminaAvahi *ga = (RemminaAvahi*) userdata;
gchar *key, *value;
assert (r);
ga->priv->has_event = TRUE;
switch (event)
{
case AVAHI_RESOLVER_FAILURE:
g_print ("(remmina-applet avahi-resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
name, type, domain, avahi_strerror (avahi_client_errno (avahi_service_resolver_get_client (r))));
break;
case AVAHI_RESOLVER_FOUND:
key = g_strdup_printf ("%s,%s,%s", name, type, domain);
if (g_hash_table_lookup (ga->discovered_services, key))
{
g_free (key);
break;
}
value = g_strdup_printf ("[%s]:%i", host_name, port);
g_hash_table_insert (ga->discovered_services, key, value);
/* key and value will be freed with g_free when the has table is freed */
g_print ("(remmina-applet avahi-resolver) Added service '%s'\n", value);
break;
}
avahi_service_resolver_free (r);
}
static void
remmina_avahi_browse_callback (
AvahiServiceBrowser *b,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiBrowserEvent event,