Merge pull request #2136 from bmiklautz/feat/kbd_indicators
Support for set keyboard indicators PDU
This commit is contained in:
commit
cda93be7dd
@ -51,6 +51,8 @@
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -85,6 +87,7 @@
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/print.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
#include "xf_rail.h"
|
||||
@ -707,6 +710,24 @@ static void xf_post_disconnect(freerdp *instance)
|
||||
xf_monitors_free(xfc, instance->settings);
|
||||
}
|
||||
|
||||
static void xf_play_sound(rdpContext* context, PLAY_SOUND_UPDATE* play_sound)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
XkbBell(xfc->display, None, 100, 0);
|
||||
}
|
||||
|
||||
void xf_check_extensions(xfContext *context)
|
||||
{
|
||||
int xkb_opcode, xkb_event, xkb_error;
|
||||
int xkb_major = XkbMajorVersion;
|
||||
int xkb_minor = XkbMinorVersion;
|
||||
if (XkbLibraryVersion( &xkb_major, &xkb_minor ) && XkbQueryExtension(context->display, &xkb_opcode, &xkb_event,
|
||||
&xkb_error, &xkb_major, &xkb_minor))
|
||||
{
|
||||
context->xkbAvailable = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback given to freerdp_connect() to process the pre-connect operations.
|
||||
* It will fill the rdp_freerdp structure (instance) with the appropriate options to use for the connection.
|
||||
@ -786,6 +807,8 @@ BOOL xf_pre_connect(freerdp* instance)
|
||||
_def_error_handler = XSetErrorHandler(_xf_error_handler);
|
||||
}
|
||||
|
||||
xf_check_extensions(xfc);
|
||||
|
||||
xfc->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
PubSub_SubscribeChannelConnected(instance->context->pubSub,
|
||||
@ -974,6 +997,8 @@ BOOL xf_post_connect(freerdp *instance)
|
||||
palette_cache_register_callbacks(instance->update);
|
||||
instance->update->BitmapUpdate = xf_gdi_bitmap_update;
|
||||
}
|
||||
instance->update->PlaySound = xf_play_sound;
|
||||
instance->update->SetKeyboardIndicators = xf_keyboard_set_indicators;
|
||||
|
||||
instance->context->rail = rail_new(instance->settings);
|
||||
rail_register_update_callbacks(instance->context->rail, instance->update);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
|
||||
@ -241,18 +242,17 @@ int xf_keyboard_read_keyboard_state(xfContext* xfc)
|
||||
return state;
|
||||
}
|
||||
|
||||
BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym)
|
||||
static int xf_keyboard_get_keymask(xfContext* xfc, int keysym)
|
||||
{
|
||||
int offset;
|
||||
int modifierpos, key, keysymMask = 0;
|
||||
KeyCode keycode = XKeysymToKeycode(xfc->display, keysym);
|
||||
|
||||
if (keycode == NoSymbol)
|
||||
return FALSE;
|
||||
return 0;
|
||||
|
||||
for (modifierpos = 0; modifierpos < 8; modifierpos++)
|
||||
{
|
||||
offset = xfc->modifierMap->max_keypermod * modifierpos;
|
||||
int offset = xfc->modifierMap->max_keypermod * modifierpos;
|
||||
|
||||
for (key = 0; key < xfc->modifierMap->max_keypermod; key++)
|
||||
{
|
||||
@ -262,10 +262,34 @@ BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym)
|
||||
}
|
||||
}
|
||||
}
|
||||
return keysymMask;
|
||||
}
|
||||
|
||||
BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym)
|
||||
{
|
||||
int keysymMask = xf_keyboard_get_keymask(xfc, keysym);
|
||||
|
||||
if (!keysymMask)
|
||||
return FALSE;
|
||||
|
||||
return (state & keysymMask) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static BOOL xf_keyboard_set_key_state(xfContext* xfc, BOOL on, int keysym)
|
||||
{
|
||||
int keysymMask;
|
||||
|
||||
if (!xfc->xkbAvailable)
|
||||
return FALSE;
|
||||
|
||||
keysymMask = xf_keyboard_get_keymask(xfc, keysym);
|
||||
if (!keysymMask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return XkbLockModifiers(xfc->display, XkbUseCoreKbd, keysymMask, on ? keysymMask : 0);
|
||||
}
|
||||
|
||||
UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc)
|
||||
{
|
||||
int state;
|
||||
@ -568,3 +592,12 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void xf_keyboard_set_indicators(rdpContext* context, UINT16 led_flags)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_SCROLL_LOCK, XK_Scroll_Lock);
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_NUM_LOCK, XK_Num_Lock);
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_CAPS_LOCK, XK_Caps_Lock);
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_KANA_LOCK, XK_Kana_Lock);
|
||||
}
|
||||
|
@ -57,5 +57,6 @@ BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym);
|
||||
UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc);
|
||||
void xf_keyboard_focus_in(xfContext* xfc);
|
||||
BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym);
|
||||
void xf_keyboard_set_indicators(rdpContext* context, UINT16 led_flags);
|
||||
|
||||
#endif /* __XF_KEYBOARD_H */
|
||||
|
@ -187,6 +187,8 @@ struct xf_context
|
||||
RdpeiClientContext* rdpei;
|
||||
RdpgfxClientContext* gfx;
|
||||
EncomspClientContext* encomsp;
|
||||
|
||||
BOOL xkbAvailable;
|
||||
};
|
||||
|
||||
void xf_create_window(xfContext* xfc);
|
||||
|
@ -54,6 +54,7 @@
|
||||
#define Update_SurfaceBits 12
|
||||
#define Update_SurfaceFrameMarker 13
|
||||
#define Update_SurfaceFrameAcknowledge 14
|
||||
#define Update_SetKeyboardIndicators 15
|
||||
|
||||
#define FREERDP_UPDATE_BEGIN_PAINT MakeMessageId(Update, BeginPaint)
|
||||
#define FREERDP_UPDATE_ END_PAINT MakeMessageId(Update, EndPaint)
|
||||
@ -69,6 +70,7 @@
|
||||
#define FREERDP_UPDATE_SURFACE_BITS MakeMessageId(Update, SurfaceBits)
|
||||
#define FREERDP_UPDATE_SURFACE_FRAME_MARKER MakeMessageId(Update, SurfaceFrameMarker)
|
||||
#define FREERDP_UPDATE_SURFACE_FRAME_ACKNOWLEDGE MakeMessageId(Update, SurfaceFrameAcknowledge)
|
||||
#define FREERDP_UPDATE_SET_KEYBOARD_INDICATORS MakeMessageId(Update, SetKeyboardIndicators)
|
||||
|
||||
/* Primary Update */
|
||||
|
||||
|
@ -142,6 +142,7 @@ typedef void (*pDesktopResize)(rdpContext* context);
|
||||
typedef void (*pBitmapUpdate)(rdpContext* context, BITMAP_UPDATE* bitmap);
|
||||
typedef void (*pPalette)(rdpContext* context, PALETTE_UPDATE* palette);
|
||||
typedef void (*pPlaySound)(rdpContext* context, PLAY_SOUND_UPDATE* play_sound);
|
||||
typedef void (*pSetKeyboardIndicators)(rdpContext* context, UINT16 led_flags);
|
||||
|
||||
typedef void (*pRefreshRect)(rdpContext* context, BYTE count, RECTANGLE_16* areas);
|
||||
typedef void (*pSuppressOutput)(rdpContext* context, BYTE allow, RECTANGLE_16* area);
|
||||
@ -165,7 +166,8 @@ struct rdp_update
|
||||
pBitmapUpdate BitmapUpdate; /* 21 */
|
||||
pPalette Palette; /* 22 */
|
||||
pPlaySound PlaySound; /* 23 */
|
||||
UINT32 paddingB[32 - 24]; /* 24 */
|
||||
pSetKeyboardIndicators SetKeyboardIndicators; /* 24 */
|
||||
UINT32 paddingB[32 - 25]; /* 25 */
|
||||
|
||||
rdpPointerUpdate* pointer; /* 32 */
|
||||
rdpPrimaryUpdate* primary; /* 33 */
|
||||
|
@ -127,6 +127,12 @@ static void update_message_PlaySound(rdpContext* context, PLAY_SOUND_UPDATE* pla
|
||||
MakeMessageId(Update, PlaySound), (void*) wParam, NULL);
|
||||
}
|
||||
|
||||
static void update_message_SetKeyboardIndicators(rdpContext* context, UINT16 led_flags)
|
||||
{
|
||||
MessageQueue_Post(context->update->queue, (void*) context,
|
||||
MakeMessageId(Update, SetKeyboardIndicators), (void*)(size_t)led_flags, NULL);
|
||||
}
|
||||
|
||||
static void update_message_RefreshRect(rdpContext* context, BYTE count, RECTANGLE_16* areas)
|
||||
{
|
||||
RECTANGLE_16* lParam;
|
||||
@ -1061,6 +1067,7 @@ static int update_message_free_update_class(wMessage* msg, int type)
|
||||
break;
|
||||
|
||||
case Update_SurfaceFrameAcknowledge:
|
||||
case Update_SetKeyboardIndicators:
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1136,6 +1143,10 @@ static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage*
|
||||
IFCALL(proxy->SurfaceFrameAcknowledge, msg->context, (UINT32) (size_t) msg->wParam);
|
||||
break;
|
||||
|
||||
case Update_SetKeyboardIndicators:
|
||||
IFCALL(proxy->SetKeyboardIndicators, msg->context, (UINT16) (size_t) msg->wParam);
|
||||
break;
|
||||
|
||||
default:
|
||||
status = -1;
|
||||
break;
|
||||
@ -2006,6 +2017,7 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat
|
||||
message->BitmapUpdate = update->BitmapUpdate;
|
||||
message->Palette = update->Palette;
|
||||
message->PlaySound = update->PlaySound;
|
||||
message->SetKeyboardIndicators = update->SetKeyboardIndicators;
|
||||
message->RefreshRect = update->RefreshRect;
|
||||
message->SuppressOutput = update->SuppressOutput;
|
||||
message->SurfaceCommand = update->SurfaceCommand;
|
||||
@ -2021,6 +2033,7 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat
|
||||
update->BitmapUpdate = update_message_BitmapUpdate;
|
||||
update->Palette = update_message_Palette;
|
||||
update->PlaySound = update_message_PlaySound;
|
||||
update->SetKeyboardIndicators = update_message_SetKeyboardIndicators;
|
||||
update->RefreshRect = update_message_RefreshRect;
|
||||
update->SuppressOutput = update_message_SuppressOutput;
|
||||
update->SurfaceCommand = update_message_SurfaceCommand;
|
||||
|
@ -43,6 +43,7 @@ struct rdp_update_proxy
|
||||
pBitmapUpdate BitmapUpdate;
|
||||
pPalette Palette;
|
||||
pPlaySound PlaySound;
|
||||
pSetKeyboardIndicators SetKeyboardIndicators;
|
||||
pRefreshRect RefreshRect;
|
||||
pSuppressOutput SuppressOutput;
|
||||
pSurfaceCommand SurfaceCommand;
|
||||
|
@ -595,12 +595,16 @@ BOOL rdp_recv_server_set_keyboard_indicators_pdu(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
UINT16 unitId;
|
||||
UINT16 ledFlags;
|
||||
rdpContext* context = rdp->instance->context;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, unitId); /* unitId (2 bytes) */
|
||||
Stream_Read_UINT16(s, ledFlags); /* ledFlags (2 bytes) */
|
||||
|
||||
IFCALL(context->update->SetKeyboardIndicators, context, ledFlags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1612,6 +1612,18 @@ BOOL update_read_suppress_output(rdpUpdate* update, wStream* s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void update_send_set_keyboard_indicators(rdpContext* context, UINT16 led_flags)
|
||||
{
|
||||
wStream* s;
|
||||
rdpRdp* rdp = context->rdp;
|
||||
|
||||
s = rdp_data_pdu_init(rdp);
|
||||
Stream_Write_UINT16(s, 0); /* unitId should be 0 according to MS-RDPBCGR 2.2.8.2.1.1 */
|
||||
Stream_Write_UINT16(s, led_flags); /* ledFlags (2 bytes) */
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS, rdp->mcs->userId);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
void update_register_server_callbacks(rdpUpdate* update)
|
||||
{
|
||||
update->BeginPaint = update_begin_paint;
|
||||
@ -1625,6 +1637,7 @@ void update_register_server_callbacks(rdpUpdate* update)
|
||||
update->SurfaceCommand = update_send_surface_command;
|
||||
update->SurfaceFrameBits = update_send_surface_frame_bits;
|
||||
update->PlaySound = update_send_play_sound;
|
||||
update->SetKeyboardIndicators = update_send_set_keyboard_indicators;
|
||||
update->primary->DstBlt = update_send_dstblt;
|
||||
update->primary->PatBlt = update_send_patblt;
|
||||
update->primary->ScrBlt = update_send_scrblt;
|
||||
|
Loading…
Reference in New Issue
Block a user