void lassi_server_send_update_order(LassiServer *ls, LassiConnection *except) { DBusMessage *n; dbus_bool_t b; gint32 g; DBusMessageIter iter, sub; GList *l; g_assert(ls); n = dbus_message_new_signal("/", LASSI_INTERFACE, "UpdateOrder"); g_assert(n); g = ++ ls->order_generation; b = dbus_message_append_args( n, DBUS_TYPE_INT32, &g, DBUS_TYPE_INVALID); g_assert(b); dbus_message_iter_init_append(n, &iter); b = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &sub); g_assert(b); for (l = ls->order; l; l = l->next) { b = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &l->data); g_assert(b); } b = dbus_message_iter_close_container(&iter, &sub); g_assert(b); server_broadcast(ls, n, except); dbus_message_unref(n); }
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_warning("Received invalid message: %s", e.message); dbus_error_free(&e); return -1; } 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); } return 0; }
static void server_send_update_grab(LassiServer *ls, int y) { char *active; DBusMessage *n; dbus_bool_t b; gint32 g; g_assert(ls); active = ls->active_connection ? ls->active_connection->id : ls->id; n = dbus_message_new_signal("/", LASSI_INTERFACE, "UpdateGrab"); g_assert(n); g = ++ ls->active_generation; b = dbus_message_append_args( n, DBUS_TYPE_INT32, &g, DBUS_TYPE_STRING, &active, DBUS_TYPE_INT32, &y, DBUS_TYPE_INVALID); g_assert(b); server_broadcast(ls, n, NULL); dbus_message_unref(n); }
static int signal_update_grab(LassiConnection *lc, DBusMessage *m) { const char*id, *current_id; gint32 generation; LassiConnection *k = NULL; DBusError e; int y; dbus_error_init(&e); if (!(dbus_message_get_args( m, &e, DBUS_TYPE_INT32, &generation, DBUS_TYPE_STRING, &id, DBUS_TYPE_INT32, &y, DBUS_TYPE_INVALID))) { g_warning("Received invalid message: %s", e.message); dbus_error_free(&e); return -1; } g_debug("received grab request for %s (%i vs %i)", id, lc->server->active_generation, generation); if (strcmp(id, lc->server->id) && !(k = g_hash_table_lookup(lc->server->connections_by_id, id))) { g_debug("Unknown connection"); return -1; } if (k == lc->server->active_connection) { g_debug("Connection already active"); return 0; } 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; } lc->server->active_connection = k; lc->server->active_generation = generation; if (!k) g_debug("We're now the active server."); else g_debug("Connection '%s' activated.", k->id); server_broadcast(lc->server, m, lc); server_layout_changed(lc->server, y); return 0; }
static void dali_outband_handler(UsbDaliError err, DaliFramePtr frame, unsigned int status, void *arg) { log_debug("Outband message received"); if (err == USBDALI_SUCCESS) { log_info("Broadcast (0x%02x 0x%02x) [0x%04x]", frame->address, frame->command, status); ServerPtr server = (ServerPtr) arg; if (server) { char rbuffer[DEFAULT_NET_FRAMESIZE]; rbuffer[0] = DEFAULT_NET_PROTOCOL; rbuffer[1] = NET_STATUS_BROADCAST; rbuffer[2] = frame->address; rbuffer[3] = frame->command; server_broadcast(server, rbuffer, sizeof(rbuffer)); } } }
int lassi_server_acquire_clipboard(LassiServer *ls, gboolean primary, char**targets) { DBusMessageIter iter, sub; DBusMessage *n; gint32 g; gboolean b; g_assert(ls); g_assert(targets); if (primary) { ls->primary_empty = FALSE; ls->primary_connection = NULL; } else { ls->clipboard_empty = FALSE; ls->clipboard_connection = NULL; } n = dbus_message_new_signal("/", LASSI_INTERFACE, "AcquireClipboard"); g_assert(n); if (primary) 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); dbus_message_iter_init_append(n, &iter); b = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &sub); g_assert(b); for (; *targets; targets++) { g_debug("Exporting target %s", *targets); b = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, targets); g_assert(b); } b = dbus_message_iter_close_container(&iter, &sub); g_assert(b); server_broadcast(ls, n, NULL); g_assert(b); dbus_message_unref(n); return 0; }
static int signal_node_removed(LassiConnection *lc, DBusMessage *m) { const char *id, *address; DBusError e; LassiConnection *k; gboolean remove_from_order; LassiServer *ls = lc->server; dbus_error_init(&e); if (!(dbus_message_get_args(m, &e, DBUS_TYPE_STRING, &id, DBUS_TYPE_STRING, &address, DBUS_TYPE_BOOLEAN, &remove_from_order, DBUS_TYPE_INVALID))) { g_warning("Received invalid message: %s", e.message); dbus_error_free(&e); return -1; } if (strcmp(id, lc->server->id) == 0) { g_debug("We've been kicked ourselves."); 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); } if ((k = g_hash_table_lookup(lc->server->connections_by_id, id))) connection_unlink(k, remove_from_order); server_broadcast(ls, m, lc == k ? NULL : lc); return 0; }
int lassi_server_return_clipboard(LassiServer *ls, gboolean primary) { DBusMessage *n; guint32 g; gboolean b; g_assert(ls); if (primary) { if (ls->primary_empty || ls->primary_connection != NULL) return -1; ls->primary_empty = TRUE; ls->primary_connection = NULL; } else { if (ls->clipboard_empty || ls->clipboard_connection != NULL) return -1; ls->clipboard_empty = TRUE; ls->clipboard_connection = NULL; } n = dbus_message_new_signal("/", LASSI_INTERFACE, "ReturnClipboard"); g_assert(n); if (primary) g = ++ ls->primary_generation; else g = ++ ls->clipboard_generation; b = dbus_message_append_args(n, DBUS_TYPE_UINT32, &g, DBUS_TYPE_BOOLEAN, &primary, DBUS_TYPE_INVALID); g_assert(b); server_broadcast(ls, n, NULL); dbus_message_unref(n); return 0; }
static int signal_hello(LassiConnection *lc, DBusMessage *m) { const char *id, *address; DBusError e; GList *i; 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; } if (!(dbus_message_get_args( m, &e, DBUS_TYPE_STRING, &id, DBUS_TYPE_STRING, &address, DBUS_TYPE_INT32, &active_generation, DBUS_TYPE_INT32, &order_generation, DBUS_TYPE_INT32, &clipboard_generation, DBUS_TYPE_INVALID))) { g_warning("Received invalid message: %s", e.message); dbus_error_free(&e); return -1; } if (strcmp(id, lc->server->id) == 0) { 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; } lc->server->active_generation = MAX(lc->server->active_generation, active_generation); lc->server->order_generation = MAX(lc->server->order_generation, order_generation); lc->server->clipboard_generation = MAX(lc->server->clipboard_generation, clipboard_generation); g_debug("Got welcome from %s (%s)", id, address); lc->id = g_strdup(id); lc->address = g_strdup(address); g_hash_table_insert(lc->server->connections_by_id, lc->id, lc); server_position_connection(lc->server, lc); /* 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); /* Notify new node about old nodes */ for (i = lc->server->connections; i; i = i->next) { LassiConnection *k = i->data; 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); } if (lc->we_are_client) { server_send_update_grab(lc->server, -1); lassi_server_send_update_order(lc->server, NULL); lc->delayed_welcome = FALSE; 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 void connection_unlink(LassiConnection *lc, gboolean remove_from_order) { LassiServer *ls; g_assert(lc); g_debug("Unlinking %s (%s)", lc->id, lc->address); ls = lc->server; 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); } ls->connections = g_list_remove(ls->connections, lc); ls->n_connections --; 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); if (ls->clipboard_connection == lc) { ls->clipboard_connection = NULL; ls->clipboard_empty = TRUE; lassi_clipboard_clear(&lc->server->clipboard_info, FALSE); } if (ls->primary_connection == lc) { ls->primary_connection = NULL; 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); } server_layout_changed(ls, -1); lassi_prefs_update(&ls->prefs_info); server_dump(ls); } lassi_tray_update(&ls->tray_info, ls->n_connections); connection_destroy(lc); }