Esempio n. 1
0
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);
}
Esempio n. 2
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_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;
}
Esempio n. 3
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
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));
		}
	}
}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
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);
}