This is the direction I wanna take with all interfaces: Clearly separate interface (aka version information and function pointers) and state information. SpiceKbdInterface defines the interface, SpiceKbdState maintains state information. Keyboard hasn't much beside a pointer to SpiceKbdInterface, for other interfaces this very likely will be different.
All SpiceKbdInterface function pointers carry a opaque value as first argument. This is the opaque pointer passed to spice_server_add_interface. Signed-off-by: Gerd Hoffmann <kra...@redhat.com> --- server/reds.c | 67 +++++++++++++++++++++++++++---------------------- server/reds.h | 11 ++++++++ server/vd_interface.h | 17 +++++------- 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/server/reds.c b/server/reds.c index a4563d4..ad1eeee 100644 --- a/server/reds.c +++ b/server/reds.c @@ -54,7 +54,7 @@ SpiceCoreInterface *core = NULL; static MigrationInterface *mig = NULL; -static KeyboardInterface *keyboard = NULL; +static SpiceKbdState *keyboard = NULL; static MouseInterface *mouse = NULL; static TabletInterface *tablet = NULL; static VDIPortInterface *vdagent = NULL; @@ -2120,12 +2120,20 @@ static void activate_modifiers_watch() core->timer_start(reds->key_modifiers_timer, KEY_MODIFIERS_TTL); } -static void push_key_scan(uint8_t scan) +static void kbd_push_scan(SpiceKbdState *kbd, uint8_t scan) { - if (!keyboard) { + if (!kbd) { return; } - keyboard->push_scan_freg(keyboard, scan); + kbd->ki->push_scan_freg(kbd->base.opaque, scan); +} + +static uint8_t kbd_get_leds(SpiceKbdState *kbd) +{ + if (!kbd) { + return 0; + } + return kbd->ki->get_leds(kbd->base.opaque); } static void inputs_handle_input(void *opaque, SpiceDataHeader *header) @@ -2146,7 +2154,7 @@ static void inputs_handle_input(void *opaque, SpiceDataHeader *header) uint8_t *now = (uint8_t *)&key_down->code; uint8_t *end = now + sizeof(key_down->code); for (; now < end && *now; now++) { - push_key_scan(*now); + kbd_push_scan(keyboard, *now); } break; } @@ -2244,22 +2252,24 @@ static void inputs_handle_input(void *opaque, SpiceDataHeader *header) } case SPICE_MSGC_INPUTS_KEY_MODIFIERS: { SpiceMsgcKeyModifiers *modifiers = (SpiceMsgcKeyModifiers *)buf; + uint8_t leds; + if (!keyboard) { break; } - uint8_t leds = keyboard->get_leds(keyboard); + leds = kbd_get_leds(keyboard); if ((modifiers->modifiers & SPICE_SCROLL_LOCK_MODIFIER) != (leds & SPICE_SCROLL_LOCK_MODIFIER)) { - push_key_scan(SCROLL_LOCK_SCAN_CODE); - push_key_scan(SCROLL_LOCK_SCAN_CODE | 0x80); + kbd_push_scan(keyboard, SCROLL_LOCK_SCAN_CODE); + kbd_push_scan(keyboard, SCROLL_LOCK_SCAN_CODE | 0x80); } if ((modifiers->modifiers & SPICE_NUM_LOCK_MODIFIER) != (leds & SPICE_NUM_LOCK_MODIFIER)) { - push_key_scan(NUM_LOCK_SCAN_CODE); - push_key_scan(NUM_LOCK_SCAN_CODE | 0x80); + kbd_push_scan(keyboard, NUM_LOCK_SCAN_CODE); + kbd_push_scan(keyboard, NUM_LOCK_SCAN_CODE | 0x80); } if ((modifiers->modifiers & SPICE_CAPS_LOCK_MODIFIER) != (leds & SPICE_CAPS_LOCK_MODIFIER)) { - push_key_scan(CAPS_LOCK_SCAN_CODE); - push_key_scan(CAPS_LOCK_SCAN_CODE | 0x80); + kbd_push_scan(keyboard, CAPS_LOCK_SCAN_CODE); + kbd_push_scan(keyboard, CAPS_LOCK_SCAN_CODE | 0x80); } activate_modifiers_watch(); break; @@ -2284,12 +2294,12 @@ void reds_set_client_mouse_allowed(int is_client_mouse_allowed, int x_res, int y static void inputs_relase_keys(void) { - push_key_scan(0x2a | 0x80); //LSHIFT - push_key_scan(0x36 | 0x80); //RSHIFT - push_key_scan(0xe0); push_key_scan(0x1d | 0x80); //RCTRL - push_key_scan(0x1d | 0x80); //LCTRL - push_key_scan(0xe0); push_key_scan(0x38 | 0x80); //RALT - push_key_scan(0x38 | 0x80); //LALT + kbd_push_scan(keyboard, 0x2a | 0x80); //LSHIFT + kbd_push_scan(keyboard, 0x36 | 0x80); //RSHIFT + kbd_push_scan(keyboard, 0xe0); kbd_push_scan(keyboard, 0x1d | 0x80); //RCTRL + kbd_push_scan(keyboard, 0x1d | 0x80); //LCTRL + kbd_push_scan(keyboard, 0xe0); kbd_push_scan(keyboard, 0x38 | 0x80); //RALT + kbd_push_scan(keyboard, 0x38 | 0x80); //LALT } static void inputs_event(int fd, int event, void *data) @@ -2411,7 +2421,7 @@ static void inputs_link(Channel *channel, RedsStreamContext *peer, int migration header.type = SPICE_MSG_INPUTS_INIT; header.size = sizeof(SpiceMsgInputsInit); header.sub_list = 0; - inputs_init.keyboard_modifiers = keyboard ? keyboard->get_leds(keyboard) : 0; + inputs_init.keyboard_modifiers = kbd_get_leds(keyboard); if (outgoing_write(inputs_state->peer, &inputs_state->out_handler, &header, sizeof(SpiceDataHeader)) != OUTGOING_OK || outgoing_write(inputs_state->peer, &inputs_state->out_handler, &inputs_init, @@ -3969,7 +3979,7 @@ static void migrate_timout(void *opaque) static void key_modifiers_sender(void *opaque) { - reds_send_keyboard_modifiers(keyboard ? keyboard->get_leds(keyboard) : 0); + reds_send_keyboard_modifiers(kbd_get_leds(keyboard)); } uint32_t reds_get_mm_time() @@ -4042,23 +4052,20 @@ spice_server_add_interface(SpiceServer *s, SpiceBaseInterface *interface, ASSERT(reds == s); - if (strcmp(interface->type, VD_INTERFACE_KEYBOARD) == 0) { - red_printf("VD_INTERFACE_KEYBOARD"); + if (strcmp(interface->type, SPICE_INTERFACE_KEYBOARD) == 0) { + red_printf("SPICE_INTERFACE_KEYBOARD"); if (keyboard) { red_printf("already have keyboard"); return NULL; } - if (interface->major_version != VD_INTERFACE_KEYBOARD_MAJOR || - interface->minor_version < VD_INTERFACE_KEYBOARD_MINOR) { + if (interface->major_version != SPICE_INTERFACE_KEYBOARD_MAJOR || + interface->minor_version < SPICE_INTERFACE_KEYBOARD_MINOR) { red_printf("unsuported keyboard interface"); return NULL; } - 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"); - } - } + keyboard = spice_malloc0(sizeof(*keyboard)); + keyboard->ki = container_of(interface, SpiceKbdInterface, base); + is = &keyboard->base; } else if (strcmp(interface->type, VD_INTERFACE_MOUSE) == 0) { red_printf("VD_INTERFACE_MOUSE"); diff --git a/server/reds.h b/server/reds.h index a2dadee..b5a4c71 100644 --- a/server/reds.h +++ b/server/reds.h @@ -62,6 +62,11 @@ struct SpiceInterfaceState { void *opaque; }; +typedef struct SpiceKbdState { + SpiceInterfaceState base; + SpiceKbdInterface *ki; +} SpiceKbdState; + void reds_desable_mm_timer(); void reds_enable_mm_timer(); void reds_update_mm_timer(uint32_t mm_time); @@ -76,5 +81,11 @@ extern uint64_t bitrate_per_sec; #define IS_LOW_BANDWIDTH() (bitrate_per_sec < 10 * 1024 * 1024) +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof(((type *) 0)->member) *__mptr = (ptr); \ + (type *) ((char *) __mptr - offsetof(type, member));}) +#endif + #endif diff --git a/server/vd_interface.h b/server/vd_interface.h index fb40bb0..9784360 100644 --- a/server/vd_interface.h +++ b/server/vd_interface.h @@ -192,20 +192,17 @@ struct QXLInterface { int (*flush_resources)(QXLInterface *qxl); }; -#define VD_INTERFACE_KEYBOARD "keyboard" -#define VD_INTERFACE_KEYBOARD_MAJOR 1 -#define VD_INTERFACE_KEYBOARD_MINOR 1 -typedef struct KeyboardInterface KeyboardInterface; +#define SPICE_INTERFACE_KEYBOARD "keyboard" +#define SPICE_INTERFACE_KEYBOARD_MAJOR 1 +#define SPICE_INTERFACE_KEYBOARD_MINOR 1 +typedef struct SpiceKbdInterface SpiceKbdInterface; typedef void (*keyborad_leads_notifier_t)(void *opaque, uint8_t leds); -struct KeyboardInterface { +struct SpiceKbdInterface { SpiceBaseInterface base; - void (*push_scan_freg)(KeyboardInterface *keyboard, uint8_t frag); - uint8_t (*get_leds)(KeyboardInterface *keyboard); - VDObjectRef (*register_leds_notifier)(KeyboardInterface *keyboard, - keyborad_leads_notifier_t notifier, void *opaque); - void (*unregister_leds_notifayer)(KeyboardInterface *keyboard, VDObjectRef notifier); + void (*push_scan_freg)(void *opaque, uint8_t frag); + uint8_t (*get_leds)(void *opaque); }; #define VD_INTERFACE_MOUSE "mouse" -- 1.6.6.1 _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel