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,6 +53,8 @@
#include "vnc_server.h" #include "vnc_server.h"
#ifdef CONFIG_NX_KBD
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
@ -61,6 +63,11 @@
#define LAST_PRTCHAR ASCII_TILDE #define LAST_PRTCHAR ASCII_TILDE
#define NPRTCHARS (ASCII_TILDE + ASCII_SPACE - 1) #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 * Private types
****************************************************************************/ ****************************************************************************/
@ -270,6 +277,126 @@ static bool g_modstate[NMODIFIERS];
* Private Functions * 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 * 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, void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
bool keydown) bool keydown)
{ {
#ifdef CONFIG_VNCSERVER_KBDENCODE
uint8_t buffer[4]
int nch;
#endif
int16_t keych; int16_t keych;
uint8_t ch;
int ret; int ret;
/* Check for modifier keys */ /* Check for modifier keys */
@ -364,6 +494,17 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
return; 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 */ /* Try to convert the keycode to an ASCII value */
keych = vnc_kbd_ascii((char)(keysym & 255)); 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 */ /* 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 /* If Shift Lock is selected, then the case of all printable
* should be reversed (unless the Shift key is also pressed) * characters should be reversed (unless the Shift key is also
* pressed)
*/ */
if (g_modstate[MOD_SHIFTLOCK]) 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 * characters should be reversed (unless the Shift key is also
* pressed) * pressed)
*/ */
else if (g_modstate[MOD_CAPSLOCK]) else if (g_modstate[MOD_CAPSLOCK] && ISALPHABETIC(keych))
{ {
if (g_modstate[MOD_SHIFT]) 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 /* If (1) only the Shift Key is pressed or (2) the Shift key is
* characters should be reversed. * 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]) 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 #ifdef CONFIG_VNCSERVER_KBDENCODE
/* Encode the normal character */ /* 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 */ /* 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, nch, buffer);
ret = nx_kbdin(session->handle, 1, &ch);
if (ret < 0) if (ret < 0)
{ {
gdbg("ERROR: nx_kbdin() failed: %d\n", ret) 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 #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); keych = vnc_kbd_lookup(g_modifiers, G_MODIFIERS_NELEM, keysym);
if (keych >= 0) 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 */ /* 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
} }
#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, void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
bool keydown); bool keydown);
#endif
#undef EXTERN #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus