/* coroutine context */ G_GNUC_INTERNAL void spice_channel_handle_wait_for_channels(SpiceChannel *channel, SpiceMsgIn *in) { SpiceChannelPrivate *c = channel->priv; SpiceMsgWaitForChannels *wfc = spice_msg_in_parsed(in); int i; for (i = 0; i < wfc->wait_count; ++i) { WaitForChannelData data = { .wait = wfc->wait_list + i, .channel = channel }; CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 " (%d/%d)", data.wait->message_serial, i + 1, wfc->wait_count); if (g_coroutine_condition_wait(&c->coroutine, wait_for_channel, &data)) CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 ", done", data.wait->message_serial); else CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 ", cancelled", data.wait->message_serial); } } static void get_msg_handler(SpiceChannel *channel, SpiceMsgIn *in, gpointer data) { SpiceMsgIn **msg = data; g_return_if_fail(msg != NULL); g_return_if_fail(*msg == NULL); spice_msg_in_ref(in); *msg = in; }
/* coroutine context */ G_GNUC_INTERNAL void spice_channel_handle_notify(SpiceChannel *channel, SpiceMsgIn *in) { static const char* severity_strings[] = {"info", "warn", "error"}; static const char* visibility_strings[] = {"!", "!!", "!!!"}; SpiceMsgNotify *notify = spice_msg_in_parsed(in); const char *severity = "?"; const char *visibility = "?"; const char *message_str = NULL; if (notify->severity <= SPICE_NOTIFY_SEVERITY_ERROR) { severity = severity_strings[notify->severity]; } if (notify->visibilty <= SPICE_NOTIFY_VISIBILITY_HIGH) { visibility = visibility_strings[notify->visibilty]; } if (notify->message_len && notify->message_len <= in->dpos - sizeof(*notify)) { message_str = (char*)notify->message; } CHANNEL_DEBUG(channel, "%s -- %s%s #%u%s%.*s", __FUNCTION__, severity, visibility, notify->what, message_str ? ": " : "", notify->message_len, message_str ? message_str : ""); }
/* coroutine context */ G_GNUC_INTERNAL void spice_channel_handle_disconnect(SpiceChannel *channel, SpiceMsgIn *in) { SpiceMsgDisconnect *disconnect = spice_msg_in_parsed(in); CHANNEL_DEBUG(channel, "%s: ts: %" PRIu64", reason: %u", __FUNCTION__, disconnect->time_stamp, disconnect->reason); }
/* coroutine context */ G_GNUC_INTERNAL void spice_channel_handle_migrate(SpiceChannel *channel, SpiceMsgIn *in) { SpiceMsgOut *out; SpiceMsgIn *data = NULL; SpiceMsgMigrate *mig = spice_msg_in_parsed(in); SpiceChannelPrivate *c = channel->priv; g_message("spice_channel_handle_migrate.\n"); CHANNEL_DEBUG(channel, "%s: flags %u", __FUNCTION__, mig->flags); if (mig->flags & SPICE_MIGRATE_NEED_FLUSH) { g_message("++++++++++++ SPICE_MIGRATE_NEED_FLUSH.\n"); /* if peer version > 1: pushing the mark msg before all other messgages and sending it, * and only it */ if (c->peer_hdr.major_version == 1) { /* iterate_write is blocking and flushing all pending write */ SPICE_CHANNEL_GET_CLASS(channel)->iterate_write(channel); } out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MIGRATE_FLUSH_MARK); spice_msg_out_send_internal(out); } if (mig->flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) { g_message("+++++++++++ SPICE_MIGRATE_NEED_DATA_TRANSFER.\n"); spice_channel_recv_msg(channel, get_msg_handler, &data); if (!data) { g_critical("expected SPICE_MSG_MIGRATE_DATA, got empty message"); goto end; } else if (spice_header_get_msg_type(data->header, c->use_mini_header) != SPICE_MSG_MIGRATE_DATA) { g_critical("expected SPICE_MSG_MIGRATE_DATA, got %d", spice_header_get_msg_type(data->header, c->use_mini_header)); goto end; } } /* swapping channels sockets */ spice_session_channel_migrate(c->session, channel); /* pushing the MIGRATE_DATA before all other pending messages */ if ((mig->flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) && (data != NULL)) { out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MIGRATE_DATA); spice_marshaller_add(out->marshaller, data->data, spice_header_get_msg_size(data->header, c->use_mini_header)); spice_msg_out_send_internal(out); } end: if (data) spice_msg_in_unref(data); }
static void spice_gtk_session_sync_keyboard_modifiers_for_channel(SpiceGtkSession *self, SpiceInputsChannel* inputs, gboolean force) { gint guest_modifiers = 0, client_modifiers = 0; g_return_if_fail(SPICE_IS_INPUTS_CHANNEL(inputs)); g_object_get(inputs, "key-modifiers", &guest_modifiers, NULL); client_modifiers = get_keyboard_lock_modifiers(); if (force || client_modifiers != guest_modifiers) { CHANNEL_DEBUG(inputs, "client_modifiers:0x%x, guest_modifiers:0x%x", client_modifiers, guest_modifiers); spice_inputs_set_key_locks(inputs, client_modifiers); } }