From 30c740201d1b111ca28e7881ddbcc91f259b8a11 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 30 Mar 2010 11:15:01 +0200 Subject: VDInterface: redesign. VDInterface has been renamed to SpiceBaseInterface. Dropped base_version element, shlib versioning should be used instead. Dropped id element, it is passed to spice_server_add_interface() instead. Now SpiceBaseInterface has static information only, multiple interface instances can share it. Added SpiceBaseInstance struct for maintaining per-instance state information. Adapted spice_server_{add,remove}_interface() functions to the new world. --- server/red_dispatcher.c | 8 +- server/red_dispatcher.h | 2 +- server/reds.c | 332 ++++++++++++++++++++++++------------------------ server/snd_worker.c | 6 +- server/spice.h | 8 +- server/vd_interface.h | 41 +++--- 6 files changed, 198 insertions(+), 199 deletions(-) (limited to 'server') diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index b3cf8cd1..f7c66464 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -462,7 +462,7 @@ uint32_t red_dispatcher_qxl_ram_size() return qxl_info.qxl_ram_size; } -RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface) +RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id) { RedDispatcher *dispatcher; int channels[2]; @@ -493,7 +493,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface) dispatcher = spice_new0(RedDispatcher, 1); dispatcher->channel = channels[0]; init_data.qxl_interface = dispatcher->qxl_interface = qxl_interface; - init_data.id = qxl_interface->base.id; + init_data.id = id; init_data.channel = channels[1]; init_data.pending = &dispatcher->pending; init_data.num_renderers = num_renderers; @@ -548,7 +548,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface) reds_channel = spice_new0(Channel, 1); reds_channel->type = SPICE_CHANNEL_DISPLAY; - reds_channel->id = qxl_interface->base.id; + reds_channel->id = id; reds_channel->link = red_dispatcher_set_peer; reds_channel->shutdown = red_dispatcher_shutdown_peer; reds_channel->migrate = red_dispatcher_migrate; @@ -557,7 +557,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface) cursor_channel = spice_new0(Channel, 1); cursor_channel->type = SPICE_CHANNEL_CURSOR; - cursor_channel->id = qxl_interface->base.id; + cursor_channel->id = id; cursor_channel->link = red_dispatcher_set_cursor_peer; cursor_channel->shutdown = red_dispatcher_shutdown_cursor_peer; cursor_channel->migrate = red_dispatcher_cursor_migrate; diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h index df151041..b0bc040f 100644 --- a/server/red_dispatcher.h +++ b/server/red_dispatcher.h @@ -19,7 +19,7 @@ #define _H_RED_DISPATCHER -struct RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface); +struct RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id); void red_dispatcher_set_mm_time(uint32_t); void red_dispatcher_on_ic_change(); diff --git a/server/reds.c b/server/reds.c index e9bfeb00..b81e0b35 100644 --- a/server/reds.c +++ b/server/reds.c @@ -359,7 +359,6 @@ typedef struct PingItem { int size; } PingItem; - #define ZERO_BUF_SIZE 4096 static uint8_t zero_page[ZERO_BUF_SIZE] = {0}; @@ -4004,163 +4003,179 @@ static void attach_to_red_agent(VDIPortInterface *interface) reds_send_agent_connected(); } -static void interface_change_notifier(void *opaque, VDInterface *interface, - VDInterfaceChangeType change) +__visible__ int spice_server_add_interface(SpiceServer *s, + SpiceBaseInstance *sin, + int id) { - if (interface->base_version != VM_INTERFACE_VERSION) { - red_printf("unsuported base interface version"); - return; - } - switch (change) { - case VD_INTERFACE_ADDING: - if (strcmp(interface->type, VD_INTERFACE_KEYBOARD) == 0) { - red_printf("VD_INTERFACE_KEYBOARD"); - if (keyboard) { - red_printf("already have keyboard"); - return; - } - if (interface->major_version != VD_INTERFACE_KEYBOARD_MAJOR || - interface->minor_version < VD_INTERFACE_KEYBOARD_MINOR) { - red_printf("unsuported keyboard interface"); - return; - } - keyboard = (KeyboardInterface *)interface; - if (keyboard->register_leds_notifier) { - if (!keyboard->register_leds_notifier(keyboard, reds_on_keyboard_leds_change, NULL)) { - red_error("register leds notifier failed"); - } - } - } else if (strcmp(interface->type, VD_INTERFACE_MOUSE) == 0) { - red_printf("VD_INTERFACE_MOUSE"); - if (mouse) { - red_printf("already have mouse"); - return; - } - if (interface->major_version != VD_INTERFACE_MOUSE_MAJOR || - interface->minor_version < VD_INTERFACE_MOUSE_MINOR) { - red_printf("unsuported mouse interface"); - return; - } - mouse = (MouseInterface *)interface; - } else if (strcmp(interface->type, VD_INTERFACE_MIGRATION) == 0) { - red_printf("VD_INTERFACE_MIGRATION"); - if (mig) { - red_printf("already have migration"); - return; - } - if (interface->major_version != VD_INTERFACE_MIGRATION_MAJOR || - interface->minor_version < VD_INTERFACE_MIGRATION_MINOR) { - red_printf("unsuported migration interface"); - return; - } - mig = (MigrationInterface *)interface; - reds->mig_notifier = mig->register_notifiers(mig, MIGRATION_NOTIFY_SPICE_KEY, - reds_mig_started, reds_mig_finished, - reds_mig_recv, NULL); - if (reds->mig_notifier == INVALID_VD_OBJECT_REF) { - red_error("migration register failed"); - } - } else if (strcmp(interface->type, VD_INTERFACE_QXL) == 0) { - QXLInterface *qxl_interface; + SpiceBaseInterface *interface = sin->sif; - red_printf("VD_INTERFACE_QXL"); - if (interface->major_version != VD_INTERFACE_QXL_MAJOR || - interface->minor_version < VD_INTERFACE_QXL_MINOR) { - red_printf("unsuported qxl interface"); - return; - } - qxl_interface = (QXLInterface *)interface; - red_dispatcher_init(qxl_interface); - } else if (strcmp(interface->type, VD_INTERFACE_TABLET) == 0) { - red_printf("VD_INTERFACE_TABLET"); - if (tablet) { - red_printf("already have tablet"); - return; - } - if (interface->major_version != VD_INTERFACE_TABLET_MAJOR || - interface->minor_version < VD_INTERFACE_TABLET_MINOR) { - red_printf("unsuported tablet interface"); - return; - } - tablet = (TabletInterface *)interface; - reds_update_mouse_mode(); - if (reds->is_client_mouse_allowed) { - tablet->set_logical_size(tablet, reds->monitor_mode.x_res, - reds->monitor_mode.y_res); - } - } else if (strcmp(interface->type, VD_INTERFACE_PLAYBACK) == 0) { - red_printf("VD_INTERFACE_PLAYBACK"); - if (interface->major_version != VD_INTERFACE_PLAYBACK_MAJOR || - interface->minor_version < VD_INTERFACE_PLAYBACK_MINOR) { - red_printf("unsuported playback interface"); - return; - } - snd_attach_playback((PlaybackInterface *)interface); - } else if (strcmp(interface->type, VD_INTERFACE_RECORD) == 0) { - red_printf("VD_INTERFACE_RECORD"); - if (interface->major_version != VD_INTERFACE_RECORD_MAJOR || - interface->minor_version < VD_INTERFACE_RECORD_MINOR) { - red_printf("unsuported record interface"); - return; - } - snd_attach_record((RecordInterface *)interface); - } else if (strcmp(interface->type, VD_INTERFACE_VDI_PORT) == 0) { - red_printf("VD_INTERFACE_VDI_PORT"); - if (vdagent) { - red_printf("vdi port already attached"); - return; - } - if (interface->major_version != VD_INTERFACE_VDI_PORT_MAJOR || - interface->minor_version < VD_INTERFACE_VDI_PORT_MINOR) { - red_printf("unsuported vdi port interface"); - return; + ASSERT(reds == s); + + if (strcmp(interface->type, VD_INTERFACE_KEYBOARD) == 0) { + red_printf("VD_INTERFACE_KEYBOARD"); + if (keyboard) { + red_printf("already have keyboard"); + return -1; + } + if (interface->major_version != VD_INTERFACE_KEYBOARD_MAJOR || + interface->minor_version < VD_INTERFACE_KEYBOARD_MINOR) { + red_printf("unsuported keyboard interface"); + return -1; + } + keyboard = (KeyboardInterface *)interface; + if (keyboard->register_leds_notifier) { + if (!keyboard->register_leds_notifier(keyboard, reds_on_keyboard_leds_change, NULL)) { + red_error("register leds notifier failed"); } - attach_to_red_agent((VDIPortInterface *)interface); - } else if (strcmp(interface->type, VD_INTERFACE_NET_WIRE) == 0) { + } + + } else if (strcmp(interface->type, VD_INTERFACE_MOUSE) == 0) { + red_printf("VD_INTERFACE_MOUSE"); + if (mouse) { + red_printf("already have mouse"); + return -1; + } + if (interface->major_version != VD_INTERFACE_MOUSE_MAJOR || + interface->minor_version < VD_INTERFACE_MOUSE_MINOR) { + red_printf("unsuported mouse interface"); + return -1; + } + mouse = (MouseInterface *)interface; + + } else if (strcmp(interface->type, VD_INTERFACE_MIGRATION) == 0) { + red_printf("VD_INTERFACE_MIGRATION"); + if (mig) { + red_printf("already have migration"); + return -1; + } + if (interface->major_version != VD_INTERFACE_MIGRATION_MAJOR || + interface->minor_version < VD_INTERFACE_MIGRATION_MINOR) { + red_printf("unsuported migration interface"); + return -1; + } + mig = (MigrationInterface *)interface; + reds->mig_notifier = mig->register_notifiers(mig, MIGRATION_NOTIFY_SPICE_KEY, + reds_mig_started, reds_mig_finished, + reds_mig_recv, NULL); + if (reds->mig_notifier == INVALID_VD_OBJECT_REF) { + red_error("migration register failed"); + } + + } else if (strcmp(interface->type, VD_INTERFACE_QXL) == 0) { + QXLInterface *qxl_interface; + + red_printf("VD_INTERFACE_QXL"); + if (interface->major_version != VD_INTERFACE_QXL_MAJOR || + interface->minor_version < VD_INTERFACE_QXL_MINOR) { + red_printf("unsuported qxl interface"); + return -1; + } + qxl_interface = (QXLInterface *)interface; + red_dispatcher_init(qxl_interface, id); + + } else if (strcmp(interface->type, VD_INTERFACE_TABLET) == 0) { + red_printf("VD_INTERFACE_TABLET"); + if (tablet) { + red_printf("already have tablet"); + return -1; + } + if (interface->major_version != VD_INTERFACE_TABLET_MAJOR || + interface->minor_version < VD_INTERFACE_TABLET_MINOR) { + red_printf("unsuported tablet interface"); + return -1; + } + tablet = (TabletInterface *)interface; + reds_update_mouse_mode(); + if (reds->is_client_mouse_allowed) { + tablet->set_logical_size(tablet, reds->monitor_mode.x_res, + reds->monitor_mode.y_res); + } + + } else if (strcmp(interface->type, VD_INTERFACE_PLAYBACK) == 0) { + red_printf("VD_INTERFACE_PLAYBACK"); + if (interface->major_version != VD_INTERFACE_PLAYBACK_MAJOR || + interface->minor_version < VD_INTERFACE_PLAYBACK_MINOR) { + red_printf("unsuported playback interface"); + return -1; + } + snd_attach_playback((PlaybackInterface *)interface); + + } else if (strcmp(interface->type, VD_INTERFACE_RECORD) == 0) { + red_printf("VD_INTERFACE_RECORD"); + if (interface->major_version != VD_INTERFACE_RECORD_MAJOR || + interface->minor_version < VD_INTERFACE_RECORD_MINOR) { + red_printf("unsuported record interface"); + return -1; + } + snd_attach_record((RecordInterface *)interface); + + } else if (strcmp(interface->type, VD_INTERFACE_VDI_PORT) == 0) { + red_printf("VD_INTERFACE_VDI_PORT"); + if (vdagent) { + red_printf("vdi port already attached"); + return -1; + } + if (interface->major_version != VD_INTERFACE_VDI_PORT_MAJOR || + interface->minor_version < VD_INTERFACE_VDI_PORT_MINOR) { + red_printf("unsuported vdi port interface"); + return -1; + } + attach_to_red_agent((VDIPortInterface *)interface); + + } else if (strcmp(interface->type, VD_INTERFACE_NET_WIRE) == 0) { #ifdef HAVE_SLIRP - NetWireInterface * net_wire = (NetWireInterface *)interface; - red_printf("VD_INTERFACE_NET_WIRE"); - if (red_tunnel) { - red_printf("net wire already attached"); - return; - } - if (interface->major_version != VD_INTERFACE_NET_WIRE_MAJOR || - interface->minor_version < VD_INTERFACE_NET_WIRE_MINOR) { - red_printf("unsuported net wire interface"); - return; - } - red_tunnel = red_tunnel_attach(core, net_wire); + NetWireInterface * net_wire = (NetWireInterface *)interface; + red_printf("VD_INTERFACE_NET_WIRE"); + if (red_tunnel) { + red_printf("net wire already attached"); + return -1; + } + if (interface->major_version != VD_INTERFACE_NET_WIRE_MAJOR || + interface->minor_version < VD_INTERFACE_NET_WIRE_MINOR) { + red_printf("unsuported net wire interface"); + return -1; + } + red_tunnel = red_tunnel_attach(core, net_wire); #else - red_printf("unsupported net wire interface"); + red_printf("unsupported net wire interface"); + return -1; #endif + } + + return 0; +} + +__visible__ int spice_server_remove_interface(SpiceBaseInstance *sin) +{ + SpiceBaseInterface *interface = sin->sif; + + if (strcmp(interface->type, VD_INTERFACE_TABLET) == 0) { + red_printf("remove VD_INTERFACE_TABLET"); + if (interface == (SpiceBaseInterface *)tablet) { + tablet = NULL; + reds_update_mouse_mode(); } - break; - case VD_INTERFACE_REMOVING: - if (strcmp(interface->type, VD_INTERFACE_TABLET) == 0) { - red_printf("remove VD_INTERFACE_TABLET"); - if (interface == (VDInterface *)tablet) { - tablet = NULL; - reds_update_mouse_mode(); - } - break; - } else if (strcmp(interface->type, VD_INTERFACE_PLAYBACK) == 0) { - red_printf("remove VD_INTERFACE_PLAYBACK"); - snd_detach_playback((PlaybackInterface *)interface); - break; - } else if (strcmp(interface->type, VD_INTERFACE_RECORD) == 0) { - red_printf("remove VD_INTERFACE_RECORD"); - snd_detach_record((RecordInterface *)interface); - break; - } else if (strcmp(interface->type, VD_INTERFACE_VDI_PORT) == 0) { - red_printf("remove VD_INTERFACE_VDI_PORT"); - if (interface == (VDInterface *)vdagent) { - reds_agent_remove(); - } - break; + + } else if (strcmp(interface->type, VD_INTERFACE_PLAYBACK) == 0) { + red_printf("remove VD_INTERFACE_PLAYBACK"); + snd_detach_playback((PlaybackInterface *)interface); + + } else if (strcmp(interface->type, VD_INTERFACE_RECORD) == 0) { + red_printf("remove VD_INTERFACE_RECORD"); + snd_detach_record((RecordInterface *)interface); + + } else if (strcmp(interface->type, VD_INTERFACE_VDI_PORT) == 0) { + red_printf("remove VD_INTERFACE_VDI_PORT"); + if (interface == (SpiceBaseInterface *)vdagent) { + reds_agent_remove(); } + + } else { red_error("VD_INTERFACE_REMOVING unsupported"); - break; + return -1; } + + return 0; } static void free_external_agent_buff(VDIPortBuf *in_buf) @@ -4256,10 +4271,6 @@ static void do_spice_init(CoreInterface *core_interface) { red_printf("starting %s", version_string); - if (core_interface->base.base_version != VM_INTERFACE_VERSION) { - red_error("bad base interface version"); - } - if (core_interface->base.major_version != VD_INTERFACE_CORE_MAJOR) { red_error("bad core interface version"); } @@ -4542,23 +4553,8 @@ __visible__ int spice_server_add_renderer(SpiceServer *s, const char *name) return 0; } -__visible__ int spice_server_add_interface(SpiceServer *s, VDInterface *interface) +__visible__ int spice_server_kbd_leds(SpiceBaseInstance *sin, int leds) { - ASSERT(reds == s); - interface_change_notifier(NULL, interface, VD_INTERFACE_ADDING); - return 0; -} - -__visible__ int spice_server_remove_interface(SpiceServer *s, VDInterface *interface) -{ - ASSERT(reds == s); - interface_change_notifier(NULL, interface, VD_INTERFACE_REMOVING); - return 0; -} - -__visible__ int spice_server_kbd_leds(SpiceServer *s, KeyboardInterface *kbd, int leds) -{ - ASSERT(reds == s); reds_on_keyboard_leds_change(NULL, leds); return 0; } diff --git a/server/snd_worker.c b/server/snd_worker.c index d5f5f377..afffb005 100644 --- a/server/snd_worker.c +++ b/server/snd_worker.c @@ -142,7 +142,7 @@ typedef struct PlaybackChannel { struct SndWorker { Channel base; - VDInterface *interface; + SpiceBaseInterface *interface; SndChannel *connection; SndWorker *next; }; @@ -1192,7 +1192,7 @@ static void remove_worker(SndWorker *worker) red_printf("not found"); } -static SndWorker *find_worker(VDInterface *interface) +static SndWorker *find_worker(SpiceBaseInterface *interface) { SndWorker *worker = workers; while (worker) { @@ -1242,7 +1242,7 @@ void snd_attach_record(RecordInterface *interface) reds_register_channel(&record_worker->base); } -static void snd_detach_common(VDInterface *interface) +static void snd_detach_common(SpiceBaseInterface *interface) { SndWorker *worker = find_worker(interface); diff --git a/server/spice.h b/server/spice.h index 094caae4..5b768ef2 100644 --- a/server/spice.h +++ b/server/spice.h @@ -43,9 +43,11 @@ int spice_server_set_tls(SpiceServer *s, int port, const char *private_key_file, const char *key_passwd, const char *dh_key_file, const char *ciphersuite); -int spice_server_add_interface(SpiceServer *s, VDInterface *interface); -int spice_server_remove_interface(SpiceServer *s, VDInterface *interface); -int spice_server_kbd_leds(SpiceServer *s, KeyboardInterface *kbd, int leds); +int spice_server_add_interface(SpiceServer *s, + SpiceBaseInstance *sin, + int id); +int spice_server_remove_interface(SpiceBaseInstance *sin); +int spice_server_kbd_leds(SpiceBaseInstance *sin, int leds); typedef enum { SPICE_IMAGE_COMPRESS_INVALID = 0, diff --git a/server/vd_interface.h b/server/vd_interface.h index 891ef524..6b86dc89 100644 --- a/server/vd_interface.h +++ b/server/vd_interface.h @@ -36,17 +36,18 @@ #define VM_INTERFACE_VERSION 1 typedef unsigned long VDObjectRef; #define INVALID_VD_OBJECT_REF 0 -typedef struct VDInterface VDInterface; -struct VDInterface { - uint32_t base_version; +typedef struct SpiceBaseInterface SpiceBaseInterface; +typedef struct SpiceBaseInstance SpiceBaseInstance; + +struct SpiceBaseInterface { const char *type; - unsigned int id; const char *description; - //todo: swap minor major order on VM_INTERFACE_VERSION change - // (here and in spacific interfaces) - uint32_t minor_version; uint32_t major_version; + uint32_t minor_version; +}; +struct SpiceBaseInstance { + SpiceBaseInterface *sif; }; #define VD_INTERFACE_CORE "core" @@ -56,7 +57,7 @@ typedef struct CoreInterface CoreInterface; typedef enum { VD_INTERFACE_ADDING, VD_INTERFACE_REMOVING, -} VDInterfaceChangeType; +} SpiceBaseInterfaceChangeType; typedef enum { VD_LOG_ERROR = 1, @@ -64,8 +65,8 @@ typedef enum { VD_LOG_INFO, } LogLevel; -typedef void (*vd_interface_change_notifier_t)(void *opaque, VDInterface *interface, - VDInterfaceChangeType change); +typedef void (*vd_interface_change_notifier_t)(void *opaque, SpiceBaseInterface *interface, + SpiceBaseInterfaceChangeType change); #define SPICE_WATCH_EVENT_READ (1 << 0) #define SPICE_WATCH_EVENT_WRITE (1 << 1) @@ -77,7 +78,7 @@ typedef struct SpiceTimer SpiceTimer; typedef void (*SpiceTimerFunc)(void *opaque); struct CoreInterface { - VDInterface base; + SpiceBaseInterface base; SpiceTimer *(*timer_add)(SpiceTimerFunc func, void *opaque); void (*timer_start)(SpiceTimer *timer, uint32_t ms); @@ -183,7 +184,7 @@ struct QXLDevSurfaceCreate { struct SpiceRect; struct QXLInterface { - VDInterface base; + SpiceBaseInterface base; uint16_t pci_vendor; uint16_t pci_id; @@ -213,7 +214,7 @@ typedef struct KeyboardInterface KeyboardInterface; typedef void (*keyborad_leads_notifier_t)(void *opaque, uint8_t leds); struct KeyboardInterface { - VDInterface base; + SpiceBaseInterface base; void (*push_scan_freg)(KeyboardInterface *keyboard, uint8_t frag); uint8_t (*get_leds)(KeyboardInterface *keyboard); @@ -228,7 +229,7 @@ struct KeyboardInterface { typedef struct MouseInterface MouseInterface; struct MouseInterface { - VDInterface base; + SpiceBaseInterface base; void (*moution)(MouseInterface* mouse, int dx, int dy, int dz, uint32_t buttons_state); @@ -241,7 +242,7 @@ struct MouseInterface { typedef struct TabletInterface TabletInterface; struct TabletInterface { - VDInterface base; + SpiceBaseInterface base; void (*set_logical_size)(TabletInterface* tablet, int width, int height); void (*position)(TabletInterface* tablet, int x, int y, uint32_t buttons_state); @@ -258,7 +259,7 @@ typedef void (*migration_notify_finished_t)(void *opaque, int completed); typedef void (*migration_notify_recv_t)(void *opaque, int fd); struct MigrationInterface { - VDInterface base; + SpiceBaseInterface base; VDObjectRef (*register_notifiers)(MigrationInterface* mig, const char *key, migration_notify_started_t, @@ -317,7 +318,7 @@ struct PlaybackPlug { }; struct PlaybackInterface { - VDInterface base; + SpiceBaseInterface base; VDObjectRef (*plug)(PlaybackInterface *playback, PlaybackPlug* plug, int *enable); void (*unplug)(PlaybackInterface *playback, VDObjectRef); @@ -343,7 +344,7 @@ struct RecordPlug { }; struct RecordInterface { - VDInterface base; + SpiceBaseInterface base; VDObjectRef (*plug)(RecordInterface *recorder, RecordPlug* plug, int *enable); void (*unplug)(RecordInterface *recorder, VDObjectRef); @@ -362,7 +363,7 @@ struct VDIPortPlug { }; struct VDIPortInterface { - VDInterface base; + SpiceBaseInterface base; VDObjectRef (*plug)(VDIPortInterface *port, VDIPortPlug* plug); void (*unplug)(VDIPortInterface *port, VDObjectRef plug); @@ -378,7 +379,7 @@ typedef struct NetWireInterface NetWireInterface; typedef void (*net_wire_packet_route_proc_t)(void *opaque, const uint8_t *pkt, int pkt_len); struct NetWireInterface { - VDInterface base; + SpiceBaseInterface base; struct in_addr (*get_ip)(NetWireInterface *vlan); int (*can_send_packet)(NetWireInterface *vlan); -- cgit