1 /* 2 * Copyright (C) 2010 Red Hat, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 or 7 * (at your option) version 3 of the License. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include <stdlib.h> 19 #include <stdio.h> 20 #include <string.h> 21 22 #include <spice.h> 23 #include <spice/enums.h> 24 25 #include "qemu-common.h" 26 #include "qemu-spice.h" 27 #include "console.h" 28 29 /* keyboard bits */ 30 31 typedef struct QemuSpiceKbd { 32 SpiceKbdInstance sin; 33 int ledstate; 34 } QemuSpiceKbd; 35 36 static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag); 37 static uint8_t kbd_get_leds(SpiceKbdInstance *sin); 38 static void kbd_leds(void *opaque, int l); 39 40 static const SpiceKbdInterface kbd_interface = { 41 .base.type = SPICE_INTERFACE_KEYBOARD, 42 .base.description = "qemu keyboard", 43 .base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR, 44 .base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR, 45 .push_scan_freg = kbd_push_key, 46 .get_leds = kbd_get_leds, 47 }; 48 49 static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag) 50 { 51 kbd_put_keycode(frag); 52 } 53 54 static uint8_t kbd_get_leds(SpiceKbdInstance *sin) 55 { 56 QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin); 57 return kbd->ledstate; 58 } 59 60 static void kbd_leds(void *opaque, int ledstate) 61 { 62 QemuSpiceKbd *kbd = opaque; 63 64 kbd->ledstate = 0; 65 if (ledstate & QEMU_SCROLL_LOCK_LED) { 66 kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK; 67 } 68 if (ledstate & QEMU_NUM_LOCK_LED) { 69 kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK; 70 } 71 if (ledstate & QEMU_CAPS_LOCK_LED) { 72 kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK; 73 } 74 spice_server_kbd_leds(&kbd->sin, ledstate); 75 } 76 77 void qemu_spice_input_init(void) 78 { 79 QemuSpiceKbd *kbd; 80 81 kbd = qemu_mallocz(sizeof(*kbd)); 82 kbd->sin.base.sif = &kbd_interface.base; 83 qemu_spice_add_interface(&kbd->sin.base); 84 qemu_add_led_event_handler(kbd_leds, kbd); 85 } 86