From patchwork Thu Dec 15 13:16:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Ossman X-Patchwork-Id: 706079 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tfYss1S7zz9snm for ; Fri, 16 Dec 2016 00:18:24 +1100 (AEDT) Received: from localhost ([::1]:54543 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cHVvQ-00027b-49 for incoming@patchwork.ozlabs.org; Thu, 15 Dec 2016 08:18:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34156) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cHVu9-0006nQ-Ql for qemu-devel@nongnu.org; Thu, 15 Dec 2016 08:17:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cHVu3-00069A-Pr for qemu-devel@nongnu.org; Thu, 15 Dec 2016 08:17:01 -0500 Received: from hayek.cendio.se ([193.12.253.119]:48190 helo=mail.cendio.se) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cHVu3-000678-Iy for qemu-devel@nongnu.org; Thu, 15 Dec 2016 08:16:55 -0500 Received: by mail.cendio.se (Postfix, from userid 498) id 622E1C0A4AFC; Thu, 15 Dec 2016 14:16:51 +0100 (CET) X-Original-To: qemu-devel@nongnu.org Received: from ossman.lkpg.cendio.se (unknown [IPv6:2a00:801:107:4700:92b1:1cff:fe97:f932]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.cendio.se (Postfix) with ESMTPS id A9C1AC0A4AEC; Thu, 15 Dec 2016 14:16:47 +0100 (CET) From: Pierre Ossman To: Gerd Hoffmann , qemu-devel@nongnu.org Date: Thu, 15 Dec 2016 14:16:46 +0100 Message-Id: <3fcc534530370027118377dc24d4049a1cef590e.1481807806.git.ossman@cendio.se> X-Mailer: git-send-email 2.7.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 193.12.253.119 Subject: [Qemu-devel] [PATCH] vnc: track LED state separately X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Piggy-backing on the modifier state array made it difficult to send out updates at the proper times. So keep track of the LED state in a separate variable. This also moves the handling up a layer in to the VNC Display object since the state is global, and also makes sure the state is readily available directly when a client connects. Signed-off-by: Pierre Ossman --- ui/vnc.c | 56 +++++++++++++------------------------------------------- ui/vnc.h | 3 ++- 2 files changed, 15 insertions(+), 44 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 2c28a59..c449a7d 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1231,8 +1231,6 @@ void vnc_disconnect_finish(VncState *vs) vnc_update_server_surface(vs->vd); } - if (vs->vd->lock_key_sync) - qemu_remove_led_event_handler(vs->led); vnc_unlock_output(vs); qemu_mutex_destroy(&vs->output_mutex); @@ -1665,69 +1663,38 @@ static void press_key(VncState *vs, int keysym) qemu_input_event_send_key_delay(vs->vd->key_delay_ms); } -static int current_led_state(VncState *vs) -{ - int ledstate = 0; - - if (vs->modifiers_state[0x46]) { - ledstate |= QEMU_SCROLL_LOCK_LED; - } - if (vs->modifiers_state[0x45]) { - ledstate |= QEMU_NUM_LOCK_LED; - } - if (vs->modifiers_state[0x3a]) { - ledstate |= QEMU_CAPS_LOCK_LED; - } - - return ledstate; -} - static void vnc_led_state_change(VncState *vs) { - int ledstate = 0; - if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) { return; } - ledstate = current_led_state(vs); vnc_lock_output(vs); vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE); - vnc_write_u8(vs, ledstate); + vnc_write_u8(vs, vs->vd->ledstate); vnc_unlock_output(vs); vnc_flush(vs); } static void kbd_leds(void *opaque, int ledstate) { - VncState *vs = opaque; - int caps, num, scr; - bool has_changed = (ledstate != current_led_state(vs)); + VncDisplay *vd = opaque; + VncState *client; trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED), (ledstate & QEMU_NUM_LOCK_LED), (ledstate & QEMU_SCROLL_LOCK_LED)); - caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0; - num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0; - scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0; + if (ledstate != vd->ledstate) + return; - if (vs->modifiers_state[0x3a] != caps) { - vs->modifiers_state[0x3a] = caps; - } - if (vs->modifiers_state[0x45] != num) { - vs->modifiers_state[0x45] = num; - } - if (vs->modifiers_state[0x46] != scr) { - vs->modifiers_state[0x46] = scr; - } + vd->ledstate = ledstate; - /* Sending the current led state message to the client */ - if (has_changed) { - vnc_led_state_change(vs); + QTAILQ_FOREACH(client, &vd->clients, next) { + vnc_led_state_change(client); } } @@ -3083,8 +3050,6 @@ void vnc_start_protocol(VncState *vs) vnc_write(vs, "RFB 003.008\n", 12); vnc_flush(vs); vnc_read_when(vs, protocol_version, 12); - if (vs->vd->lock_key_sync) - vs->led = qemu_add_led_event_handler(kbd_leds, vs); vs->mouse_mode_notifier.notify = check_pointer_type_change; qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier); @@ -3191,6 +3156,8 @@ static void vnc_display_close(VncDisplay *vd) } g_free(vd->tlsaclname); vd->tlsaclname = NULL; + if (vd->lock_key_sync) + qemu_remove_led_event_handler(vd->led); } int vnc_display_password(const char *id, const char *password) @@ -3758,6 +3725,9 @@ void vnc_display_open(const char *id, Error **errp) } #endif vd->lock_key_sync = lock_key_sync; + if (lock_key_sync) + vd->led = qemu_add_led_event_handler(kbd_leds, vd); + vd->ledstate = 0; vd->key_delay_ms = key_delay_ms; device_id = qemu_opt_get(opts, "display"); diff --git a/ui/vnc.h b/ui/vnc.h index d20b154..d8c9de5 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -154,6 +154,8 @@ struct VncDisplay DisplayChangeListener dcl; kbd_layout_t *kbd_layout; int lock_key_sync; + QEMUPutLEDEntry *led; + int ledstate; int key_delay_ms; QemuMutex mutex; @@ -304,7 +306,6 @@ struct VncState size_t read_handler_expect; /* input */ uint8_t modifiers_state[256]; - QEMUPutLEDEntry *led; bool abort; QemuMutex output_mutex;