From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Sat, 21 Jan 2017 15:29:18 +0000 Subject: [spice-server] stream-channel: Write a base channel to implement the streaming Currently only compile, not used and not much sense Signed-off-by: Frediano Ziglio Acked-by: Jonathon Jongsma --- server/Makefile.am | 2 + server/stream-channel.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++ server/stream-channel.h | 53 +++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 server/stream-channel.c create mode 100644 server/stream-channel.h diff --git a/server/Makefile.am b/server/Makefile.am index f08ddf883..e2e3ce861 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -166,6 +166,8 @@ libserver_la_SOURCES = \ stat.h \ stream.c \ stream.h \ + stream-channel.c \ + stream-channel.h \ stream-device.c \ sw-canvas.c \ tree.c \ diff --git a/server/stream-channel.c b/server/stream-channel.c new file mode 100644 index 000000000..fd735f562 --- /dev/null +++ b/server/stream-channel.c @@ -0,0 +1,175 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2017 Red Hat, Inc. + + This library 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. + + This library 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 this library; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "red-channel-client.h" +#include "stream-channel.h" +#include "reds.h" +#include "common-graphics-channel.h" + +#define TYPE_STREAM_CHANNEL_CLIENT stream_channel_client_get_type() + +#define STREAM_CHANNEL_CLIENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_STREAM_CHANNEL_CLIENT, StreamChannelClient)) +#define STREAM_CHANNEL_CLIENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_STREAM_CHANNEL_CLIENT, StreamChannelClientClass)) +#define IS_STREAM_CHANNEL_CLIENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_STREAM_CHANNEL_CLIENT)) +#define IS_STREAM_CHANNEL_CLIENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_STREAM_CHANNEL_CLIENT)) +#define STREAM_CHANNEL_CLIENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_STREAM_CHANNEL_CLIENT, StreamChannelClientClass)) + +typedef struct StreamChannelClient StreamChannelClient; +typedef struct StreamChannelClientClass StreamChannelClientClass; + +/* we need to inherit from CommonGraphicsChannelClient + * to get buffer handling */ +struct StreamChannelClient { + CommonGraphicsChannelClient parent; +}; + +struct StreamChannelClientClass { + CommonGraphicsChannelClientClass parent_class; +}; + +GType stream_channel_client_get_type(void) G_GNUC_CONST; + +G_DEFINE_TYPE(StreamChannelClient, stream_channel_client, TYPE_COMMON_GRAPHICS_CHANNEL_CLIENT) + +struct StreamChannel { + RedChannel parent; +}; + +struct StreamChannelClass { + RedChannelClass parent_class; +}; + +G_DEFINE_TYPE(StreamChannel, stream_channel, RED_TYPE_CHANNEL) + +static void stream_channel_client_on_disconnect(RedChannelClient *rcc); + +static void +stream_channel_client_class_init(StreamChannelClientClass *klass) +{ + RedChannelClientClass *channel_class = RED_CHANNEL_CLIENT_CLASS(klass); + + channel_class->on_disconnect = stream_channel_client_on_disconnect; +} + +static void +stream_channel_client_init(StreamChannelClient *client) +{ +} + +static void +stream_channel_client_on_disconnect(RedChannelClient *rcc) +{ +} + +static StreamChannelClient* +stream_channel_client_new(StreamChannel *channel, RedClient *client, RedsStream *stream, + int mig_target, RedChannelCapabilities *caps) +{ + StreamChannelClient *rcc; + + rcc = g_initable_new(TYPE_STREAM_CHANNEL_CLIENT, + NULL, NULL, + "channel", channel, + "client", client, + "stream", stream, + "monitor-latency", FALSE, + "caps", caps, + NULL); + + return rcc; +} + +static void +stream_channel_send_item(RedChannelClient *rcc, RedPipeItem *pipe_item) +{ + switch (pipe_item->type) { + default: + spice_error("invalid pipe item type"); + } + + red_channel_client_begin_send_message(rcc); +} + +StreamChannel* +stream_channel_new(RedsState *server, uint32_t id) +{ + return g_object_new(TYPE_STREAM_CHANNEL, + "spice-server", server, + "core-interface", reds_get_core_interface(server), + "channel-type", SPICE_CHANNEL_DISPLAY, + // TODO this id should be after all qxl devices + "id", id, + "migration-flags", 0, + "handle-acks", TRUE, // TODO sure ?? + NULL); +} + +static void +stream_channel_connect(RedChannel *red_channel, RedClient *red_client, RedsStream *stream, + int migration, RedChannelCapabilities *caps) +{ + StreamChannel *channel = STREAM_CHANNEL(red_channel); + StreamChannelClient *client; + + spice_return_if_fail(stream != NULL); + + client = stream_channel_client_new(channel, red_client, stream, migration, caps); + spice_return_if_fail(client != NULL); +} + +static void +stream_channel_constructed(GObject *object) +{ + ClientCbs client_cbs = { NULL, }; + RedChannel *red_channel = RED_CHANNEL(object); + RedsState *reds = red_channel_get_server(red_channel); + + G_OBJECT_CLASS(stream_channel_parent_class)->constructed(object); + + client_cbs.connect = stream_channel_connect; + red_channel_register_client_cbs(red_channel, &client_cbs, NULL); + + reds_register_channel(reds, red_channel); +} + +static void +stream_channel_class_init(StreamChannelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + RedChannelClass *channel_class = RED_CHANNEL_CLASS(klass); + + object_class->constructed = stream_channel_constructed; + + channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_DISPLAY, NULL); + channel_class->handle_message = red_channel_client_handle_message; + + channel_class->send_item = stream_channel_send_item; +} + +static void +stream_channel_init(StreamChannel *channel) +{ +} diff --git a/server/stream-channel.h b/server/stream-channel.h new file mode 100644 index 000000000..e50e17e9e --- /dev/null +++ b/server/stream-channel.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2017 Red Hat, Inc. + + This library 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. + + This library 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 this library; if not, see . +*/ + +#ifndef STREAM_CHANNEL_H_ +#define STREAM_CHANNEL_H_ + +#include "red-channel.h" + +G_BEGIN_DECLS + +/** + * This type it's a RedChannel class which implement display + * channel with input only by stream. + * A pointer to StreamChannel can be converted to a RedChannel. + */ +typedef struct StreamChannel StreamChannel; +typedef struct StreamChannelClass StreamChannelClass; + +#define TYPE_STREAM_CHANNEL stream_channel_get_type() + +#define STREAM_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_STREAM_CHANNEL, StreamChannel)) +#define STREAM_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_STREAM_CHANNEL, StreamChannelClass)) +#define IS_STREAM_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_STREAM_CHANNEL)) +#define IS_STREAM_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_STREAM_CHANNEL)) +#define STREAM_CHANNEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_STREAM_CHANNEL, StreamChannelClass)) + +GType stream_channel_get_type(void) G_GNUC_CONST; + +/** + * Create StreamChannel. + */ +StreamChannel* stream_channel_new(RedsState *server, uint32_t id); + +G_END_DECLS + +#endif /* STREAM_CHANNEL_H_ */