From 02ff678b9ec7f36c9c18fa2c0e6b1f388d0c106e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 9 Oct 2007 14:12:49 -0400 Subject: properly handle local name collisions, which is somewhat necessary if you want to do a good screenshot of mango lassi in action when you are on the road with only a single laptop screen available. ;-) --- lassi-avahi.c | 88 ++++++++++------- lassi-server.c | 308 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 209 insertions(+), 187 deletions(-) diff --git a/lassi-avahi.c b/lassi-avahi.c index a247070..258c199 100644 --- a/lassi-avahi.c +++ b/lassi-avahi.c @@ -23,14 +23,14 @@ static void resolve_cb( AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata) { - + LassiAvahiInfo *i = userdata; - + g_assert(r); g_assert(i); - + /* Called whenever a service has been resolved successfully or timed out */ - + switch (event) { case AVAHI_RESOLVER_FOUND: { char a[AVAHI_ADDRESS_STR_MAX], *t; @@ -45,9 +45,9 @@ static void resolve_cb( case AVAHI_RESOLVER_FAILURE: g_message("Failed to resolve service '%s' of type '%s' in domain '%s': %s", name, type, domain, avahi_strerror(avahi_client_errno(i->client))); break; - + } - + avahi_service_resolver_free(r); } @@ -63,7 +63,7 @@ static void browse_cb( void* userdata) { LassiAvahiInfo *i = userdata; - + g_assert(b); g_assert(i); @@ -73,11 +73,11 @@ static void browse_cb( if (!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN) && !lassi_server_is_connected(i->server, name) && lassi_server_is_known(i->server, name)) - + if (!(avahi_service_resolver_new(i->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_cb, i))) g_message("Failed to resolve service '%s': %s", name, avahi_strerror(avahi_client_errno(i->client))); break; - + case AVAHI_BROWSER_REMOVE: case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: @@ -95,36 +95,36 @@ static void create_service(LassiAvahiInfo *i); static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { LassiAvahiInfo *i = userdata; - + g_assert(g); g_assert(i); i->group = g; - + switch (state) { case AVAHI_ENTRY_GROUP_ESTABLISHED : g_message("Service '%s' successfully established.", i->service_name); break; - + case AVAHI_ENTRY_GROUP_COLLISION : { char *n; - + n = avahi_alternative_service_name(i->service_name); avahi_free(i->service_name); i->service_name = n; - + g_message("Service name collision, renaming service to '%s'", n); - + /* And recreate the services */ create_service(i); break; } - - case AVAHI_ENTRY_GROUP_FAILURE : + + case AVAHI_ENTRY_GROUP_FAILURE : g_message("Entry group failure: %s", avahi_strerror(avahi_client_errno(i->client))); gtk_main_quit(); break; - + case AVAHI_ENTRY_GROUP_UNCOMMITED: case AVAHI_ENTRY_GROUP_REGISTERING: ; @@ -144,13 +144,31 @@ static void create_service(LassiAvahiInfo *i) { if (avahi_entry_group_is_empty(i->group)) { int ret; - if (!i->service_name) - i->service_name = g_strdup(i->server->id); - - if ((ret = avahi_entry_group_add_service(i->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, i->service_name, LASSI_SERVICE_TYPE, NULL, NULL, i->server->port, NULL)) < 0) { - g_message("Failed to add service: %s", avahi_strerror(ret)); - gtk_main_quit(); - return; + for (;;) { + + if (!i->service_name) + i->service_name = g_strdup(i->server->id); + + if ((ret = avahi_entry_group_add_service(i->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, i->service_name, LASSI_SERVICE_TYPE, NULL, NULL, i->server->port, NULL)) < 0) { + + if (ret == AVAHI_ERR_COLLISION) { + char *n = avahi_alternative_service_name(i->service_name); + avahi_free(i->service_name); + i->service_name = n; + continue; + } + + g_message("Failed to add service: %s", avahi_strerror(ret)); + gtk_main_quit(); + return; + } + + break; + } + + if (strcmp(i->service_name, i->server->id)) { + g_free(i->server->id); + i->server->id = g_strdup(i->service_name); } if ((ret = avahi_entry_group_commit(i->group)) < 0) { @@ -171,27 +189,27 @@ static void client_cb(AvahiClient *client, AvahiClientState state, void *userdat if (!i->group) create_service(i); break; - + case AVAHI_CLIENT_FAILURE: g_message("Client failure: %s", avahi_strerror(avahi_client_errno(client))); gtk_main_quit(); break; - + case AVAHI_CLIENT_S_COLLISION: case AVAHI_CLIENT_S_REGISTERING: if (i->group) avahi_entry_group_reset(i->group); - + break; - + case AVAHI_CLIENT_CONNECTING: ; } } - + int lassi_avahi_init(LassiAvahiInfo *i, LassiServer *server) { int error; - + g_assert(i); g_assert(server); @@ -204,7 +222,7 @@ int lassi_avahi_init(LassiAvahiInfo *i, LassiServer *server) { g_message("avahi_glib_poll_new() failed."); goto fail; } - + if (!(i->client = avahi_client_new(avahi_glib_poll_get(i->poll), 0, client_cb, i, &error))) { g_message("avahi_client_new() failed: %s", avahi_strerror(error)); goto fail; @@ -214,7 +232,7 @@ int lassi_avahi_init(LassiAvahiInfo *i, LassiServer *server) { g_message("avahi_service_browser_new(): %s", avahi_strerror(avahi_client_errno(i->client))); goto fail; } - + return 0; fail: @@ -224,7 +242,7 @@ fail: void lassi_avahi_done(LassiAvahiInfo *i) { g_assert(i); - + if (i->client) avahi_client_free(i->client); @@ -232,6 +250,6 @@ void lassi_avahi_done(LassiAvahiInfo *i) { avahi_glib_poll_free(i->poll); g_free(i->service_name); - + memset(i, 0, sizeof(*i)); } diff --git a/lassi-server.c b/lassi-server.c index 2b0a25d..f160279 100644 --- a/lassi-server.c +++ b/lassi-server.c @@ -31,7 +31,7 @@ static void server_send_update_grab(LassiServer *ls, int y); static void server_broadcast(LassiServer *ls, DBusMessage *m, LassiConnection *except) { GList *i; - + g_assert(ls); g_assert(m); @@ -55,9 +55,9 @@ static void server_layout_changed(LassiServer *ls, int y) { g_assert(ls); g_debug("updating layout"); - + lassi_grab_enable_triggers(&ls->grab_info, !!ls->connections_left, !!ls->connections_right); - + if (ls->active_connection) { char *t; gboolean to_left = !!g_list_find(ls->connections_left, ls->active_connection); @@ -65,12 +65,12 @@ static void server_layout_changed(LassiServer *ls, int y) { t = g_strdup_printf("Mouse and keyboard are being redirected to %s, which is located to the %s of this screen.\n" "To redirect input back to this screen, press and release both shift keys simultaneously.", ls->active_connection->id, to_left ? "left" : "right"); - + if (to_left) lassi_osd_set_text(&ls->osd_info, t, "go-previous", NULL); else lassi_osd_set_text(&ls->osd_info, t, NULL, "go-next"); - + lassi_grab_start(&ls->grab_info, to_left); } else { @@ -96,13 +96,13 @@ static void server_set_order(LassiServer *ls, GList *order) { LassiConnection *lc; if (!(lc = g_hash_table_lookup(ls->connections_by_id, l->data))) { - + if (strcmp(ls->id, l->data)) continue; } - + g_assert(lc || on_left); - + if (!lc) on_left = FALSE; else if (on_left) @@ -116,7 +116,7 @@ static void server_set_order(LassiServer *ls, GList *order) { if (!lc->id) continue; - + if (g_list_find(ls->connections_left, lc)) continue; @@ -126,7 +126,7 @@ static void server_set_order(LassiServer *ls, GList *order) { ls->order = g_list_append(ls->order, lc->id); ls->connections_right = g_list_prepend(ls->connections_right, lc); } - + ls->connections_right = g_list_reverse(ls->connections_right); server_layout_changed(ls, -1); @@ -136,7 +136,7 @@ static void server_set_order(LassiServer *ls, GList *order) { static void server_dump(LassiServer *ls) { GList *l; int n = 0; - + g_assert(ls); g_debug("BEGIN Current connections:"); @@ -156,7 +156,7 @@ static void server_dump(LassiServer *ls) { continue; g_debug("%2i) %s %s %s", n++, ls->active_connection == lc ? "ACTIVE" : " ", lc->id, lc->address); } - + if (!ls->active_connection) g_debug("We're the active connection"); @@ -165,7 +165,7 @@ static void server_dump(LassiServer *ls) { static void connection_destroy(LassiConnection *lc) { g_assert(lc); - + dbus_connection_flush(lc->dbus_connection); dbus_connection_close(lc->dbus_connection); dbus_connection_unref(lc->dbus_connection); @@ -187,7 +187,7 @@ static void server_pick_active_connection(LassiServer *ls) { if (!lc->id) continue; - + if (strcmp(lc->id, id) > 0) { id = lc->id; pick = lc; @@ -195,7 +195,7 @@ static void server_pick_active_connection(LassiServer *ls) { } ls->active_connection = pick; - + server_send_update_grab(ls, -1); server_layout_changed(ls, -1); } @@ -232,7 +232,7 @@ static void server_send_update_order(LassiServer *ls, LassiConnection *except) { gint32 g; DBusMessageIter iter, sub; GList *l; - + g_assert(ls); n = dbus_message_new_signal("/", LASSI_INTERFACE, "UpdateOrder"); @@ -257,7 +257,7 @@ static void server_send_update_order(LassiServer *ls, LassiConnection *except) { b = dbus_message_iter_close_container(&iter, &sub); g_assert(b); - + server_broadcast(ls, n, except); dbus_message_unref(n); } @@ -265,7 +265,7 @@ static void server_send_update_order(LassiServer *ls, LassiConnection *except) { int lassi_server_change_grab(LassiServer *ls, gboolean to_left, int y) { LassiConnection *lc; GList *l; - + g_assert(ls); l = to_left ? ls->connections_left : ls->connections_right; @@ -285,7 +285,7 @@ int lassi_server_acquire_grab(LassiServer *ls) { g_assert(ls); ls->active_connection = NULL; - + server_send_update_grab(ls, -1); server_layout_changed(ls, -1); return 0; @@ -299,7 +299,7 @@ int lassi_server_motion_event(LassiServer *ls, int dx, int dy) { if (!ls->active_connection) return -1; - + n = dbus_message_new_signal("/", LASSI_INTERFACE, "MotionEvent"); g_assert(n); @@ -308,11 +308,11 @@ int lassi_server_motion_event(LassiServer *ls, int dx, int dy) { b = dbus_connection_send(ls->active_connection->dbus_connection, n, NULL); g_assert(b); - + dbus_message_unref(n); - + dbus_connection_flush(ls->active_connection->dbus_connection); - + return 0; } @@ -322,7 +322,7 @@ int lassi_server_button_event(LassiServer *ls, unsigned button, gboolean is_pres if (!ls->active_connection) return -1; - + n = dbus_message_new_signal("/", LASSI_INTERFACE, "ButtonEvent"); g_assert(n); @@ -331,11 +331,11 @@ int lassi_server_button_event(LassiServer *ls, unsigned button, gboolean is_pres b = dbus_connection_send(ls->active_connection->dbus_connection, n, NULL); g_assert(b); - + dbus_message_unref(n); dbus_connection_flush(ls->active_connection->dbus_connection); - + return 0; } @@ -345,7 +345,7 @@ int lassi_server_key_event(LassiServer *ls, unsigned key, gboolean is_press) { if (!ls->active_connection) return -1; - + n = dbus_message_new_signal("/", LASSI_INTERFACE, "KeyEvent"); g_assert(n); @@ -354,11 +354,11 @@ int lassi_server_key_event(LassiServer *ls, unsigned key, gboolean is_press) { b = dbus_connection_send(ls->active_connection->dbus_connection, n, NULL); g_assert(b); - + dbus_message_unref(n); dbus_connection_flush(ls->active_connection->dbus_connection); - + return 0; } @@ -366,7 +366,7 @@ static void show_welcome(LassiConnection *lc, gboolean connect) { gboolean to_left; LassiServer *ls; char *summary, *body; - + g_assert(lc); ls = lc->server; @@ -379,9 +379,9 @@ static void show_welcome(LassiConnection *lc, gboolean connect) { summary = g_strdup_printf("%s no longer shares input with this desktop", lc->id); body = g_strdup_printf("You're no longer sharing keyboard and mouse with %s which was located to the %s.", lc->id, to_left ? "left" : "right"); } - + lassi_tray_show_notification(&ls->tray_info, summary, body, to_left ? LASSI_TRAY_NOTIFICATION_LEFT : LASSI_TRAY_NOTIFICATION_RIGHT); - + g_free(summary); g_free(body); } @@ -397,18 +397,18 @@ static void connection_unlink(LassiConnection *lc, gboolean remove_from_order) { if (lc->id) { DBusMessage *n; dbus_bool_t b; - + /* Tell everyone */ n = dbus_message_new_signal("/", LASSI_INTERFACE, "NodeRemoved"); g_assert(n); - + b = dbus_message_append_args(n, DBUS_TYPE_STRING, &lc->id, DBUS_TYPE_STRING, &lc->address, DBUS_TYPE_BOOLEAN, &remove_from_order, DBUS_TYPE_INVALID); g_assert(b); - + server_broadcast(ls, n, NULL); dbus_message_unref(n); } @@ -418,11 +418,11 @@ static void connection_unlink(LassiConnection *lc, gboolean remove_from_order) { if (lc->id) { show_welcome(lc, FALSE); - + g_hash_table_remove(ls->connections_by_id, lc->id); ls->connections_left = g_list_remove(ls->connections_left, lc); ls->connections_right = g_list_remove(ls->connections_right, lc); - + if (ls->active_connection == lc) server_pick_active_connection(ls); @@ -437,10 +437,10 @@ static void connection_unlink(LassiConnection *lc, gboolean remove_from_order) { ls->primary_empty = TRUE; lassi_clipboard_clear(&lc->server->clipboard_info, TRUE); } - + if (remove_from_order) { GList *i = g_list_find_custom(ls->order, lc->id, (GCompareFunc) strcmp); - + if (i) ls->order = g_list_delete_link(ls->order, i); } @@ -451,23 +451,23 @@ static void connection_unlink(LassiConnection *lc, gboolean remove_from_order) { } lassi_tray_update(&ls->tray_info, ls->n_connections); - + connection_destroy(lc); } static void server_position_connection(LassiServer *ls, LassiConnection *lc) { GList *l; LassiConnection *last = NULL; - + g_assert(ls); g_assert(lc); g_assert(!g_list_find(ls->connections_left, lc)); g_assert(!g_list_find(ls->connections_right, lc)); - + for (l = ls->order; l; l = l->next) { LassiConnection *k; - + if (strcmp(l->data, lc->id) == 0) break; @@ -509,7 +509,7 @@ int lassi_server_acquire_clipboard(LassiServer *ls, gboolean primary, char**targ DBusMessage *n; gint32 g; gboolean b; - + g_assert(ls); g_assert(targets); @@ -520,7 +520,7 @@ int lassi_server_acquire_clipboard(LassiServer *ls, gboolean primary, char**targ ls->clipboard_empty = FALSE; ls->clipboard_connection = NULL; } - + n = dbus_message_new_signal("/", LASSI_INTERFACE, "AcquireClipboard"); g_assert(n); @@ -528,7 +528,7 @@ int lassi_server_acquire_clipboard(LassiServer *ls, gboolean primary, char**targ g = ++ ls->primary_generation; else g = ++ ls->clipboard_generation; - + b = dbus_message_append_args(n, DBUS_TYPE_INT32, &g, DBUS_TYPE_BOOLEAN, &primary, DBUS_TYPE_INVALID); g_assert(b); @@ -548,7 +548,7 @@ int lassi_server_acquire_clipboard(LassiServer *ls, gboolean primary, char**targ server_broadcast(ls, n, NULL); g_assert(b); - + dbus_message_unref(n); return 0; } @@ -557,7 +557,7 @@ int lassi_server_return_clipboard(LassiServer *ls, gboolean primary) { DBusMessage *n; guint32 g; gboolean b; - + g_assert(ls); if (primary) { @@ -567,7 +567,7 @@ int lassi_server_return_clipboard(LassiServer *ls, gboolean primary) { ls->primary_empty = TRUE; ls->primary_connection = NULL; - + } else { if (ls->clipboard_empty || ls->clipboard_connection != NULL) @@ -589,7 +589,7 @@ int lassi_server_return_clipboard(LassiServer *ls, gboolean primary) { g_assert(b); server_broadcast(ls, n, NULL); - + dbus_message_unref(n); return 0; } @@ -601,7 +601,7 @@ int lassi_server_get_clipboard(LassiServer *ls, gboolean primary, const char *t, int ret = -1; DBusMessageIter iter, sub; gboolean b; - + g_assert(ls); dbus_error_init(&e); @@ -612,7 +612,7 @@ int lassi_server_get_clipboard(LassiServer *ls, gboolean primary, const char *t, return -1; c = ls->primary_connection->dbus_connection; - + } else { if (ls->clipboard_empty || !ls->clipboard_connection) @@ -620,7 +620,7 @@ int lassi_server_get_clipboard(LassiServer *ls, gboolean primary, const char *t, c = ls->clipboard_connection->dbus_connection; } - + n = dbus_message_new_method_call(NULL, "/", LASSI_INTERFACE, "GetClipboard"); g_assert(n); @@ -647,9 +647,9 @@ int lassi_server_get_clipboard(LassiServer *ls, gboolean primary, const char *t, *p = g_memdup(*p, *l); ret = 0; - + finish: - + dbus_message_unref(n); if (reply) @@ -667,9 +667,9 @@ static int signal_hello(LassiConnection *lc, DBusMessage *m) { dbus_bool_t b; DBusMessage *n; gint32 active_generation, order_generation, clipboard_generation; - + dbus_error_init(&e); - + if (lc->id) { g_debug("Received duplicate HelloNode."); return -1; @@ -692,7 +692,7 @@ static int signal_hello(LassiConnection *lc, DBusMessage *m) { g_debug("Dropping looped back connection."); return -1; } - + if (g_hash_table_lookup(lc->server->connections_by_id, id)) { g_debug("Dropping duplicate connection."); return -1; @@ -712,10 +712,10 @@ static int signal_hello(LassiConnection *lc, DBusMessage *m) { /* Notify all old nodes of the new one */ n = dbus_message_new_signal("/", LASSI_INTERFACE, "NodeAdded"); g_assert(n); - + b = dbus_message_append_args(n, DBUS_TYPE_STRING, &id, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID); g_assert(b); - + server_broadcast(lc->server, n, lc); dbus_message_unref(n); @@ -726,16 +726,16 @@ static int signal_hello(LassiConnection *lc, DBusMessage *m) { if (k == lc || !k->id) continue; - + n = dbus_message_new_signal("/", LASSI_INTERFACE, "NodeAdded"); g_assert(n); - + b = dbus_message_append_args(n, DBUS_TYPE_STRING, &id, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID); g_assert(b); - + b = dbus_connection_send(lc->dbus_connection, n, NULL); g_assert(b); - + dbus_message_unref(n); } @@ -747,21 +747,21 @@ static int signal_hello(LassiConnection *lc, DBusMessage *m) { show_welcome(lc, TRUE); } else lc->delayed_welcome = TRUE; - + server_layout_changed(lc->server, -1); lassi_prefs_update(&lc->server->prefs_info); server_dump(lc->server); - + return 0; } static int signal_node_added(LassiConnection *lc, DBusMessage *m) { const char *id, *address; DBusError e; - + dbus_error_init(&e); - + if (!(dbus_message_get_args(m, &e, DBUS_TYPE_STRING, &id, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID))) { g_debug("Received invalid message: %s", e.message); dbus_error_free(&e); @@ -770,21 +770,21 @@ static int signal_node_added(LassiConnection *lc, DBusMessage *m) { if (strcmp(id, lc->server->id) == 0) return 0; - + if (g_hash_table_lookup(lc->server->connections_by_id, id)) return 0; if (!(lassi_server_connect(lc->server, address))) { DBusMessage *n; dbus_bool_t b; - + /* Failed to connnect to this client, tell everyone */ n = dbus_message_new_signal("/", LASSI_INTERFACE, "NodeRemoved"); g_assert(n); - + b = dbus_message_append_args(n, DBUS_TYPE_STRING, &id, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID); g_assert(b); - + server_broadcast(lc->server, n, NULL); dbus_message_unref(n); } @@ -817,16 +817,16 @@ static int signal_node_removed(LassiConnection *lc, DBusMessage *m) { server_disconnect_all(lc->server, TRUE); return 0; } - + if (remove_from_order) { GList *i = g_list_find_custom(ls->order, id, (GCompareFunc) strcmp); - + if (i) ls->order = g_list_delete_link(ls->order, i); } ls = lc->server; - + if ((k = g_hash_table_lookup(lc->server->connections_by_id, id))) connection_unlink(k, remove_from_order); @@ -841,7 +841,7 @@ static int signal_update_grab(LassiConnection *lc, DBusMessage *m) { LassiConnection *k = NULL; DBusError e; int y; - + dbus_error_init(&e); if (!(dbus_message_get_args( @@ -868,7 +868,7 @@ static int signal_update_grab(LassiConnection *lc, DBusMessage *m) { } current_id = lc->server->active_connection ? lc->server->active_connection->id : lc->server->id; - + if ((lc->server->active_generation > generation || (lc->server->active_generation == generation && strcmp(current_id, id) > 0))) { g_debug("Ignoring request for active connection"); return 0; @@ -876,15 +876,15 @@ static int signal_update_grab(LassiConnection *lc, DBusMessage *m) { lc->server->active_connection = k; lc->server->active_generation = generation; - + if (!k) g_debug("We're now the active server."); - else + else g_debug("Connection '%s' activated.", k->id); server_broadcast(lc->server, m, lc); server_layout_changed(lc->server, y); - + return 0; } @@ -895,7 +895,7 @@ static int signal_update_order(LassiConnection *lc, DBusMessage *m) { GList *new_order = NULL, *merged_order = NULL; int r = 0; int c = 0; - + dbus_error_init(&e); if (!(dbus_message_get_args( @@ -919,7 +919,7 @@ static int signal_update_order(LassiConnection *lc, DBusMessage *m) { g_debug("Ignoring request for layout"); return 0; } - + dbus_message_iter_recurse(&iter, &sub); while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { @@ -936,7 +936,7 @@ static int signal_update_order(LassiConnection *lc, DBusMessage *m) { r = -1; goto finish; } - + c = lassi_list_compare(lc->server->order, new_order); if (c == 0) { @@ -957,9 +957,9 @@ static int signal_update_order(LassiConnection *lc, DBusMessage *m) { } server_send_update_order(lc->server, lassi_list_compare(lc->server->order, new_order) ? NULL : lc); - + lc->server->order_generation = generation; - + finish: lassi_list_free(new_order); @@ -969,7 +969,7 @@ finish: lc->delayed_welcome = FALSE; show_welcome(lc, TRUE); } - + return r; } @@ -977,7 +977,7 @@ static int signal_key_event(LassiConnection *lc, DBusMessage *m) { DBusError e; guint32 key; gboolean is_press; - + dbus_error_init(&e); if (!(dbus_message_get_args(m, &e, DBUS_TYPE_UINT32, &key, DBUS_TYPE_BOOLEAN, &is_press, DBUS_TYPE_INVALID))) { @@ -988,14 +988,14 @@ static int signal_key_event(LassiConnection *lc, DBusMessage *m) { /* g_debug("got dbus key %i %i", key, !!is_press); */ lassi_grab_press_key(&lc->server->grab_info, key, is_press); - + return 0; } static int signal_motion_event(LassiConnection *lc, DBusMessage *m) { DBusError e; int dx, dy; - + dbus_error_init(&e); if (!(dbus_message_get_args(m, &e, DBUS_TYPE_INT32, &dx, DBUS_TYPE_INT32, &dy, DBUS_TYPE_INVALID))) { @@ -1006,7 +1006,7 @@ static int signal_motion_event(LassiConnection *lc, DBusMessage *m) { /* g_debug("got dbus motion %i %i", dx, dy); */ lassi_grab_move_pointer_relative(&lc->server->grab_info, dx, dy); - + return 0; } @@ -1014,7 +1014,7 @@ static int signal_button_event(LassiConnection *lc, DBusMessage *m) { DBusError e; guint32 button; gboolean is_press; - + dbus_error_init(&e); if (!(dbus_message_get_args(m, &e, DBUS_TYPE_UINT32, &button, DBUS_TYPE_BOOLEAN, &is_press, DBUS_TYPE_INVALID))) { @@ -1025,7 +1025,7 @@ static int signal_button_event(LassiConnection *lc, DBusMessage *m) { /* g_debug("got dbus button %i %i", button, !!is_press); */ lassi_grab_press_button(&lc->server->grab_info, button, is_press); - + return 0; } @@ -1036,7 +1036,7 @@ static int signal_acquire_clipboard(LassiConnection *lc, DBusMessage *m) { DBusMessageIter iter, sub; char **targets; unsigned alloc_targets, j; - + dbus_error_init(&e); if (!(dbus_message_get_args(m, &e, DBUS_TYPE_INT32, &g, DBUS_TYPE_BOOLEAN, &primary, DBUS_TYPE_INVALID))) { @@ -1051,7 +1051,7 @@ static int signal_acquire_clipboard(LassiConnection *lc, DBusMessage *m) { } /* FIXME, tie break missing */ - + dbus_message_iter_init(m, &iter); dbus_message_iter_next(&iter); dbus_message_iter_next(&iter); @@ -1065,11 +1065,11 @@ static int signal_acquire_clipboard(LassiConnection *lc, DBusMessage *m) { targets = g_new(char*, alloc_targets = 20); j = 0; - + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { const char *t; dbus_message_iter_get_basic(&sub, &t); - + if (j >= alloc_targets) { alloc_targets *= 2; targets = g_realloc(targets, sizeof(char*) * (alloc_targets+1)); @@ -1084,7 +1084,7 @@ static int signal_acquire_clipboard(LassiConnection *lc, DBusMessage *m) { } targets[j] = NULL; - + lassi_clipboard_set(&lc->server->clipboard_info, primary, targets); g_free(targets); @@ -1187,15 +1187,15 @@ static int method_get_clipboard(LassiConnection *lc, DBusMessage *m) { b = dbus_message_iter_close_container(&iter, &sub); g_assert(b); - + finish: g_assert(n); - + dbus_connection_send(lc->dbus_connection, n, NULL); dbus_message_unref(n); g_free(p); - + return 0; } @@ -1206,7 +1206,7 @@ DBusHandlerResult message_function(DBusConnection *c, DBusMessage *m, void *user g_assert(c); g_assert(m); g_assert(lc); - + dbus_error_init(&e); /* g_debug("[%s] interface=%s, path=%s, member=%s serial=%u", */ @@ -1218,71 +1218,71 @@ DBusHandlerResult message_function(DBusConnection *c, DBusMessage *m, void *user if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected")) goto fail; - + else if (dbus_message_is_signal(m, LASSI_INTERFACE, "Hello")) { if (signal_hello(lc, m) < 0) goto fail; - + } else if (lc->id) { if (dbus_message_is_signal(m, LASSI_INTERFACE, "NodeAdded")) { if (signal_node_added(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "NodeRemoved")) { if (signal_node_removed(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "UpdateGrab")) { - + if (signal_update_grab(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "UpdateOrder")) { - + if (signal_update_order(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "KeyEvent")) { - + if (signal_key_event(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "MotionEvent")) { - + if (signal_motion_event(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "ButtonEvent")) { - + if (signal_button_event(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "AcquireClipboard")) { - + if (signal_acquire_clipboard(lc, m) < 0) goto fail; - + } else if (dbus_message_is_signal(m, LASSI_INTERFACE, "ReturnClipboard")) { - + if (signal_return_clipboard(lc, m) < 0) goto fail; - + } else if (dbus_message_is_method_call(m, LASSI_INTERFACE, "GetClipboard")) { if (method_get_clipboard(lc, m) < 0) goto fail; - - } else + + } else return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - + } else return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - + return DBUS_HANDLER_RESULT_HANDLED; - + fail: dbus_error_free(&e); @@ -1298,7 +1298,7 @@ static LassiConnection* connection_add(LassiServer *ls, DBusConnection *c, gbool DBusMessage *m; gint32 ag, og, cg; int fd, one = 1; - + g_assert(ls); g_assert(c); @@ -1310,19 +1310,19 @@ static LassiConnection* connection_add(LassiServer *ls, DBusConnection *c, gbool lc->delayed_welcome = FALSE; ls->connections = g_list_prepend(ls->connections, lc); ls->n_connections++; - + dbus_connection_setup_with_g_main(c, NULL); - + b = dbus_connection_add_filter(c, message_function, lc, NULL); g_assert(b); - + m = dbus_message_new_signal("/", LASSI_INTERFACE, "Hello"); g_assert(m); - + ag = ls->active_generation; og = ls->order_generation; cg = ls->clipboard_generation; - + b = dbus_message_append_args( m, DBUS_TYPE_STRING, &ls->id, @@ -1339,10 +1339,10 @@ static LassiConnection* connection_add(LassiServer *ls, DBusConnection *c, gbool if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) g_warning("Failed to enable TCP_NODELAY"); - + b = dbus_connection_send(c, m, NULL); g_assert(b); - + dbus_message_unref(m); lassi_tray_update(&ls->tray_info, ls->n_connections); @@ -1357,18 +1357,18 @@ static void new_connection(DBusServer *s, DBusConnection *c, void *userdata) { if (ls->n_connections >= CONNECTIONS_MAX) return; - + dbus_connection_set_allow_anonymous(c, TRUE); - connection_add(ls, c, FALSE); + connection_add(ls, c, FALSE); } static int server_init(LassiServer *ls) { DBusError e; int r = -1; guint16 port; - + g_assert(ls); - + memset(ls, 0, sizeof(*ls)); dbus_error_init(&e); @@ -1379,7 +1379,7 @@ static int server_init(LassiServer *ls) { t = g_strdup_printf("tcp:port=%u,host=0.0.0.0", port); ls->dbus_server = dbus_server_listen(t, &e); g_free(t); - + if (ls->dbus_server) { ls->port = port; break; @@ -1399,13 +1399,19 @@ static int server_init(LassiServer *ls) { } g_debug("Listening on port %u", port); - + dbus_server_setup_with_g_main(ls->dbus_server, NULL); dbus_server_set_new_connection_function(ls->dbus_server, new_connection, ls, NULL); ls->connections_by_id = g_hash_table_new(g_str_hash, g_str_equal); ls->id = g_strdup_printf("%s's desktop on %s", g_get_user_name(), g_get_host_name()); + + if (lassi_avahi_init(&ls->avahi_info, ls) < 0) + goto finish; + + /* The initialization of Avahi might have changed ls->id! */ + ls->address = dbus_server_get_address(ls->dbus_server); ls->order = g_list_prepend(NULL, g_strdup(ls->id)); @@ -1414,21 +1420,19 @@ static int server_init(LassiServer *ls) { if (lassi_osd_init(&ls->osd_info) < 0) goto finish; - + if (lassi_clipboard_init(&ls->clipboard_info, ls) < 0) goto finish; - if (lassi_avahi_init(&ls->avahi_info, ls) < 0) - goto finish; if (lassi_tray_init(&ls->tray_info, ls) < 0) goto finish; if (lassi_prefs_init(&ls->prefs_info, ls) < 0) goto finish; - + r = 0; - + finish: dbus_error_free(&e); return r; @@ -1436,7 +1440,7 @@ finish: void lassi_server_disconnect(LassiServer *ls, const char *id, gboolean remove_from_order) { LassiConnection *lc; - + g_assert(ls); g_assert(id); @@ -1444,7 +1448,7 @@ void lassi_server_disconnect(LassiServer *ls, const char *id, gboolean remove_fr connection_unlink(lc, remove_from_order); else if (remove_from_order) { GList *i = g_list_find_custom(ls->order, id, (GCompareFunc) strcmp); - + if (i) ls->order = g_list_delete_link(ls->order, i); } @@ -1462,7 +1466,7 @@ static void server_disconnect_all(LassiServer *ls, gboolean clear_order) { } static void server_done(LassiServer *ls) { - + g_assert(ls); if (ls->dbus_server) { @@ -1479,15 +1483,15 @@ static void server_done(LassiServer *ls) { g_free(ls->address); lassi_list_free(ls->order); - + lassi_grab_done(&ls->grab_info); lassi_osd_done(&ls->osd_info); lassi_clipboard_done(&ls->clipboard_info); lassi_avahi_done(&ls->avahi_info); lassi_tray_done(&ls->tray_info); lassi_prefs_done(&ls->prefs_info); - - memset(ls, 0, sizeof(*ls)); + + memset(ls, 0, sizeof(*ls)); } gboolean lassi_server_is_connected(LassiServer *ls, const char *id) { @@ -1513,7 +1517,7 @@ LassiConnection* lassi_server_connect(LassiServer *ls, const char *a) { if (ls->n_connections >= CONNECTIONS_MAX) goto finish; - + if (!(c = dbus_connection_open_private(a, &e))) { g_warning("Failed to connect to client: %s", e.message); goto finish; @@ -1536,10 +1540,10 @@ int main(int argc, char *argv[]) { gtk_init(&argc, &argv); memset(&ls, 0, sizeof(ls)); - + if (server_init(&ls) < 0) goto fail; - + gtk_main(); fail: -- cgit