/***
  This file is part of avahi.

  avahi is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 2.1 of the
  License, or (at your option) any later version.

  avahi 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 Lesser General
  Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with avahi; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA.
***/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdarg.h>
#include <net/if.h>

#include <gtk/gtk.h>

#include <avahi-glib/glib-watch.h>
#include <avahi-client/client.h>
#include <avahi-client/lookup.h>
#include <avahi-common/error.h>
#include <avahi-common/address.h>
#include <avahi-common/domain.h>
#include <avahi-common/i18n.h>

#include "avahi-ui.h"

#if defined(HAVE_GDBM) || defined(HAVE_DBM)
#include "../avahi-utils/stdb.h"
#endif

/* todo: i18n, HIGify */

struct _AuiServiceDialogPrivate {
    AvahiGLibPoll *glib_poll;
    AvahiClient *client;
    AvahiServiceBrowser **browsers;
    AvahiServiceResolver *resolver;
    AvahiDomainBrowser *domain_browser;

    gchar **browse_service_types;
    gchar *service_type;
    gchar *domain;
    gchar *service_name;
    AvahiProtocol address_family;

    AvahiAddress address;
    gchar *host_name;
    AvahiStringList *txt_data;
    guint16 port;

    gboolean resolve_service, resolve_service_done;
    gboolean resolve_host_name, resolve_host_name_done;

    GtkWidget *domain_label;
    GtkWidget *domain_button;
    GtkWidget *service_tree_view;
    GtkWidget *service_progress_bar;

    GtkListStore *service_list_store, *domain_list_store;
    GHashTable *service_type_names;

    guint service_pulse_timeout;
    guint domain_pulse_timeout;
    guint start_idle;

    AvahiIfIndex common_interface;
    AvahiProtocol common_protocol;

    GtkWidget *domain_dialog;
    GtkWidget *domain_entry;
    GtkWidget *domain_tree_view;
    GtkWidget *domain_progress_bar;
    GtkWidget *domain_ok_button;

    gint forward_response_id;
};

enum {
    PROP_0,
    PROP_BROWSE_SERVICE_TYPES,
    PROP_DOMAIN,
    PROP_SERVICE_TYPE,
    PROP_SERVICE_NAME,
    PROP_ADDRESS,
    PROP_PORT,
    PROP_HOST_NAME,
    PROP_TXT_DATA,
    PROP_RESOLVE_SERVICE,
    PROP_RESOLVE_HOST_NAME,
    PROP_ADDRESS_FAMILY
};

enum {
    SERVICE_COLUMN_IFACE,
    SERVICE_COLUMN_PROTO,
    SERVICE_COLUMN_TYPE,
    SERVICE_COLUMN_NAME,
    SERVICE_COLUMN_PRETTY_IFACE,
    SERVICE_COLUMN_PRETTY_TYPE,
    N_SERVICE_COLUMNS
};

enum {
    DOMAIN_COLUMN_NAME,
    DOMAIN_COLUMN_REF,
    N_DOMAIN_COLUMNS
};

static void aui_service_dialog_finalize(GObject *object);
static void aui_service_dialog_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void aui_service_dialog_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);

static int get_default_response(GtkDialog *dlg) {
    gint ret = GTK_RESPONSE_NONE;

    if (gtk_window_get_default_widget(GTK_WINDOW(dlg)))
        /* Use the response of the default widget, if possible */
        ret = gtk_dialog_get_response_for_widget(dlg, gtk_window_get_default_widget(GTK_WINDOW(dlg)));

    if (ret == GTK_RESPONSE_NONE) {
        /* Fall back to finding the first positive response */
        GList *children, *t;
        gint bad = GTK_RESPONSE_NONE;

        t = children = gtk_container_get_children(GTK_CONTAINER(gtk_dialog_get_action_area(dlg)));

        while (t) {
            GtkWidget *child = t->data;

            ret = gtk_dialog_get_response_for_widget(dlg, child);

            if (ret == GTK_RESPONSE_ACCEPT ||
                ret == GTK_RESPONSE_OK ||
                ret == GTK_RESPONSE_YES ||
                ret == GTK_RESPONSE_APPLY)
                break;

            if (ret != GTK_RESPONSE_NONE && bad == GTK_RESPONSE_NONE)
                bad = ret;

            t = t->next;
        }

        g_list_free (children);

        /* Fall back to finding the first negative response */
        if (ret == GTK_RESPONSE_NONE)
            ret = bad;
    }

    return ret;
}

G_DEFINE_TYPE(AuiServiceDialog, aui_service_dialog, GTK_TYPE_DIALOG)

static void aui_service_dialog_class_init(AuiServiceDialogClass *klass) {
    GObjectClass *object_class;

    avahi_init_i18n();

    object_class = (GObjectClass*) klass;

    object_class->finalize = aui_service_dialog_finalize;
    object_class->set_property = aui_service_dialog_set_property;
    object_class->get_property = aui_service_dialog_get_property;

    g_object_class_install_property(
            object_class,
            PROP_BROWSE_SERVICE_TYPES,
            g_param_spec_pointer("browse_service_types", _("Browse Service Types"), _("A NULL terminated list of service types to browse for"),
                                G_PARAM_READABLE | G_PARAM_WRITABLE));
    g_object_class_install_property(
            object_class,
            PROP_DOMAIN,
            g_param_spec_string("domain", _("Domain"), _("The domain to browse in, or NULL for the default domain"),
                                NULL,
                                G_PARAM_READABLE | G_PARAM_WRITABLE));
    g_object_class_install_property(
            object_class,
            PROP_SERVICE_TYPE,
            g_param_spec_string("service_type", _("Service Type"), _("The service type of the selected service"),
                                NULL,
                                G_PARAM_READABLE | G_PARAM_WRITABLE));
    g_object_class_install_property(
            object_class,
            PROP_SERVICE_NAME,
            g_param_spec_string("service_name", _("Service Name"), _("The service name of the selected service"),
                                NULL,
                                G_PARAM_READABLE | G_PARAM_WRITABLE));
    g_object_class_install_property(
            object_class,
            PROP_ADDRESS,
            g_param_spec_pointer("address", _("Address"), _("The address of the resolved service"),
                                G_PARAM_READABLE));
    g_object_class_install_property(
            object_class,
            PROP_PORT,
            g_param_spec_uint("port", _("Port"), _("The IP port number of the resolved service"),
                             0, 0xFFFF, 0,
                             G_PARAM_READABLE));
    g_object_class_install_property(
            object_class,
            PROP_HOST_NAME,
            g_param_spec_string("host_name", _("Host Name"), _("The host name of the resolved service"),
                                NULL,
                                G_PARAM_READABLE));
    g_object_class_install_property(
            object_class,
            PROP_TXT_DATA,
            g_param_spec_pointer("txt_data", _("TXT Data"), _("The TXT data of the resolved service"),
                                G_PARAM_READABLE));
    g_object_class_install_property(
            object_class,
            PROP_RESOLVE_SERVICE,
            g_param_spec_boolean("resolve_service", _("Resolve Service"), _("Resolve the selected service automatically before returning"),
                                 TRUE,
                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
    g_object_class_install_property(
            object_class,
            PROP_RESOLVE_HOST_NAME,
            g_param_spec_boolean("resolve_host_name", _("Resolve Service Host Name"), _("Resolve the host name of the selected service automatically before returning"),
                                 TRUE,
                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
    g_object_class_install_property(
            object_class,
            PROP_ADDRESS_FAMILY,
            g_param_spec_int("address_family", _("Address family"), _("The address family for host name resolution"),
                             AVAHI_PROTO_UNSPEC, AVAHI_PROTO_INET6, AVAHI_PROTO_UNSPEC,
                             G_PARAM_READABLE | G_PARAM_WRITABLE));
}


GtkWidget *aui_service_dialog_new_valist(
        const gchar *title,
        GtkWindow *parent,
        const gchar *first_button_text,
        va_list varargs) {

    const gchar *button_text;
    gint dr;

    GtkWidget *w = (GtkWidget*)g_object_new(
                                      AUI_TYPE_SERVICE_DIALOG,
#if !GTK_CHECK_VERSION (2,21,8)
                                      "has-separator", FALSE,
#endif
                                      "title", title,
                                      NULL);

    if (parent)
        gtk_window_set_transient_for(GTK_WINDOW(w), parent);

    button_text = first_button_text;
    while (button_text) {
        gint response_id;

        response_id = va_arg(varargs, gint);
        gtk_dialog_add_button(GTK_DIALOG(w), button_text, response_id);
        button_text = va_arg(varargs, const gchar *);
    }

    gtk_dialog_set_response_sensitive(GTK_DIALOG(w), GTK_RESPONSE_ACCEPT, FALSE);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(w), GTK_RESPONSE_OK, FALSE);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(w), GTK_RESPONSE_YES, FALSE);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(w), GTK_RESPONSE_APPLY, FALSE);

    if ((dr = get_default_response(GTK_DIALOG(w))) != GTK_RESPONSE_NONE)
        gtk_dialog_set_default_response(GTK_DIALOG(w), dr);

    return w;
}

GtkWidget* aui_service_dialog_new(
        const gchar *title,
        GtkWindow *parent,
        const gchar *first_button_text,
        ...) {

    GtkWidget *w;

    va_list varargs;
    va_start(varargs, first_button_text);
    w = aui_service_dialog_new_valist(title, parent, first_button_text, varargs);
    va_end(varargs);

    return w;
}

static gboolean service_pulse_callback(gpointer data) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(data);

    gtk_progress_bar_pulse(GTK_PROGRESS_BAR(d->priv->service_progress_bar));
    return TRUE;
}

static gboolean domain_pulse_callback(gpointer data) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(data);

    gtk_progress_bar_pulse(GTK_PROGRESS_BAR(d->priv->domain_progress_bar));
    return TRUE;
}

static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(userdata);

    if (state == AVAHI_CLIENT_FAILURE) {
        GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                              GTK_DIALOG_DESTROY_WITH_PARENT,
                                              GTK_MESSAGE_ERROR,
                                              GTK_BUTTONS_CLOSE,
                                              _("Avahi client failure: %s"),
                                              avahi_strerror(avahi_client_errno(c)));
        gtk_dialog_run(GTK_DIALOG(m));
        gtk_widget_destroy(m);

        gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
    }
}

static void resolve_callback(
        AvahiServiceResolver *r G_GNUC_UNUSED,
        AvahiIfIndex interface G_GNUC_UNUSED,
        AvahiProtocol protocol G_GNUC_UNUSED,
        AvahiResolverEvent event,
        const char *name,
        const char *type,
        const char *domain,
        const char *host_name,
        const AvahiAddress *a,
        uint16_t port,
        AvahiStringList *txt,
        AvahiLookupResultFlags flags G_GNUC_UNUSED,
        void *userdata) {

    AuiServiceDialog *d = AUI_SERVICE_DIALOG(userdata);

    switch (event) {
        case AVAHI_RESOLVER_FOUND:

            d->priv->resolve_service_done = 1;

            g_free(d->priv->service_name);
            d->priv->service_name = g_strdup(name);

            g_free(d->priv->service_type);
            d->priv->service_type = g_strdup(type);

            g_free(d->priv->domain);
            d->priv->domain = g_strdup(domain);

            g_free(d->priv->host_name);
            d->priv->host_name = g_strdup(host_name);

            d->priv->port = port;

            avahi_string_list_free(d->priv->txt_data);
            d->priv->txt_data = avahi_string_list_copy(txt);

            if (a) {
                d->priv->resolve_host_name_done = 1;
                d->priv->address = *a;
            }

            gtk_dialog_response(GTK_DIALOG(d), d->priv->forward_response_id);

            break;

        case AVAHI_RESOLVER_FAILURE: {
            GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_MESSAGE_ERROR,
                                                  GTK_BUTTONS_CLOSE,
                                                  _("Avahi resolver failure: %s"),
                                                  avahi_strerror(avahi_client_errno(d->priv->client)));
            gtk_dialog_run(GTK_DIALOG(m));
            gtk_widget_destroy(m);

            gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
            break;
        }
    }
}


static void browse_callback(
        AvahiServiceBrowser *b G_GNUC_UNUSED,
        AvahiIfIndex interface,
        AvahiProtocol protocol,
        AvahiBrowserEvent event,
        const char *name,
        const char *type,
        const char *domain,
        AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
        void* userdata) {

    AuiServiceDialog *d = AUI_SERVICE_DIALOG(userdata);

    switch (event) {

        case AVAHI_BROWSER_NEW: {
            gchar *ifs;
            const gchar *pretty_type = NULL;
            char ifname[IFNAMSIZ];
            GtkTreeIter iter;
            GtkTreeSelection *selection;

            if (!(if_indextoname(interface, ifname)))
                g_snprintf(ifname, sizeof(ifname), "%i", interface);

            ifs = g_strdup_printf("%s %s", ifname, protocol == AVAHI_PROTO_INET ? "IPv4" : "IPv6");

            if (d->priv->service_type_names)
                pretty_type = g_hash_table_lookup (d->priv->service_type_names, type);

            if (!pretty_type) {
#if defined(HAVE_GDBM) || defined(HAVE_DBM)
                pretty_type = stdb_lookup(type);
#else
                pretty_type = type;
#endif
            }

            gtk_list_store_append(d->priv->service_list_store, &iter);

            gtk_list_store_set(d->priv->service_list_store, &iter,
                               SERVICE_COLUMN_IFACE, interface,
                               SERVICE_COLUMN_PROTO, protocol,
                               SERVICE_COLUMN_NAME, name,
                               SERVICE_COLUMN_TYPE, type,
                               SERVICE_COLUMN_PRETTY_IFACE, ifs,
                               SERVICE_COLUMN_PRETTY_TYPE, pretty_type,
                               -1);

            g_free(ifs);

            if (d->priv->common_protocol == AVAHI_PROTO_UNSPEC)
                d->priv->common_protocol = protocol;

            if (d->priv->common_interface == AVAHI_IF_UNSPEC)
                d->priv->common_interface = interface;

            if (d->priv->common_interface != interface || d->priv->common_protocol != protocol) {
                gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 0), TRUE);
                gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(d->priv->service_tree_view), TRUE);
            }

            selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(d->priv->service_tree_view));
            if (!gtk_tree_selection_get_selected(selection, NULL, NULL)) {

                if (!d->priv->service_type ||
                    !d->priv->service_name ||
                    (avahi_domain_equal(d->priv->service_type, type) && strcasecmp(d->priv->service_name, name) == 0)) {
                    GtkTreePath *path;

                    gtk_tree_selection_select_iter(selection, &iter);

                    path = gtk_tree_model_get_path(GTK_TREE_MODEL(d->priv->service_list_store), &iter);
                    gtk_tree_view_set_cursor(GTK_TREE_VIEW(d->priv->service_tree_view), path, NULL, FALSE);
                    gtk_tree_path_free(path);
                }

            }

            break;
        }

        case AVAHI_BROWSER_REMOVE: {
            GtkTreeIter iter;
            gboolean valid;

            valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(d->priv->service_list_store), &iter);
            while (valid) {
                gint _interface, _protocol;
                gchar *_name, *_type;
                gboolean found;

                gtk_tree_model_get(GTK_TREE_MODEL(d->priv->service_list_store), &iter,
                                   SERVICE_COLUMN_IFACE, &_interface,
                                   SERVICE_COLUMN_PROTO, &_protocol,
                                   SERVICE_COLUMN_NAME, &_name,
                                   SERVICE_COLUMN_TYPE, &_type,
                                   -1);

                found = _interface == interface && _protocol == protocol && strcasecmp(_name, name) == 0 && avahi_domain_equal(_type, type);
                g_free(_name);

                if (found) {
                    gtk_list_store_remove(d->priv->service_list_store, &iter);
                    break;
                }

                valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(d->priv->service_list_store), &iter);
            }

            break;
        }

        case AVAHI_BROWSER_FAILURE: {
            GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_MESSAGE_ERROR,
                                                  GTK_BUTTONS_CLOSE,
                                                  _("Browsing for service type %s in domain %s failed: %s"),
                                                  type, domain ? domain : _("n/a"),
                                                  avahi_strerror(avahi_client_errno(d->priv->client)));
            gtk_dialog_run(GTK_DIALOG(m));
            gtk_widget_destroy(m);

            /* Fall through */
        }

        case AVAHI_BROWSER_ALL_FOR_NOW:
            if (d->priv->service_pulse_timeout > 0) {
                g_source_remove(d->priv->service_pulse_timeout);
                d->priv->service_pulse_timeout = 0;
                gtk_widget_hide(d->priv->service_progress_bar);
            }
            break;

        case AVAHI_BROWSER_CACHE_EXHAUSTED:
            ;
    }
}

static void domain_make_default_selection(AuiServiceDialog *d, const gchar *name, GtkTreeIter *iter) {
    GtkTreeSelection *selection;

    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(d->priv->domain_tree_view));
    if (!gtk_tree_selection_get_selected(selection, NULL, NULL)) {

        if (avahi_domain_equal(gtk_entry_get_text(GTK_ENTRY(d->priv->domain_entry)), name)) {
            GtkTreePath *path;

            gtk_tree_selection_select_iter(selection, iter);

            path = gtk_tree_model_get_path(GTK_TREE_MODEL(d->priv->domain_list_store), iter);
            gtk_tree_view_set_cursor(GTK_TREE_VIEW(d->priv->domain_tree_view), path, NULL, FALSE);
            gtk_tree_path_free(path);
        }

    }
}

static void domain_browse_callback(
        AvahiDomainBrowser *b G_GNUC_UNUSED,
        AvahiIfIndex interface G_GNUC_UNUSED,
        AvahiProtocol protocol G_GNUC_UNUSED,
        AvahiBrowserEvent event,
        const char *name,
        AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
        void* userdata) {

    AuiServiceDialog *d = AUI_SERVICE_DIALOG(userdata);

    switch (event) {

        case AVAHI_BROWSER_NEW: {
            GtkTreeIter iter;
            gboolean found = FALSE, valid;
            gint ref;

            valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
            while (valid) {
                gchar *_name;

                gtk_tree_model_get(GTK_TREE_MODEL(d->priv->domain_list_store), &iter,
                                   DOMAIN_COLUMN_NAME, &_name,
                                   DOMAIN_COLUMN_REF, &ref,
                                   -1);

                found = avahi_domain_equal(_name, name);
                g_free(_name);

                if (found)
                    break;

                valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
            }

            if (found)
                gtk_list_store_set(d->priv->domain_list_store, &iter, DOMAIN_COLUMN_REF, ref + 1, -1);
            else {
                gtk_list_store_append(d->priv->domain_list_store, &iter);

                gtk_list_store_set(d->priv->domain_list_store, &iter,
                                   DOMAIN_COLUMN_NAME, name,
                                   DOMAIN_COLUMN_REF, 1,
                                   -1);
            }

            domain_make_default_selection(d, name, &iter);

            break;
        }

        case AVAHI_BROWSER_REMOVE: {
            gboolean valid;
            GtkTreeIter iter;

            valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
            while (valid) {
                gint ref;
                gchar *_name;
                gboolean found;

                gtk_tree_model_get(GTK_TREE_MODEL(d->priv->domain_list_store), &iter,
                                   DOMAIN_COLUMN_NAME, &_name,
                                   DOMAIN_COLUMN_REF, &ref,
                                   -1);

                found = avahi_domain_equal(_name, name);
                g_free(_name);

                if (found) {
                    if (ref <= 1)
                        gtk_list_store_remove(d->priv->service_list_store, &iter);
                    else
                        gtk_list_store_set(d->priv->domain_list_store, &iter, DOMAIN_COLUMN_REF, ref - 1, -1);
                    break;
                }

                valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
            }

            break;
        }


        case AVAHI_BROWSER_FAILURE: {
            GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_MESSAGE_ERROR,
                                                  GTK_BUTTONS_CLOSE,
                                                  _("Avahi domain browser failure: %s"),
                                                  avahi_strerror(avahi_client_errno(d->priv->client)));
            gtk_dialog_run(GTK_DIALOG(m));
            gtk_widget_destroy(m);

            /* Fall through */
        }

        case AVAHI_BROWSER_ALL_FOR_NOW:
            if (d->priv->domain_pulse_timeout > 0) {
                g_source_remove(d->priv->domain_pulse_timeout);
                d->priv->domain_pulse_timeout = 0;
                gtk_widget_hide(d->priv->domain_progress_bar);
            }
            break;

        case AVAHI_BROWSER_CACHE_EXHAUSTED:
            ;
    }
}

static const gchar *get_domain_name(AuiServiceDialog *d) {
    const gchar *domain;

    g_return_val_if_fail(d, NULL);
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);

    if (d->priv->domain)
        return d->priv->domain;

    if (!(domain = avahi_client_get_domain_name(d->priv->client))) {
        GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                              GTK_DIALOG_DESTROY_WITH_PARENT,
                                              GTK_MESSAGE_ERROR,
                                              GTK_BUTTONS_CLOSE,
                                              _("Failed to read Avahi domain: %s"),
                                              avahi_strerror(avahi_client_errno(d->priv->client)));
        gtk_dialog_run(GTK_DIALOG(m));
        gtk_widget_destroy(m);

        return NULL;
    }

    return domain;
}

static gboolean start_callback(gpointer data) {
    int error;
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(data);
    gchar **st;
    AvahiServiceBrowser **sb;
    unsigned i;
    const char *domain;

    d->priv->start_idle = 0;

    if (!d->priv->browse_service_types || !*d->priv->browse_service_types) {
        g_warning(_("Browse service type list is empty!"));
        return FALSE;
    }

    if (!d->priv->client) {
        if (!(d->priv->client = avahi_client_new(avahi_glib_poll_get(d->priv->glib_poll), 0, client_callback, d, &error))) {

            GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_MESSAGE_ERROR,
                                                  GTK_BUTTONS_CLOSE,
                                                  _("Failed to connect to Avahi server: %s"),
                                                  avahi_strerror(error));
            gtk_dialog_run(GTK_DIALOG(m));
            gtk_widget_destroy(m);

            gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
            return FALSE;
        }
    }

    if (!(domain = get_domain_name(d))) {
        gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
        return FALSE;
    }

    g_assert(domain);

    if (avahi_domain_equal(domain, "local."))
        gtk_label_set_markup(GTK_LABEL(d->priv->domain_label), _("Browsing for services on <b>local network</b>:"));
    else {
        gchar *t = g_strdup_printf(_("Browsing for services in domain <b>%s</b>:"), domain);
        gtk_label_set_markup(GTK_LABEL(d->priv->domain_label), t);
        g_free(t);
    }

    if (d->priv->browsers) {
        for (sb = d->priv->browsers; *sb; sb++)
            avahi_service_browser_free(*sb);

        g_free(d->priv->browsers);
        d->priv->browsers = NULL;
    }

    gtk_list_store_clear(GTK_LIST_STORE(d->priv->service_list_store));
    d->priv->common_interface = AVAHI_IF_UNSPEC;
    d->priv->common_protocol = AVAHI_PROTO_UNSPEC;

    gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 0), FALSE);
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(d->priv->service_tree_view), FALSE);
    gtk_widget_show(d->priv->service_progress_bar);

    if (d->priv->service_pulse_timeout <= 0)
        d->priv->service_pulse_timeout = g_timeout_add(100, service_pulse_callback, d);

    for (i = 0; d->priv->browse_service_types[i]; i++)
        ;
    g_assert(i > 0);

    d->priv->browsers = g_new0(AvahiServiceBrowser*, i+1);
    for (st = d->priv->browse_service_types, sb = d->priv->browsers; *st; st++, sb++) {

        if (!(*sb = avahi_service_browser_new(d->priv->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, *st, d->priv->domain, 0, browse_callback, d))) {
            GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_MESSAGE_ERROR,
                                                  GTK_BUTTONS_CLOSE,
                                                  _("Failed to create browser for %s: %s"),
                                                  *st,
                                                  avahi_strerror(avahi_client_errno(d->priv->client)));
            gtk_dialog_run(GTK_DIALOG(m));
            gtk_widget_destroy(m);

            gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
            return FALSE;

        }
    }

    return FALSE;
}

static void aui_service_dialog_finalize(GObject *object) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(object);

    if (d->priv->domain_pulse_timeout > 0)
        g_source_remove(d->priv->domain_pulse_timeout);

    if (d->priv->service_pulse_timeout > 0)
        g_source_remove(d->priv->service_pulse_timeout);

    if (d->priv->start_idle > 0)
        g_source_remove(d->priv->start_idle);

    g_free(d->priv->host_name);
    g_free(d->priv->domain);
    g_free(d->priv->service_name);

    avahi_string_list_free(d->priv->txt_data);

    g_strfreev(d->priv->browse_service_types);

    if (d->priv->domain_browser)
        avahi_domain_browser_free(d->priv->domain_browser);

    if (d->priv->resolver)
        avahi_service_resolver_free(d->priv->resolver);

    if (d->priv->browsers) {
        AvahiServiceBrowser **sb;

        for (sb = d->priv->browsers; *sb; sb++)
            avahi_service_browser_free(*sb);

        g_free(d->priv->browsers);
    }

    if (d->priv->client)
        avahi_client_free(d->priv->client);

    if (d->priv->glib_poll)
        avahi_glib_poll_free(d->priv->glib_poll);

    if (d->priv->service_list_store)
        g_object_unref(d->priv->service_list_store);
    if (d->priv->domain_list_store)
        g_object_unref(d->priv->domain_list_store);
    if (d->priv->service_type_names)
        g_hash_table_unref (d->priv->service_type_names);

    g_free(d->priv);
    d->priv = NULL;

    G_OBJECT_CLASS(aui_service_dialog_parent_class)->finalize(object);
}

static void service_row_activated_callback(GtkTreeView *tree_view G_GNUC_UNUSED, GtkTreePath *path G_GNUC_UNUSED, GtkTreeViewColumn *column G_GNUC_UNUSED, gpointer user_data) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(user_data);

    gtk_dialog_response(GTK_DIALOG(d), get_default_response(GTK_DIALOG(d)));
}

static void service_selection_changed_callback(GtkTreeSelection *selection, gpointer user_data) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(user_data);
    gboolean b;

    b = gtk_tree_selection_get_selected(selection, NULL, NULL);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(d), GTK_RESPONSE_ACCEPT, b);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(d), GTK_RESPONSE_OK, b);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(d), GTK_RESPONSE_YES, b);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(d), GTK_RESPONSE_APPLY, b);
}

static void response_callback(GtkDialog *dialog, gint response, gpointer user_data) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(user_data);

    if ((response == GTK_RESPONSE_ACCEPT ||
        response == GTK_RESPONSE_OK ||
        response == GTK_RESPONSE_YES ||
        response == GTK_RESPONSE_APPLY) &&
        ((d->priv->resolve_service && !d->priv->resolve_service_done) ||
         (d->priv->resolve_host_name && !d->priv->resolve_host_name_done))) {

        GtkTreeIter iter;
        gint interface, protocol;
        gchar *name, *type;
        GdkCursor *cursor;

        g_signal_stop_emission(dialog, g_signal_lookup("response", gtk_dialog_get_type()), 0);
        d->priv->forward_response_id = response;

        if (d->priv->resolver)
            return;

        g_return_if_fail(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(d->priv->service_tree_view)), NULL, &iter));

        gtk_tree_model_get(GTK_TREE_MODEL(d->priv->service_list_store), &iter,
                           SERVICE_COLUMN_IFACE, &interface,
                           SERVICE_COLUMN_PROTO, &protocol,
                           SERVICE_COLUMN_NAME, &name,
                           SERVICE_COLUMN_TYPE, &type, -1);

        g_return_if_fail(d->priv->client);

        gtk_widget_set_sensitive(GTK_WIDGET(dialog), FALSE);
        cursor = gdk_cursor_new(GDK_WATCH);
        gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(dialog)), cursor);
        g_object_unref(G_OBJECT(cursor));

        if (!(d->priv->resolver = avahi_service_resolver_new(
                      d->priv->client, interface, protocol, name, type, d->priv->domain,
                      d->priv->address_family, !d->priv->resolve_host_name ? AVAHI_LOOKUP_NO_ADDRESS : 0, resolve_callback, d))) {

            GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_MESSAGE_ERROR,
                                                  GTK_BUTTONS_CLOSE,
                                                  _("Failed to create resolver for %s of type %s in domain %s: %s"),
                                                  name, type, d->priv->domain,
                                                  avahi_strerror(avahi_client_errno(d->priv->client)));
            gtk_dialog_run(GTK_DIALOG(m));
            gtk_widget_destroy(m);

            gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
            return;
        }
    }
}

static gboolean is_valid_domain_suffix(const gchar *n) {
    gchar label[AVAHI_LABEL_MAX];

    if (!avahi_is_valid_domain_name(n))
        return FALSE;

    if (!avahi_unescape_label(&n, label, sizeof(label)))
        return FALSE;

    /* At least one label */

    return !!label[0];
}

static void domain_row_activated_callback(GtkTreeView *tree_view G_GNUC_UNUSED, GtkTreePath *path G_GNUC_UNUSED, GtkTreeViewColumn *column G_GNUC_UNUSED, gpointer user_data) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(user_data);

    if (is_valid_domain_suffix(gtk_entry_get_text(GTK_ENTRY(d->priv->domain_entry))))
        gtk_dialog_response(GTK_DIALOG(d->priv->domain_dialog), GTK_RESPONSE_ACCEPT);
}

static void domain_selection_changed_callback(GtkTreeSelection *selection G_GNUC_UNUSED, gpointer user_data) {
    GtkTreeIter iter;
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(user_data);
    gchar *name;

    g_return_if_fail(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(d->priv->domain_tree_view)), NULL, &iter));

    gtk_tree_model_get(GTK_TREE_MODEL(d->priv->domain_list_store), &iter,
                       DOMAIN_COLUMN_NAME, &name, -1);

    gtk_entry_set_text(GTK_ENTRY(d->priv->domain_entry), name);
}

static void domain_entry_changed_callback(GtkEditable *editable G_GNUC_UNUSED, gpointer user_data) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(user_data);

    gtk_widget_set_sensitive(d->priv->domain_ok_button, is_valid_domain_suffix(gtk_entry_get_text(GTK_ENTRY(d->priv->domain_entry))));
}

static void domain_button_clicked(GtkButton *button G_GNUC_UNUSED, gpointer user_data) {
    GtkWidget *vbox, *vbox2, *scrolled_window;
    GtkTreeSelection *selection;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(user_data);
    AuiServiceDialogPrivate *p = d->priv;
    const gchar *domain;
    GtkTreeIter iter;

    g_return_if_fail(!p->domain_dialog);
    g_return_if_fail(!p->domain_browser);

    if (!(domain = get_domain_name(d))) {
        gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
        return;
    }

    if (!(p->domain_browser = avahi_domain_browser_new(p->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, 0, domain_browse_callback, d))) {
        GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                              GTK_DIALOG_DESTROY_WITH_PARENT,
                                              GTK_MESSAGE_ERROR,
                                              GTK_BUTTONS_CLOSE,
                                              _("Failed to create domain browser: %s"),
                                              avahi_strerror(avahi_client_errno(p->client)));
        gtk_dialog_run(GTK_DIALOG(m));
        gtk_widget_destroy(m);

        gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
        return;
    }

    p->domain_dialog = gtk_dialog_new();
    gtk_container_set_border_width(GTK_CONTAINER(p->domain_dialog), 5);
    gtk_window_set_title(GTK_WINDOW(p->domain_dialog), _("Change domain"));
#if !GTK_CHECK_VERSION(2,21,8)
    gtk_dialog_set_has_separator(GTK_DIALOG(p->domain_dialog), FALSE);
#endif

    vbox = gtk_vbox_new(FALSE, 8);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(p->domain_dialog))), vbox, TRUE, TRUE, 0);

    p->domain_entry = gtk_entry_new();
    gtk_entry_set_max_length(GTK_ENTRY(p->domain_entry), AVAHI_DOMAIN_NAME_MAX);
    gtk_entry_set_text(GTK_ENTRY(p->domain_entry), domain);
    gtk_entry_set_activates_default(GTK_ENTRY(p->domain_entry), TRUE);
    g_signal_connect(p->domain_entry, "changed", G_CALLBACK(domain_entry_changed_callback), d);
    gtk_box_pack_start(GTK_BOX(vbox), p->domain_entry, FALSE, FALSE, 0);

    vbox2 = gtk_vbox_new(FALSE, 8);
    gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);

    scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
    gtk_box_pack_start(GTK_BOX(vbox2), scrolled_window, TRUE, TRUE, 0);

    p->domain_list_store = gtk_list_store_new(N_DOMAIN_COLUMNS, G_TYPE_STRING, G_TYPE_INT);

    p->domain_tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(p->domain_list_store));
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(p->domain_tree_view), FALSE);
    g_signal_connect(p->domain_tree_view, "row-activated", G_CALLBACK(domain_row_activated_callback), d);
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(p->domain_tree_view));
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
    g_signal_connect(selection, "changed", G_CALLBACK(domain_selection_changed_callback), d);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("Service Name"), renderer, "text", DOMAIN_COLUMN_NAME, NULL);
    gtk_tree_view_column_set_expand(column, TRUE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(p->domain_tree_view), column);

    gtk_tree_view_set_search_column(GTK_TREE_VIEW(p->domain_tree_view), DOMAIN_COLUMN_NAME);
    gtk_container_add(GTK_CONTAINER(scrolled_window), p->domain_tree_view);

    p->domain_progress_bar = gtk_progress_bar_new();
    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(p->domain_progress_bar), _("Browsing..."));
    gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(p->domain_progress_bar), 0.1);
    gtk_box_pack_end(GTK_BOX(vbox2), p->domain_progress_bar, FALSE, FALSE, 0);

    gtk_dialog_add_button(GTK_DIALOG(p->domain_dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
    p->domain_ok_button = GTK_WIDGET(gtk_dialog_add_button(GTK_DIALOG(p->domain_dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT));
    gtk_dialog_set_default_response(GTK_DIALOG(p->domain_dialog), GTK_RESPONSE_ACCEPT);
    gtk_widget_set_sensitive(p->domain_ok_button, is_valid_domain_suffix(gtk_entry_get_text(GTK_ENTRY(p->domain_entry))));

    gtk_widget_grab_default(p->domain_ok_button);
    gtk_widget_grab_focus(p->domain_entry);

    gtk_window_set_default_size(GTK_WINDOW(p->domain_dialog), 300, 300);

    gtk_widget_show_all(vbox);

    gtk_list_store_append(p->domain_list_store, &iter);
    gtk_list_store_set(p->domain_list_store, &iter, DOMAIN_COLUMN_NAME, "local", DOMAIN_COLUMN_REF, 1, -1);
    domain_make_default_selection(d, "local", &iter);

    p->domain_pulse_timeout = g_timeout_add(100, domain_pulse_callback, d);

    if (gtk_dialog_run(GTK_DIALOG(p->domain_dialog)) == GTK_RESPONSE_ACCEPT)
        aui_service_dialog_set_domain(d, gtk_entry_get_text(GTK_ENTRY(p->domain_entry)));

    gtk_widget_destroy(p->domain_dialog);
    p->domain_dialog = NULL;

    if (p->domain_pulse_timeout > 0) {
        g_source_remove(p->domain_pulse_timeout);
        p->domain_pulse_timeout = 0;
    }

    avahi_domain_browser_free(p->domain_browser);
    p->domain_browser = NULL;
}

static void aui_service_dialog_init(AuiServiceDialog *d) {
    GtkWidget *vbox, *vbox2, *scrolled_window;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;
    GtkTreeSelection *selection;
    AuiServiceDialogPrivate *p;

    p = d->priv = g_new(AuiServiceDialogPrivate, 1);

    p->host_name = NULL;
    p->domain = NULL;
    p->service_name = NULL;
    p->service_type = NULL;
    p->txt_data = NULL;
    p->browse_service_types = NULL;
    memset(&p->address, 0, sizeof(p->address));
    p->port = 0;
    p->resolve_host_name = p->resolve_service = TRUE;
    p->resolve_host_name_done = p->resolve_service_done = FALSE;
    p->address_family = AVAHI_PROTO_UNSPEC;

    p->glib_poll = NULL;
    p->client = NULL;
    p->browsers = NULL;
    p->resolver = NULL;
    p->domain_browser = NULL;

    p->service_pulse_timeout = 0;
    p->domain_pulse_timeout = 0;
    p->start_idle = 0;
    p->common_interface = AVAHI_IF_UNSPEC;
    p->common_protocol = AVAHI_PROTO_UNSPEC;

    p->domain_dialog = NULL;
    p->domain_entry = NULL;
    p->domain_tree_view = NULL;
    p->domain_progress_bar = NULL;
    p->domain_ok_button = NULL;

    p->forward_response_id = GTK_RESPONSE_NONE;

    p->service_list_store = p->domain_list_store = NULL;
    p->service_type_names = NULL;

    gtk_widget_push_composite_child();

    gtk_container_set_border_width(GTK_CONTAINER(d), 5);

    vbox = gtk_vbox_new(FALSE, 8);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(d))), vbox, TRUE, TRUE, 0);

    p->domain_label = gtk_label_new(_("Initializing..."));
    gtk_label_set_ellipsize(GTK_LABEL(p->domain_label), TRUE);
    gtk_misc_set_alignment(GTK_MISC(p->domain_label), 0, 0.5);
    gtk_box_pack_start(GTK_BOX(vbox), p->domain_label, FALSE, FALSE, 0);


    vbox2 = gtk_vbox_new(FALSE, 8);
    gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);

    scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
    gtk_box_pack_start(GTK_BOX(vbox2), scrolled_window, TRUE, TRUE, 0);

    p->service_list_store = gtk_list_store_new(N_SERVICE_COLUMNS, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

    p->service_tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(p->service_list_store));
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(p->service_tree_view), FALSE);
    g_signal_connect(p->service_tree_view, "row-activated", G_CALLBACK(service_row_activated_callback), d);
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(p->service_tree_view));
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
    g_signal_connect(selection, "changed", G_CALLBACK(service_selection_changed_callback), d);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("Location"), renderer, "text", SERVICE_COLUMN_PRETTY_IFACE, NULL);
    gtk_tree_view_column_set_visible(column, FALSE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(p->service_tree_view), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", SERVICE_COLUMN_NAME, NULL);
    gtk_tree_view_column_set_expand(column, TRUE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(p->service_tree_view), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("Type"), renderer, "text", SERVICE_COLUMN_PRETTY_TYPE, NULL);
    gtk_tree_view_column_set_visible(column, FALSE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(p->service_tree_view), column);

    gtk_tree_view_set_search_column(GTK_TREE_VIEW(p->service_tree_view), SERVICE_COLUMN_NAME);
    gtk_container_add(GTK_CONTAINER(scrolled_window), p->service_tree_view);

    p->service_progress_bar = gtk_progress_bar_new();
    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(p->service_progress_bar), _("Browsing..."));
    gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(p->service_progress_bar), 0.1);
    gtk_box_pack_end(GTK_BOX(vbox2), p->service_progress_bar, FALSE, FALSE, 0);

    p->domain_button = gtk_button_new_with_mnemonic(_("_Domain..."));
    gtk_button_set_image(GTK_BUTTON(p->domain_button), gtk_image_new_from_stock(GTK_STOCK_NETWORK, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(p->domain_button, "clicked", G_CALLBACK(domain_button_clicked), d);
    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(d))), p->domain_button, FALSE, TRUE, 0);
    gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(gtk_dialog_get_action_area(GTK_DIALOG(d))), p->domain_button, TRUE);
    gtk_widget_show(p->domain_button);

    gtk_dialog_set_default_response(GTK_DIALOG(d), GTK_RESPONSE_ACCEPT);

    gtk_widget_grab_focus(p->service_tree_view);

    gtk_window_set_default_size(GTK_WINDOW(d), 400, 300);

    gtk_widget_show_all(vbox);

    gtk_widget_pop_composite_child();

    p->glib_poll = avahi_glib_poll_new(NULL, G_PRIORITY_DEFAULT);

    p->service_pulse_timeout = g_timeout_add(100, service_pulse_callback, d);
    p->start_idle = g_idle_add(start_callback, d);

    g_signal_connect(d, "response", G_CALLBACK(response_callback), d);
}

static void restart_browsing(AuiServiceDialog *d) {
    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));

    if (d->priv->start_idle <= 0)
        d->priv->start_idle = g_idle_add(start_callback, d);
}

void aui_service_dialog_set_browse_service_types(AuiServiceDialog *d, const char *type, ...) {
    va_list ap;
    const char *t;
    unsigned u;

    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
    g_return_if_fail(type);

    g_strfreev(d->priv->browse_service_types);

    va_start(ap, type);
    for (u = 1; va_arg(ap, const char *); u++)
        ;
    va_end(ap);

    d->priv->browse_service_types = g_new0(gchar*, u+1);
    d->priv->browse_service_types[0] = g_strdup(type);

    va_start(ap, type);
    for (u = 1; (t = va_arg(ap, const char*)); u++)
        d->priv->browse_service_types[u] = g_strdup(t);
    va_end(ap);

    if (d->priv->browse_service_types[0] && d->priv->browse_service_types[1]) {
        /* Multiple service types, show type-column */
        gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 2), TRUE);
    }

    restart_browsing(d);
}

void aui_service_dialog_set_browse_service_typesv(AuiServiceDialog *d, const char *const*types) {

    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
    g_return_if_fail(types);
    g_return_if_fail(*types);

    g_strfreev(d->priv->browse_service_types);
    d->priv->browse_service_types = g_strdupv((char**) types);

    if (d->priv->browse_service_types[0] && d->priv->browse_service_types[1]) {
        /* Multiple service types, show type-column */
        gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 2), TRUE);
    }

    restart_browsing(d);
}

const gchar*const* aui_service_dialog_get_browse_service_types(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);

    return (const char* const*) d->priv->browse_service_types;
}

void aui_service_dialog_set_service_type_name(AuiServiceDialog *d, const gchar *type, const gchar *name) {
    GtkTreeModel *m = NULL;
    GtkTreeIter iter;

    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
    g_return_if_fail(NULL != type);
    g_return_if_fail(NULL != name);

    if (NULL == d->priv->service_type_names)
        d->priv->service_type_names = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);

    g_hash_table_insert(d->priv->service_type_names, g_strdup(type), g_strdup(name));

    if (d->priv->service_list_store)
        m = GTK_TREE_MODEL(d->priv->service_list_store);

    if (m && gtk_tree_model_get_iter_first(m, &iter)) {
        do {
            char *stored_type = NULL;

            gtk_tree_model_get(m, &iter, SERVICE_COLUMN_TYPE, &stored_type, -1);

            if (stored_type && g_str_equal(stored_type, type))
                gtk_list_store_set(d->priv->service_list_store, &iter, SERVICE_COLUMN_PRETTY_TYPE, name, -1);
        } while (gtk_tree_model_iter_next(m, &iter));
    }
}

void aui_service_dialog_set_domain(AuiServiceDialog *d, const char *domain) {
    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
    g_return_if_fail(!domain || is_valid_domain_suffix(domain));

    g_free(d->priv->domain);
    d->priv->domain = domain ? avahi_normalize_name_strdup(domain) : NULL;

    restart_browsing(d);
}

const char* aui_service_dialog_get_domain(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);

    return d->priv->domain;
}

void aui_service_dialog_set_service_name(AuiServiceDialog *d, const char *name) {
    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));

    g_free(d->priv->service_name);
    d->priv->service_name = g_strdup(name);
}

const char* aui_service_dialog_get_service_name(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);

    return d->priv->service_name;
}

void aui_service_dialog_set_service_type(AuiServiceDialog *d, const char*stype) {
    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));

    g_free(d->priv->service_type);
    d->priv->service_type = g_strdup(stype);
}

const char* aui_service_dialog_get_service_type(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);

    return d->priv->service_type;
}

const AvahiAddress* aui_service_dialog_get_address(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);
    g_return_val_if_fail(d->priv->resolve_service_done && d->priv->resolve_host_name_done, NULL);

    return &d->priv->address;
}

guint16 aui_service_dialog_get_port(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), 0);
    g_return_val_if_fail(d->priv->resolve_service_done, 0);

    return d->priv->port;
}

const char* aui_service_dialog_get_host_name(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);
    g_return_val_if_fail(d->priv->resolve_service_done, NULL);

    return d->priv->host_name;
}

const AvahiStringList *aui_service_dialog_get_txt_data(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);
    g_return_val_if_fail(d->priv->resolve_service_done, NULL);

    return d->priv->txt_data;
}

void aui_service_dialog_set_resolve_service(AuiServiceDialog *d, gboolean resolve) {
    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));

    d->priv->resolve_service = resolve;
}

gboolean aui_service_dialog_get_resolve_service(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), FALSE);

    return d->priv->resolve_service;
}

void aui_service_dialog_set_resolve_host_name(AuiServiceDialog *d, gboolean resolve) {
    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));

    d->priv->resolve_host_name = resolve;
}

gboolean aui_service_dialog_get_resolve_host_name(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), FALSE);

    return d->priv->resolve_host_name;
}

void aui_service_dialog_set_address_family(AuiServiceDialog *d, AvahiProtocol proto) {
    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
    g_return_if_fail(proto == AVAHI_PROTO_UNSPEC || proto == AVAHI_PROTO_INET || proto == AVAHI_PROTO_INET6);

    d->priv->address_family = proto;
}

AvahiProtocol aui_service_dialog_get_address_family(AuiServiceDialog *d) {
    g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), AVAHI_PROTO_UNSPEC);

    return d->priv->address_family;
}

static void aui_service_dialog_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(object);

    switch (prop_id) {
        case PROP_BROWSE_SERVICE_TYPES:
            aui_service_dialog_set_browse_service_typesv(d, g_value_get_pointer(value));
            break;

        case PROP_DOMAIN:
            aui_service_dialog_set_domain(d, g_value_get_string(value));
            break;

        case PROP_SERVICE_TYPE:
            aui_service_dialog_set_service_type(d, g_value_get_string(value));
            break;

        case PROP_SERVICE_NAME:
            aui_service_dialog_set_service_name(d, g_value_get_string(value));
            break;

        case PROP_RESOLVE_SERVICE:
            aui_service_dialog_set_resolve_service(d, g_value_get_boolean(value));
            break;

        case PROP_RESOLVE_HOST_NAME:
            aui_service_dialog_set_resolve_host_name(d, g_value_get_boolean(value));
            break;

        case PROP_ADDRESS_FAMILY:
            aui_service_dialog_set_address_family(d, g_value_get_int(value));
            break;

        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
            break;
    }
}

static void aui_service_dialog_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
    AuiServiceDialog *d = AUI_SERVICE_DIALOG(object);

    switch (prop_id) {
        case PROP_BROWSE_SERVICE_TYPES:
            g_value_set_pointer(value, (gpointer) aui_service_dialog_get_browse_service_types(d));
            break;

        case PROP_DOMAIN:
            g_value_set_string(value, aui_service_dialog_get_domain(d));
            break;

        case PROP_SERVICE_TYPE:
            g_value_set_string(value, aui_service_dialog_get_service_type(d));
            break;

        case PROP_SERVICE_NAME:
            g_value_set_string(value, aui_service_dialog_get_service_name(d));
            break;

        case PROP_ADDRESS:
            g_value_set_pointer(value, (gpointer) aui_service_dialog_get_address(d));
            break;

        case PROP_PORT:
            g_value_set_uint(value, aui_service_dialog_get_port(d));
            break;

        case PROP_HOST_NAME:
            g_value_set_string(value, aui_service_dialog_get_host_name(d));
            break;

        case PROP_TXT_DATA:
            g_value_set_pointer(value, (gpointer) aui_service_dialog_get_txt_data(d));
            break;

        case PROP_RESOLVE_SERVICE:
            g_value_set_boolean(value, aui_service_dialog_get_resolve_service(d));
            break;

        case PROP_RESOLVE_HOST_NAME:
            g_value_set_boolean(value, aui_service_dialog_get_resolve_host_name(d));
            break;

        case PROP_ADDRESS_FAMILY:
            g_value_set_int(value, aui_service_dialog_get_address_family(d));
            break;

        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
            break;
    }
}
