vncserver: Support keyboard driver

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi 2022-07-10 00:13:09 +08:00 committed by Alan Carvalho de Assis
parent 5a45130d5c
commit 70c0672598
6 changed files with 193 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,6 +35,7 @@
#include <nuttx/video/rfb.h>
#include <nuttx/video/vnc.h>
#include <nuttx/input/touchscreen.h>
#include <nuttx/input/keyboard.h>
#include <nuttx/net/net.h>
#include <nuttx/semaphore.h>
@ -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
*