VNC: Add support for encoded special keys

This commit is contained in:
Gregory Nutt 2016-04-15 08:01:47 -06:00
parent 074d5fdde6
commit a9a006c94b
2 changed files with 193 additions and 18 deletions

View File

@ -53,13 +53,20 @@
#include "vnc_server.h"
#ifdef CONFIG_NX_KBD
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define FIRST_PRTCHAR ASCII_SPACE
#define LAST_PRTCHAR ASCII_TILDE
#define NPRTCHARS (ASCII_TILDE + ASCII_SPACE - 1)
#define FIRST_PRTCHAR ASCII_SPACE
#define LAST_PRTCHAR ASCII_TILDE
#define NPRTCHARS (ASCII_TILDE + ASCII_SPACE - 1)
#define ISPRINTABLE(c) ((c) >= FIRST_PRTCHAR && (c) <= LAST_PRTCHAR)
#define ISLOWERCASE(c) ((c) >= ASCII_a && (c) <= ASCII_z)
#define ISUPPERCASE(c) ((c) >= ASCII_A && (c) <= ASCII_Z)
#define ISALPHABETIC(c) (ISLOWERCASE(c) || ISUPPERCASE(c))
/****************************************************************************
* Private types
@ -270,6 +277,126 @@ static bool g_modstate[NMODIFIERS];
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_kbd_encode
*
* Description:
* Encode one escape sequence command into the proivded buffer.
*
* Input Parameters:
* buffer - The location to write the sequence
* keycode - The command to be added to the output stream.
* terminator - Escape sequence terminating character.
*
* Returned Value:
* Number of bytes written
*
****************************************************************************/
#ifdef CONFIG_VNCSERVER_KBDENCODE
static inline int vnc_kbd_encode(FAR uint8_t *buffer, uint8_t keycode,
uint8_t terminator)
{
*buffer++ = ASCII_ESC;
*buffer++ = ASCII_LBRACKET;
*buffer++ = keycode;
*buffer = terminator;
return 4;
}
#endif
/****************************************************************************
* Name: vnc_kbd_press
*
* Description:
* Indicates a normal key press event. Put one byte of normal keyboard
* data into the user provided buffer.
*
* Input Parameters:
* buffer - The location to write the sequence
* ch - The character to be added to the output stream.
*
* Returned Value:
* Number of bytes written
*
****************************************************************************/
#ifdef CONFIG_VNCSERVER_KBDENCODE
static inline void vnc_kbd_press(FAR uint8_t *buffer, uint8_t ch)
{
*buffer = ch;
return 1;
}
#endif
/****************************************************************************
* Name: vnc_kbd_release
*
* Description:
* Encode the release of a normal key.
*
* Input Parameters:
* buffer - The location to write the sequence
* ch - The character associated with the key that was releared.
*
* Returned Value:
* Number of bytes written
*
****************************************************************************/
#ifdef CONFIG_VNCSERVER_KBDENCODE
static inline void vnc_kbd_release(FAR uint8_t *buffer, uint8_t ch)
{
return vnc_kbd_encode(buffer, ch, ('a' + KBD_RELEASE));
}
#endif
/****************************************************************************
* Name: vnc_kbd_specpress
*
* Description:
* Denotes a special key press event. Put one special keyboard command
* into the user provided buffer.
*
* Input Parameters:
* buffer - The location to write the sequence
* keycode - The command to be added to the output stream.
*
* Returned Value:
* Number of bytes written
*
****************************************************************************/
#ifdef CONFIG_VNCSERVER_KBDENCODE
static inline void vnc_kbd_specpress(FAR uint8_t *buffer, uint8_t keycode)
{
return vnc_kbd_encode(buffer, keycode, stream, ('a' + KBD_SPECPRESS));
}
#endif
/****************************************************************************
* Name: vnc_kbd_specrel
*
* Description:
* Denotes a special key release event. Put one special keyboard
* command into the user provided buffer.
*
* Input Parameters:
* buffer - The location to write the sequence
* keycode - The command to be added to the output stream.
*
* Returned Value:
* Number of bytes written
*
****************************************************************************/
#ifdef CONFIG_VNCSERVER_KBDENCODE
static inline void vnc_kbd_specrel(FAR uint8_t *buffer, uint8_t keycode)
{
return vnc_kbd_encode(buffer, keycode, stream, ('a' + KBD_SPECREL));
}
#endif
/****************************************************************************
* Name: vnc_kbd_lookup
*
@ -351,8 +478,11 @@ static int vnc_kbd_ascii(uint32_t keysym)
void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
bool keydown)
{
#ifdef CONFIG_VNCSERVER_KBDENCODE
uint8_t buffer[4]
int nch;
#endif
int16_t keych;
uint8_t ch;
int ret;
/* Check for modifier keys */
@ -364,6 +494,17 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
return;
}
#ifndef CONFIG_VNCSERVER_KBDENCODE
/* If we are not encoding key presses, then we have to ignore key release
* events.
*/
if (!keydown)
{
return;
}
#endif
/* Try to convert the keycode to an ASCII value */
keych = vnc_kbd_ascii((char)(keysym & 255));
@ -382,10 +523,11 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
/* Other modifiers apply only to printable characters */
else if (keych >= FIRST_PRTCHAR && keych <= LAST_PRTCHAR)
else if (ISPRINTABLE(keych))
{
/* If Shift Lock is selected, then the case of all characters
* should be reversed (unless the Shift key is also pressed)
/* If Shift Lock is selected, then the case of all printable
* characters should be reversed (unless the Shift key is also
* pressed)
*/
if (g_modstate[MOD_SHIFTLOCK])
@ -398,12 +540,12 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
}
}
/* If Caps Lock is selected, then the case of printable
/* If Caps Lock is selected, then the case of alphabetic
* characters should be reversed (unless the Shift key is also
* pressed)
*/
else if (g_modstate[MOD_CAPSLOCK])
else if (g_modstate[MOD_CAPSLOCK] && ISALPHABETIC(keych))
{
if (g_modstate[MOD_SHIFT])
{
@ -413,8 +555,9 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
}
}
/* If only the Shift Key is pressed, then the case of all
* characters should be reversed.
/* If (1) only the Shift Key is pressed or (2) the Shift key is
* pressed with Caps Lock, but the character is not alphabetic,
* then the case of all printable characters should be reversed.
*/
else if (g_modstate[MOD_SHIFT])
@ -425,19 +568,31 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
#ifdef CONFIG_VNCSERVER_KBDENCODE
/* Encode the normal character */
#warning Missing logic
if (keydown)
{
nch = vnc_kbd_press(buffer, keych);
}
else
{
nch = vnc_kbd_release(buffer, keych);
}
/* Inject the normal character sequence into NX */
#warning Missing logic
#else
/* Inject the key press into NX */
ch = (uint8_t)keych;
ret = nx_kbdin(session->handle, 1, &ch);
ret = nx_kbdin(session->handle, nch, buffer);
if (ret < 0)
{
gdbg("ERROR: nx_kbdin() failed: %d\n", ret)
}
#else
/* Inject the single key press into NX */
ret = nx_kbdchin(session->handle,(uint8_t)keych);
if (ret < 0)
{
gdbg("ERROR: nx_kbdchin() failed: %d\n", ret)
}
#endif
}
@ -451,9 +606,27 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
keych = vnc_kbd_lookup(g_modifiers, G_MODIFIERS_NELEM, keysym);
if (keych >= 0)
{
/* Encode the speical character */
if (keydown)
{
nch = vnc_kbd_specpress(buffer, keych);
}
else
{
nch = vnc_kbd_specrel(buffer, keych);
}
/* Inject the special character sequence into NX */
#warning Missing logic
ret = nx_kbdin(session->handle, nch, buffer);
if (ret < 0)
{
gdbg("ERROR: nx_kbdin() failed: %d\n", ret)
}
}
}
#endif
}
#endif /* CONFIG_NX_KBD */

View File

@ -244,8 +244,10 @@ FAR struct vnc_session_s *vnc_find_session(int display);
*
****************************************************************************/
#ifdef CONFIG_NX_KBD
void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
bool keydown);
#endif
#undef EXTERN
#ifdef __cplusplus