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.
This commit is contained in:
Gerd Hoffmann 2010-03-30 11:15:01 +02:00
parent 455cae7c74
commit 30c740201d
6 changed files with 201 additions and 202 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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;
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");
}
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;
}
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
}
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;
}
red_error("VD_INTERFACE_REMOVING unsupported");
break;
}
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();
}
} 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");
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;
}

View File

@ -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);

View File

@ -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,

View File

@ -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);