VNC: Add support for encoded special keys
This commit is contained in:
parent
074d5fdde6
commit
a9a006c94b
@ -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 */
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user