6a3c2aded6
* Simplify EINTR/ECANCEL error handling 1. Add semaphore uninterruptible wait function 2 .Replace semaphore wait loop with a single uninterruptible wait 3. Replace all sem_xxx to nxsem_xxx * Unify the void cast usage 1. Remove void cast for function because many place ignore the returned value witout cast 2. Replace void cast for variable with UNUSED macro
655 lines
20 KiB
C
655 lines
20 KiB
C
/****************************************************************************
|
||
* graphics/vnc/vnc_keymap.c
|
||
*
|
||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without
|
||
* modification, are permitted provided that the following conditions
|
||
* are met:
|
||
*
|
||
* 1. Redistributions of source code must retain the above copyright
|
||
* notice, this list of conditions and the following disclaimer.
|
||
* 2. Redistributions in binary form must reproduce the above copyright
|
||
* notice, this list of conditions and the following disclaimer in
|
||
* the documentation and/or other materials provided with the
|
||
* distribution.
|
||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||
* used to endorse or promote products derived from this software
|
||
* without specific prior written permission.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
* POSSIBILITY OF SUCH DAMAGE.
|
||
*
|
||
****************************************************************************/
|
||
|
||
/****************************************************************************
|
||
* Included Files
|
||
****************************************************************************/
|
||
|
||
#include <nuttx/config.h>
|
||
|
||
#include <stdint.h>
|
||
#include <errno.h>
|
||
|
||
#include <nuttx/ascii.h>
|
||
|
||
#define XK_MISCELLANY 1 /* Select X11 character set */
|
||
#define XK_LATIN1 1
|
||
#define XK_XKB_KEYS 1
|
||
|
||
#include <nuttx/nx/nx.h>
|
||
#include <nuttx/video/vnc.h>
|
||
#include <nuttx/input/x11_keysymdef.h>
|
||
#include <nuttx/input/kbd_codec.h>
|
||
|
||
#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 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
|
||
****************************************************************************/
|
||
|
||
enum vnc_modifier_e
|
||
{
|
||
MOD_SHIFT = 0, /* Left or right shift key */
|
||
MOD_CONTROL, /* Left or right control key */
|
||
MOD_ALT, /* Alt key */
|
||
MOD_CAPSLOCK, /* Caps lock */
|
||
MOD_SHIFTLOCK, /* Shift lock */
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
MOD_SCROLLLOCK, /* Scroll lock */
|
||
MOD_NUMLOCK, /* Num lock */
|
||
#endif
|
||
NMODIFIERS
|
||
};
|
||
|
||
struct vnc_keymap_s
|
||
{
|
||
uint16_t nxcode;
|
||
uint16_t x11code;
|
||
};
|
||
|
||
/****************************************************************************
|
||
* Private Data
|
||
****************************************************************************/
|
||
|
||
/* Special key modifiers */
|
||
|
||
static const struct vnc_keymap_s g_modifiers[] =
|
||
{
|
||
{MOD_SHIFT, XK_Shift_L},
|
||
{MOD_SHIFT, XK_Shift_R},
|
||
{MOD_CONTROL, XK_Control_L},
|
||
{MOD_CONTROL, XK_Control_R},
|
||
{MOD_ALT, XK_Alt_L},
|
||
{MOD_ALT, XK_Alt_R},
|
||
{MOD_CAPSLOCK, XK_Caps_Lock},
|
||
{MOD_SHIFTLOCK, XK_Shift_Lock},
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
{MOD_SCROLLLOCK, XK_Scroll_Lock},
|
||
{MOD_NUMLOCK, XK_Num_Lock},
|
||
#endif
|
||
};
|
||
|
||
#define G_MODIFIERS_NELEM (sizeof(g_modifiers) / sizeof(struct vnc_keymap_s))
|
||
|
||
/* Map special mappings for X11 codes to ASCII characters */
|
||
|
||
static const struct vnc_keymap_s g_asciimap[] =
|
||
{
|
||
/* Control characters */
|
||
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
{ASCII_BS, XK_BackSpace},
|
||
#endif
|
||
{ASCII_TAB, XK_Tab},
|
||
{ASCII_LF, XK_Linefeed},
|
||
{ASCII_CR, XK_Return},
|
||
{ASCII_ESC, XK_Escape},
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
{ASCII_DEL, XK_Delete},
|
||
#endif
|
||
|
||
/* Alternative encodings */
|
||
|
||
{'`', XK_dead_grave},
|
||
{'<EFBFBD>', XK_dead_acute},
|
||
{ASCII_TILDE, XK_dead_tilde},
|
||
{ASCII_CARET, XK_dead_circumflex},
|
||
|
||
/* Keypad aliases */
|
||
|
||
{ASCII_0, XK_KP_0},
|
||
{ASCII_1, XK_KP_1},
|
||
{ASCII_2, XK_KP_2},
|
||
{ASCII_3, XK_KP_3},
|
||
{ASCII_4, XK_KP_4},
|
||
{ASCII_5, XK_KP_5},
|
||
{ASCII_6, XK_KP_6},
|
||
{ASCII_7, XK_KP_7},
|
||
{ASCII_8, XK_KP_8},
|
||
{ASCII_9, XK_KP_9},
|
||
|
||
{ASCII_ASTERISK, XK_KP_Multiply},
|
||
{ASCII_PLUS, XK_KP_Add},
|
||
{ASCII_COMMA, XK_KP_Separator},
|
||
{ASCII_HYPHEN, XK_KP_Subtract},
|
||
{ASCII_PERIOD, XK_KP_Decimal},
|
||
{ASCII_DIVIDE, XK_KP_Divide},
|
||
|
||
{ASCII_SPACE, XK_KP_Space},
|
||
{ASCII_TAB, XK_KP_Tab},
|
||
{ASCII_CR, XK_KP_Enter}
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
, {ASCII_DEL, XK_KP_Delete}
|
||
#endif
|
||
};
|
||
|
||
#define G_ASCIIMAP_NELEM (sizeof(g_asciimap) / sizeof(struct vnc_keymap_s))
|
||
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
static const struct vnc_keymap_s g_cursor[] =
|
||
{
|
||
{KEYCODE_BACKDEL, XK_BackSpace},
|
||
{KEYCODE_FWDDEL, XK_Delete},
|
||
{KEYCODE_FWDDEL, XK_KP_Delete},
|
||
{KEYCODE_HOME, XK_Home},
|
||
{KEYCODE_HOME, XK_KP_Home},
|
||
{KEYCODE_END, XK_End},
|
||
{KEYCODE_END, XK_KP_End},
|
||
{KEYCODE_LEFT, XK_Left},
|
||
{KEYCODE_LEFT, XK_KP_Left},
|
||
{KEYCODE_RIGHT, XK_Right},
|
||
{KEYCODE_RIGHT, XK_KP_Right},
|
||
{KEYCODE_UP, XK_Up},
|
||
{KEYCODE_UP, XK_KP_Up},
|
||
{KEYCODE_DOWN, XK_Down},
|
||
{KEYCODE_DOWN, XK_KP_Down},
|
||
{KEYCODE_PAGEUP, XK_Page_Up},
|
||
{KEYCODE_PAGEUP, XK_KP_Prior},
|
||
{KEYCODE_PAGEUP, XK_KP_Page_Up},
|
||
{KEYCODE_PAGEDOWN, XK_Page_Down},
|
||
{KEYCODE_PAGEDOWN, XK_KP_Next},
|
||
{KEYCODE_PAGEDOWN, XK_KP_Page_Down},
|
||
{KEYCODE_INSERT, XK_Insert},
|
||
{KEYCODE_INSERT, XK_KP_Insert},
|
||
|
||
{KEYCODE_SELECT, XK_Select},
|
||
{KEYCODE_EXECUTE, XK_Execute},
|
||
{KEYCODE_HELP, XK_Help},
|
||
{KEYCODE_MENU, XK_Alt_L},
|
||
{KEYCODE_MENU, XK_Alt_R},
|
||
{KEYCODE_PAUSE, XK_Pause},
|
||
{KEYCODE_PRTSCRN, XK_Print},
|
||
{KEYCODE_CLEAR, XK_Clear},
|
||
{MOD_SCROLLLOCK, XK_Scroll_Lock},
|
||
{MOD_NUMLOCK, XK_Num_Lock},
|
||
|
||
{KEYCODE_F1, XK_KP_F1},
|
||
{KEYCODE_F1, XK_F1},
|
||
{KEYCODE_F2, XK_KP_F2},
|
||
{KEYCODE_F2, XK_F2},
|
||
{KEYCODE_F3, XK_KP_F3},
|
||
{KEYCODE_F3, XK_F3},
|
||
{KEYCODE_F4, XK_KP_F4},
|
||
{KEYCODE_F4, XK_F4},
|
||
{KEYCODE_F5, XK_F5},
|
||
{KEYCODE_F6, XK_F6},
|
||
{KEYCODE_F7, XK_F7},
|
||
{KEYCODE_F8, XK_F8},
|
||
{KEYCODE_F9, XK_F9},
|
||
{KEYCODE_F10, XK_F10},
|
||
{KEYCODE_F11, XK_F11},
|
||
{KEYCODE_F12, XK_F12},
|
||
{KEYCODE_F13, XK_F13},
|
||
{KEYCODE_F14, XK_F14},
|
||
{KEYCODE_F15, XK_F15},
|
||
{KEYCODE_F16, XK_F16},
|
||
{KEYCODE_F17, XK_F17},
|
||
{KEYCODE_F18, XK_F18},
|
||
{KEYCODE_F19, XK_F19},
|
||
{KEYCODE_F20, XK_F20},
|
||
{KEYCODE_F21, XK_F21},
|
||
{KEYCODE_F22, XK_F22},
|
||
{KEYCODE_F23, XK_F23},
|
||
{KEYCODE_F24, XK_F24},
|
||
};
|
||
#endif
|
||
|
||
/* Changes the case of a character. Based on US keyboard layout */
|
||
|
||
static const uint8_t g_caseswap[NPRTCHARS] =
|
||
{
|
||
ASCII_SPACE, ASCII_1, ASCII_RSQUOTE, ASCII_3, /* ! " # */
|
||
ASCII_4, ASCII_5, ASCII_7, ASCII_QUOTE, /* $ % & ' */
|
||
ASCII_9, ASCII_0, ASCII_8, ASCII_EQUAL, /* ( ) * + */
|
||
ASCII_LT, ASCII_UNDERSCORE, ASCII_GT, ASCII_QUESTION, /* , - . / */
|
||
ASCII_RPAREN, ASCII_EXCLAM, ASCII_AT, ASCII_NUMBER, /* 0 1 2 3 */
|
||
ASCII_DOLLAR, ASCII_PERCENT, ASCII_CIRCUMFLEX, ASCII_AMPERSAND, /* 4 5 6 7 */
|
||
ASCII_ASTERISK, ASCII_LPAREN, ASCII_SEMICOLON, ASCII_COLON, /* 8 9 : ; */
|
||
ASCII_COMMA, ASCII_PLUS, ASCII_PERIOD, ASCII_SLASH, /* < = > ? */
|
||
ASCII_2, ASCII_a, ASCII_b, ASCII_c, /* @ A B C */
|
||
ASCII_d, ASCII_e, ASCII_f, ASCII_g, /* D E F G */
|
||
ASCII_h, ASCII_i, ASCII_j, ASCII_k, /* H I J K */
|
||
ASCII_l, ASCII_m, ASCII_n, ASCII_o, /* L M N O */
|
||
ASCII_p, ASCII_q, ASCII_r, ASCII_s, /* P Q R S */
|
||
ASCII_t, ASCII_u, ASCII_v, ASCII_v, /* T U V W */
|
||
ASCII_x, ASCII_y, ASCII_z, ASCII_LBRACE, /* X Y Z [ */
|
||
ASCII_VERTBAR, ASCII_RBRACE, ASCII_6, ASCII_HYPHEN, /* \ ] ^ _ */
|
||
ASCII_TILDE, ASCII_A, ASCII_B, ASCII_C, /* ' a b c */
|
||
ASCII_D, ASCII_E, ASCII_F, ASCII_G, /* c e f g */
|
||
ASCII_H, ASCII_I, ASCII_J, ASCII_K, /* h i j k */
|
||
ASCII_L, ASCII_M, ASCII_N, ASCII_O, /* l m n o */
|
||
ASCII_P, ASCII_Q, ASCII_R, ASCII_S, /* p q r s */
|
||
ASCII_T, ASCII_U, ASCII_V, ASCII_W, /* t u v w */
|
||
ASCII_X, ASCII_Y, ASCII_Z, ASCII_LBRACKET, /* x y z { */
|
||
ASCII_BACKSLASH, ASCII_RBRACKET, ASCII_RSQUOTE, /* | } ~ */
|
||
};
|
||
|
||
/* State of each modifier */
|
||
|
||
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
|
||
*
|
||
* Description:
|
||
* Attempt to map the X11 keycode by searching in a lookup table.
|
||
*
|
||
****************************************************************************/
|
||
|
||
static int vnc_kbd_lookup(FAR const struct vnc_keymap_s *table,
|
||
unsigned int nelem, uint16_t keysym)
|
||
{
|
||
int i;
|
||
|
||
/* First just try to map the virtual keycode using our lookup-table */
|
||
|
||
for (i = 0; i < nelem; i++)
|
||
{
|
||
if (table[i].x11code == keysym)
|
||
{
|
||
/* We have a match */
|
||
|
||
return (int)table[i].nxcode;
|
||
}
|
||
}
|
||
|
||
/* No match */
|
||
|
||
return -EINVAL;
|
||
}
|
||
|
||
/****************************************************************************
|
||
* Name: vnc_kbd_ascii
|
||
*
|
||
* Description:
|
||
* Attempt to map the X11 keycode into the corresponding ASCII code.
|
||
*
|
||
****************************************************************************/
|
||
|
||
static int vnc_kbd_ascii(uint16_t keysym)
|
||
{
|
||
/* ISO/IEC 8859-1 Latin1 matches C ASCII in this range: */
|
||
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
if (keysym >= ASCII_SPACE && keysym < ASCII_DEL)
|
||
#else
|
||
if (keysym >= ASCII_SPACE && keysym <= ASCII_DEL)
|
||
#endif
|
||
{
|
||
return (int)keysym;
|
||
}
|
||
|
||
/* Perform a lookup to handler some special cases */
|
||
|
||
return vnc_kbd_lookup(g_asciimap, G_ASCIIMAP_NELEM, keysym);
|
||
}
|
||
|
||
/****************************************************************************
|
||
* Public Functions
|
||
****************************************************************************/
|
||
|
||
/****************************************************************************
|
||
* Name: vnc_key_map
|
||
*
|
||
* Description:
|
||
* Map the receive X11 keysym into something understood by NuttX and route
|
||
* that through NX to the appropriate window.
|
||
*
|
||
* Input Parameters:
|
||
* session - An instance of the session structure allocated by
|
||
* vnc_create_session().
|
||
* keysym - The X11 keysym value (see include/nuttx/inputx11_keysymdef)
|
||
* keydown - True: Key pressed; False: Key released
|
||
*
|
||
* Returned Value:
|
||
* None
|
||
*
|
||
****************************************************************************/
|
||
|
||
void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym,
|
||
bool keydown)
|
||
{
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
uint8_t buffer[4]
|
||
int nch;
|
||
#else
|
||
uint8_t buffer;
|
||
#endif
|
||
int16_t keych;
|
||
|
||
/* Check for modifier keys */
|
||
|
||
keych = vnc_kbd_lookup(g_modifiers, G_MODIFIERS_NELEM, keysym);
|
||
if (keych >= 0)
|
||
{
|
||
g_modstate[keych] = keydown;
|
||
return;
|
||
}
|
||
|
||
#ifndef CONFIG_VNCSERVER_KBDENCODE
|
||
/* If we are not encoding key presses, then we have to ignore key release
|
||
* events.
|
||
*/
|
||
|
||
if (!keydown)
|
||
{
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
/* If no external keyboard input handler has been provided, then we have to drop the keyboard input.
|
||
*/
|
||
|
||
if (session->kbdout == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
/* Try to convert the keycode to an ASCII value */
|
||
|
||
keych = vnc_kbd_ascii((char)(keysym & 255));
|
||
if (keych >= 0)
|
||
{
|
||
/* It is a simple ASCII-mappable LATIN1 character. Now we need
|
||
* to apply any modifiers.
|
||
*/
|
||
|
||
if (g_modstate[MOD_CONTROL])
|
||
{
|
||
/* Make into a control character */
|
||
|
||
keych &= 0x1f;
|
||
}
|
||
|
||
/* Other modifiers apply only to printable characters */
|
||
|
||
else if (ISPRINTABLE(keych))
|
||
{
|
||
/* 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])
|
||
{
|
||
if (g_modstate[MOD_SHIFT])
|
||
{
|
||
/* Swap case */
|
||
|
||
keych = g_caseswap[keych];
|
||
}
|
||
}
|
||
|
||
/* 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] && ISALPHABETIC(keych))
|
||
{
|
||
if (g_modstate[MOD_SHIFT])
|
||
{
|
||
/* Swap case */
|
||
|
||
keych = g_caseswap[keych];
|
||
}
|
||
}
|
||
|
||
/* 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])
|
||
{
|
||
keych = g_caseswap[keych];
|
||
}
|
||
}
|
||
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
/* Encode the normal character */
|
||
|
||
if (keydown)
|
||
{
|
||
nch = vnc_kbd_press(buffer, keych);
|
||
}
|
||
else
|
||
{
|
||
nch = vnc_kbd_release(buffer, keych);
|
||
}
|
||
|
||
/* Inject the normal character sequence into NX */
|
||
|
||
session->kbdout(session->arg, nch, buffer);
|
||
#else
|
||
/* Inject the single key press into NX */
|
||
|
||
buffer = (uint8_t)keych;
|
||
session->kbdout(session->arg, 1, &buffer);
|
||
#endif
|
||
}
|
||
|
||
/* Not mappable to an ASCII LATIN1 character */
|
||
|
||
#ifdef CONFIG_VNCSERVER_KBDENCODE
|
||
else
|
||
{
|
||
/* Lookup cursor movement/screen control keysyms */
|
||
|
||
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 */
|
||
|
||
session->kbdout(session->arg, nch, buffer);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/****************************************************************************
|
||
* Name: vnc_kbdout
|
||
*
|
||
* Description:
|
||
* This is the default keyboard callout function. This is simply wrappers around nx_kdbout(), respectively. When configured using vnc_fbinitialize(), the 'arg' must be the correct NXHANDLE value.
|
||
*
|
||
* Input Parameters:
|
||
* arg - The NXHANDLE from the NX graphics subsystem
|
||
* nch - Number of characters
|
||
* ch - An array of input characters.
|
||
*
|
||
* Returned Value:
|
||
* None
|
||
*
|
||
****************************************************************************/
|
||
|
||
void vnc_kbdout(FAR void *arg, uint8_t nch, FAR const uint8_t *ch)
|
||
{
|
||
DEBUGASSERT(arg != NULL);
|
||
nx_kbdin((NXHANDLE)arg, nch, ch);
|
||
}
|
||
|
||
#endif /* CONFIG_NX_KBD */
|