From 70c0672598b8ad13324fc7c5b666754b5a7aaad7 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Sun, 10 Jul 2022 00:13:09 +0800 Subject: [PATCH] vncserver: Support keyboard driver Signed-off-by: Huang Qi --- drivers/video/vnc/Kconfig | 16 ++++++++ drivers/video/vnc/Make.defs | 4 ++ drivers/video/vnc/vnc_fbdev.c | 68 +++++++++++++++++++++++--------- drivers/video/vnc/vnc_kbd.c | 61 ++++++++++++++++++++++++++++ drivers/video/vnc/vnc_receiver.c | 14 +++++++ drivers/video/vnc/vnc_server.h | 49 ++++++++++++++++++++++- 6 files changed, 193 insertions(+), 19 deletions(-) create mode 100644 drivers/video/vnc/vnc_kbd.c diff --git a/drivers/video/vnc/Kconfig b/drivers/video/vnc/Kconfig index b17e55fa8f..d722ce4076 100644 --- a/drivers/video/vnc/Kconfig +++ b/drivers/video/vnc/Kconfig @@ -155,6 +155,22 @@ config VNCSERVER_TOUCH_DEVNAME Touch device name prefix, final devi name is /dev/inputX by default, X is display number +config VNCSERVER_KBD + bool "Enable keyboard input" + default n + select INPUT + select INPUT_KEYBOARD + ---help--- + Use keyboard based input driver + +config VNCSERVER_KBD_DEVNAME + string "Keyboard input device name prefix" + default "/dev/kbd" + depends on VNCSERVER_KBD + ---help--- + Keyboard device name prefix, final devi name is /dev/kbdX by default, + X is display number + config VNCSERVER_INBUFFER_SIZE int "Input buffer size" default 80 diff --git a/drivers/video/vnc/Make.defs b/drivers/video/vnc/Make.defs index 1af4fb9e36..15951ef852 100644 --- a/drivers/video/vnc/Make.defs +++ b/drivers/video/vnc/Make.defs @@ -27,6 +27,10 @@ ifeq ($(CONFIG_VNCSERVER_TOUCH),y) CSRCS += vnc_touch.c endif +ifeq ($(CONFIG_VNCSERVER_KBD),y) +CSRCS += vnc_kbd.c +endif + DEPPATH += --dep-path video/vnc CFLAGS += ${shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)video$(DELIM)vnc} VPATH += :video/vnc diff --git a/drivers/video/vnc/vnc_fbdev.c b/drivers/video/vnc/vnc_fbdev.c index bed7ca1fc3..57050652fc 100644 --- a/drivers/video/vnc/vnc_fbdev.c +++ b/drivers/video/vnc/vnc_fbdev.c @@ -601,19 +601,41 @@ int up_fbinitialize(int display) { int ret; FAR struct vnc_session_s *session; -#ifdef CONFIG_VNCSERVER_TOUCH +#if defined (CONFIG_VNCSERVER_TOUCH) || defined (CONFIG_VNCSERVER_KBD) char devname[NAME_MAX]; #endif DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS); + /* Start the VNC server kernel thread. */ + + ret = vnc_start_server(display); + + if (ret < 0) + { + gerr("ERROR: vnc_start_server() failed: %d\n", ret); + return ret; + } + + /* Wait for the VNC server to be ready */ + + ret = vnc_wait_start(display); + + if (ret < 0) + { + gerr("ERROR: wait for vnc server start failed: %d\n", ret); + return ret; + } + /* Save the input callout function information in the session structure. */ session = g_vnc_sessions[display]; + session->arg = session; + #ifdef CONFIG_VNCSERVER_TOUCH - ret = snprintf(devname, NAME_MAX, CONFIG_VNCSERVER_TOUCH_DEVNAME "%d", - display); + ret = snprintf(devname, sizeof(devname), + CONFIG_VNCSERVER_TOUCH_DEVNAME "%d", display); if (ret < 0) { @@ -631,29 +653,27 @@ int up_fbinitialize(int display) session->mouseout = vnc_touch_event; #endif - session->arg = session; - /* Start the VNC server kernel thread. */ - - ret = vnc_start_server(display); +#ifdef CONFIG_VNCSERVER_KBD + ret = snprintf(devname, sizeof(devname), + CONFIG_VNCSERVER_KBD_DEVNAME "%d", display); if (ret < 0) { - gerr("ERROR: vnc_start_server() failed: %d\n", ret); -#ifdef CONFIG_VNCSERVER_TOUCH - vnc_touch_unregister(session, devname); -#endif + gerr("ERROR: Format vnc keyboard driver path failed.\n"); return ret; } - /* Wait for the VNC server to be ready */ - - ret = vnc_wait_start(display); + ret = vnc_kbd_register(devname, session); if (ret < 0) { - gerr("ERROR: wait for vnc server start failed: %d\n", ret); + gerr("ERROR: Initial vnc keyboard driver failed.\n"); + return ret; } + session->kbdout = vnc_kbd_event; +#endif + return ret; } @@ -831,7 +851,7 @@ FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane) void up_fbuninitialize(int display) { FAR struct vnc_session_s *session; -#ifdef CONFIG_VNCSERVER_TOUCH +#if defined(CONFIG_VNCSERVER_TOUCH) || defined (CONFIG_VNCSERVER_KBD) int ret; char devname[NAME_MAX]; #endif @@ -844,8 +864,8 @@ void up_fbuninitialize(int display) if (session != NULL) { #ifdef CONFIG_VNCSERVER_TOUCH - ret = snprintf(devname, NAME_MAX, CONFIG_VNCSERVER_TOUCH_DEVNAME "%d", - display); + ret = snprintf(devname, sizeof(devname), + CONFIG_VNCSERVER_TOUCH_DEVNAME "%d", display); if (ret < 0) { @@ -855,5 +875,17 @@ void up_fbuninitialize(int display) vnc_touch_unregister(session, devname); #endif + +#ifdef CONFIG_VNCSERVER_KBD + ret = snprintf(devname, sizeof(devname), + CONFIG_VNCSERVER_KBD_DEVNAME "%d", display); + if (ret < 0) + { + gerr("ERROR: Format vnc keyboard driver path failed.\n"); + return; + } + + vnc_kbd_unregister(session, devname); +#endif } } diff --git a/drivers/video/vnc/vnc_kbd.c b/drivers/video/vnc/vnc_kbd.c new file mode 100644 index 0000000000..3d26abf926 --- /dev/null +++ b/drivers/video/vnc/vnc_kbd.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * drivers/video/vnc/vnc_kbd.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "vnc_server.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_kbd_register + ****************************************************************************/ + +int vnc_kbd_register(FAR const char *devpath, + FAR struct vnc_session_s *session) +{ + return keyboard_register(&session->kbd, devpath, 1); +} + +/**************************************************************************** + * Name: vnc_kbd_register + ****************************************************************************/ + +void vnc_kbd_unregister(FAR struct vnc_session_s *session, + FAR const char *devpath) +{ + keyboard_unregister(&session->kbd, devpath); +} + +/**************************************************************************** + * Name: vnc_kbd_event + ****************************************************************************/ + +int vnc_kbd_event(FAR void *arg, uint8_t pressed, FAR const uint8_t *keycode) +{ + FAR struct vnc_session_s *session = arg; + keyboard_event(&session->kbd, rfb_getbe32(keycode), + pressed ? KEYBOARD_PRESS : KEYBOARD_RELEASE); + return OK; +} diff --git a/drivers/video/vnc/vnc_receiver.c b/drivers/video/vnc/vnc_receiver.c index 4fdd00ab08..5f0dd7d034 100644 --- a/drivers/video/vnc/vnc_receiver.c +++ b/drivers/video/vnc/vnc_receiver.c @@ -321,8 +321,22 @@ int vnc_receiver(FAR struct vnc_session_s *session) /* Inject the key press/release event into NX */ keyevent = (FAR struct rfb_keyevent_s *)session->inbuf; +#ifdef CONFIG_VNCSERVER_KBD + /* If uinput like virtual keyboard enabled, pass keycode to + * keyboard driver. + * + * This driver cannot be used with NX now, + * if vnc server works with NX, should not enable + * CONFIG_VNCSERVER_KBD. + */ + + session->kbdout(&session->kbd, keyevent->down, + (FAR const uint8_t *)keyevent->key); + +#else vnc_key_map(session, rfb_getbe32(keyevent->key), (bool)keyevent->down); +#endif } } break; diff --git a/drivers/video/vnc/vnc_server.h b/drivers/video/vnc/vnc_server.h index 88c25e19bb..b57357bc2b 100644 --- a/drivers/video/vnc/vnc_server.h +++ b/drivers/video/vnc/vnc_server.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -224,7 +225,11 @@ struct vnc_session_s FAR void *arg; /* Argument that accompanies the callouts */ #ifdef CONFIG_VNCSERVER_TOUCH - FAR struct touch_lowerhalf_s touch; /* Touch driver instance */ + struct touch_lowerhalf_s touch; /* Touch driver instance */ +#endif + +#ifdef CONFIG_VNCSERVER_KBD + struct keyboard_lowerhalf_s kbd; /* Keyboard driver instance */ #endif /* Updater information */ @@ -547,6 +552,48 @@ int vnc_touch_event(FAR void *arg, int16_t x, int16_t y, uint8_t buttons); #endif +#ifdef CONFIG_VNCSERVER_KBD + +/**************************************************************************** + * Name: vnc_kbd_register + * + * Description: + * Register keyboard device to fetch keyboard event from VNC client. + * + * Returned Value: + * Driver instance + * + ****************************************************************************/ + +int vnc_kbd_register(FAR const char *devpath, + FAR struct vnc_session_s *session); + +/**************************************************************************** + * Name: vnc_kbd_register + * + * Description: + * Unregister keyboard device. + * + ****************************************************************************/ + +void vnc_kbd_unregister(FAR struct vnc_session_s *session, + FAR const char *devpath); + +/**************************************************************************** + * Name: vnc_kbd_event + * + * Description: + * Report a keyboard event from vnc client. + * Same prototype with vnc_kbdout_t but different semantics + * (to pass raw keycode). + * + ****************************************************************************/ + +int vnc_kbd_event(FAR void *arg, uint8_t pressed, + FAR const uint8_t *keycode); + +#endif + /**************************************************************************** * Name: vnc_convert_rgbNN *