mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 08:54:38 +09:00
Merge branch 'xkeys' of github.com:awakecoding/FreeRDP
This commit is contained in:
@@ -868,7 +868,7 @@ BOOL xf_pre_connect(freerdp* instance)
|
||||
xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False);
|
||||
xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False);
|
||||
|
||||
xf_kbd_init(xfc);
|
||||
xf_keyboard_init(xfc);
|
||||
|
||||
xfc->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA);
|
||||
|
||||
@@ -972,10 +972,10 @@ BOOL xf_post_connect(freerdp* instance)
|
||||
|
||||
ZeroMemory(&gcv, sizeof(gcv));
|
||||
|
||||
if (xfc->modifier_map)
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
if (xfc->modifierMap)
|
||||
XFreeModifiermap(xfc->modifierMap);
|
||||
|
||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
||||
xfc->modifierMap = XGetModifierMapping(xfc->display);
|
||||
|
||||
xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv);
|
||||
xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, xfc->width, xfc->height, xfc->depth);
|
||||
@@ -1161,11 +1161,7 @@ void xf_window_free(xfContext* xfc)
|
||||
{
|
||||
rdpContext* context = (rdpContext*) xfc;
|
||||
|
||||
if (xfc->modifier_map)
|
||||
{
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
xfc->modifier_map = NULL;
|
||||
}
|
||||
xf_keyboard_free(xfc);
|
||||
|
||||
if (xfc->gc)
|
||||
{
|
||||
@@ -1515,8 +1511,8 @@ void* xf_thread(void* param)
|
||||
*/
|
||||
if (freerdp_focus_required(instance))
|
||||
{
|
||||
xf_kbd_focus_in(xfc);
|
||||
xf_kbd_focus_in(xfc);
|
||||
xf_keyboard_focus_in(xfc);
|
||||
xf_keyboard_focus_in(xfc);
|
||||
}
|
||||
|
||||
if (!async_transport)
|
||||
|
||||
@@ -87,6 +87,99 @@ const char* const X11_EVENT_STRINGS[] =
|
||||
#define DEBUG_X11_LMS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
int xf_event_action_script_init(xfContext* xfc)
|
||||
{
|
||||
int exitCode;
|
||||
char* xevent;
|
||||
FILE* actionScript;
|
||||
char buffer[1024] = { 0 };
|
||||
char command[1024] = { 0 };
|
||||
|
||||
xfc->xevents = ArrayList_New(TRUE);
|
||||
ArrayList_Object(xfc->xevents)->fnObjectFree = free;
|
||||
|
||||
sprintf_s(command, sizeof(command), "%s xevent", xfc->actionScript);
|
||||
|
||||
actionScript = popen(command, "r");
|
||||
|
||||
if (actionScript < 0)
|
||||
return -1;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), actionScript) != NULL)
|
||||
{
|
||||
strtok(buffer, "\n");
|
||||
xevent = _strdup(buffer);
|
||||
ArrayList_Add(xfc->xevents, xevent);
|
||||
}
|
||||
|
||||
exitCode = pclose(actionScript);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xf_event_action_script_free(xfContext* xfc)
|
||||
{
|
||||
if (xfc->xevents)
|
||||
{
|
||||
ArrayList_Free(xfc->xevents);
|
||||
xfc->xevents = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int xf_event_execute_action_script(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
int index;
|
||||
int count;
|
||||
char* name;
|
||||
int exitCode;
|
||||
FILE* actionScript;
|
||||
BOOL match = FALSE;
|
||||
const char* xeventName;
|
||||
char buffer[1024] = { 0 };
|
||||
char command[1024] = { 0 };
|
||||
|
||||
if (!xfc->actionScript)
|
||||
return 1;
|
||||
|
||||
if (event->type > (sizeof(X11_EVENT_STRINGS) / sizeof(const char*)))
|
||||
return 1;
|
||||
|
||||
xeventName = X11_EVENT_STRINGS[event->type];
|
||||
|
||||
count = ArrayList_Count(xfc->xevents);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
name = (char*) ArrayList_GetItem(xfc->xevents, index);
|
||||
|
||||
if (_stricmp(name, xeventName) == 0)
|
||||
{
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
return 1;
|
||||
|
||||
sprintf_s(command, sizeof(command), "%s xevent %s %d",
|
||||
xfc->actionScript, xeventName, (int) xfc->window->handle);
|
||||
|
||||
actionScript = popen(command, "r");
|
||||
|
||||
if (actionScript < 0)
|
||||
return -1;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), actionScript) != NULL)
|
||||
{
|
||||
strtok(buffer, "\n");
|
||||
}
|
||||
|
||||
exitCode = pclose(actionScript);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
int x, y;
|
||||
@@ -395,34 +488,28 @@ static BOOL xf_event_KeyPress(xfContext* xfc, XEvent* event, BOOL app)
|
||||
|
||||
XLookupString((XKeyEvent*) event, str, sizeof(str), &keysym, NULL);
|
||||
|
||||
xf_kbd_set_keypress(xfc, event->xkey.keycode, keysym);
|
||||
|
||||
if (xfc->fullscreen_toggle && xf_kbd_handle_special_keys(xfc, keysym))
|
||||
return TRUE;
|
||||
|
||||
xf_kbd_send_key(xfc, TRUE, event->xkey.keycode);
|
||||
xf_keyboard_key_press(xfc, event->xkey.keycode, keysym);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_event_KeyRelease(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
XEvent next_event;
|
||||
XEvent nextEvent;
|
||||
|
||||
if (XPending(xfc->display))
|
||||
{
|
||||
ZeroMemory(&next_event, sizeof(next_event));
|
||||
XPeekEvent(xfc->display, &next_event);
|
||||
ZeroMemory(&nextEvent, sizeof(nextEvent));
|
||||
XPeekEvent(xfc->display, &nextEvent);
|
||||
|
||||
if (next_event.type == KeyPress)
|
||||
if (nextEvent.type == KeyPress)
|
||||
{
|
||||
if (next_event.xkey.keycode == event->xkey.keycode)
|
||||
if (nextEvent.xkey.keycode == event->xkey.keycode)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
xf_kbd_unset_keypress(xfc, event->xkey.keycode);
|
||||
xf_kbd_send_key(xfc, FALSE, event->xkey.keycode);
|
||||
xf_keyboard_key_release(xfc, event->xkey.keycode);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -451,7 +538,7 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app)
|
||||
xf_rail_adjust_position(xfc, window);
|
||||
}
|
||||
|
||||
xf_kbd_focus_in(xfc);
|
||||
xf_keyboard_focus_in(xfc);
|
||||
|
||||
if (!app)
|
||||
xf_cliprdr_check_owner(xfc);
|
||||
@@ -469,7 +556,7 @@ static BOOL xf_event_FocusOut(xfContext* xfc, XEvent* event, BOOL app)
|
||||
if (event->xfocus.mode == NotifyWhileGrabbed)
|
||||
XUngrabKeyboard(xfc->display, CurrentTime);
|
||||
|
||||
xf_kbd_clear(xfc);
|
||||
xf_keyboard_clear(xfc);
|
||||
|
||||
if (app)
|
||||
xf_rail_send_activate(xfc, event->xany.window, FALSE);
|
||||
@@ -481,10 +568,10 @@ static BOOL xf_event_MappingNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (event->xmapping.request == MappingModifier)
|
||||
{
|
||||
if (xfc->modifier_map)
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
if (xfc->modifierMap)
|
||||
XFreeModifiermap(xfc->modifierMap);
|
||||
|
||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
||||
xfc->modifierMap = XGetModifierMapping(xfc->display);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -681,7 +768,7 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
rdpUpdate* update = xfc->instance->update;
|
||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||
|
||||
xf_kbd_release_all_keypress(xfc);
|
||||
xf_keyboard_release_all_keypress(xfc);
|
||||
|
||||
if (!app)
|
||||
{
|
||||
@@ -941,6 +1028,8 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
xf_event_execute_action_script(xfc, event);
|
||||
|
||||
if (event->type != MotionNotify)
|
||||
DEBUG_X11("%s Event(%d): wnd=0x%04X", X11_EVENT_STRINGS[event->type], event->type, (UINT32) event->xany.window);
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "xf_client.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
int xf_event_action_script_init(xfContext* xfc);
|
||||
void xf_event_action_script_free(xfContext* xfc);
|
||||
|
||||
BOOL xf_event_process(freerdp* instance, XEvent* event);
|
||||
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
||||
|
||||
|
||||
@@ -236,7 +236,6 @@ void xf_input_save_last_event(XGenericEventCookie* cookie)
|
||||
lastEvent.detail = event->detail;
|
||||
lastEvent.event_x = event->event_x;
|
||||
lastEvent.event_y = event->event_y;
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pan(xfContext* xfc)
|
||||
@@ -269,13 +268,10 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
|
||||
dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x);
|
||||
dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y);
|
||||
|
||||
|
||||
//only pan in x if dist_y is greater than something
|
||||
if(dist_y > MIN_FINGER_DIST)
|
||||
|
||||
if (dist_y > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(px_vector > PAN_THRESHOLD)
|
||||
if (px_vector > PAN_THRESHOLD)
|
||||
{
|
||||
|
||||
{
|
||||
@@ -293,7 +289,7 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(px_vector < -PAN_THRESHOLD)
|
||||
else if (px_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
@@ -313,10 +309,10 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
|
||||
}
|
||||
|
||||
if(dist_x > MIN_FINGER_DIST)
|
||||
if (dist_x > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(py_vector > PAN_THRESHOLD)
|
||||
if (py_vector > PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
@@ -333,7 +329,7 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(py_vector < -PAN_THRESHOLD)
|
||||
else if (py_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
@@ -351,7 +347,6 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pinch(xfContext* xfc)
|
||||
@@ -368,7 +363,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* first calculate the distance */
|
||||
dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) +
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
@@ -399,7 +393,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
|
||||
z_vector += delta;
|
||||
|
||||
|
||||
lastDist = dist;
|
||||
|
||||
if (z_vector > ZOOM_THRESHOLD)
|
||||
@@ -451,8 +444,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
if(active_contacts == MAX_CONTACTS)
|
||||
printf("Houston, we have a problem!\n\n");
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
@@ -472,6 +463,7 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
@@ -493,14 +485,13 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
{
|
||||
contacts[i].id = 0;
|
||||
contacts[i].count = 0;
|
||||
//contacts[i].pos_x = (int)event->event_x;
|
||||
//contacts[i].pos_y = (int)event->event_y;
|
||||
|
||||
active_contacts--;
|
||||
break;printf("TouchBegin\n");
|
||||
@@ -733,15 +724,15 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
||||
int xf_input_handle_event(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
#ifdef WITH_XI
|
||||
//printf("m:%d g:%d\n", (xfc->settings->MultiTouchInput), (xfc->settings->MultiTouchGestures) );
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
return xf_input_handle_event_remote(xfc, event);
|
||||
}
|
||||
|
||||
if (xfc->settings->MultiTouchGestures)
|
||||
{
|
||||
return xf_input_handle_event_local(xfc, event);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
@@ -33,66 +35,153 @@
|
||||
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
|
||||
#include "xf_event.h"
|
||||
|
||||
#include "xf_keyboard.h"
|
||||
|
||||
void xf_kbd_init(xfContext* xfc)
|
||||
int xf_keyboard_action_script_init(xfContext* xfc)
|
||||
{
|
||||
xf_kbd_clear(xfc);
|
||||
int exitCode;
|
||||
FILE* keyScript;
|
||||
char* keyCombination;
|
||||
char buffer[1024] = { 0 };
|
||||
char command[1024] = { 0 };
|
||||
|
||||
xfc->keyboard_layout_id = xfc->instance->settings->KeyboardLayout;
|
||||
xfc->keyboard_layout_id = freerdp_keyboard_init(xfc->keyboard_layout_id);
|
||||
xfc->instance->settings->KeyboardLayout = xfc->keyboard_layout_id;
|
||||
if (xfc->actionScript)
|
||||
{
|
||||
free(xfc->actionScript);
|
||||
xfc->actionScript = NULL;
|
||||
}
|
||||
|
||||
if (xfc->modifier_map)
|
||||
XFreeModifiermap(xfc->modifier_map);
|
||||
if (PathFileExistsA("/usr/share/freerdp/action.sh"))
|
||||
xfc->actionScript = _strdup("/usr/share/freerdp/action.sh");
|
||||
|
||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
||||
if (!xfc->actionScript)
|
||||
return 0;
|
||||
|
||||
xfc->keyCombinations = ArrayList_New(TRUE);
|
||||
ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free;
|
||||
|
||||
sprintf_s(command, sizeof(command), "%s key", xfc->actionScript);
|
||||
|
||||
keyScript = popen(command, "r");
|
||||
|
||||
if (keyScript < 0)
|
||||
{
|
||||
free(xfc->actionScript);
|
||||
xfc->actionScript = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
|
||||
{
|
||||
strtok(buffer, "\n");
|
||||
keyCombination = _strdup(buffer);
|
||||
ArrayList_Add(xfc->keyCombinations, keyCombination);
|
||||
}
|
||||
|
||||
exitCode = pclose(keyScript);
|
||||
|
||||
xf_event_action_script_init(xfc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xf_kbd_clear(xfContext* xfc)
|
||||
void xf_keyboard_action_script_free(xfContext* xfc)
|
||||
{
|
||||
ZeroMemory(xfc->pressed_keys, 256 * sizeof(BOOL));
|
||||
xf_event_action_script_free(xfc);
|
||||
|
||||
if (xfc->keyCombinations)
|
||||
{
|
||||
ArrayList_Free(xfc->keyCombinations);
|
||||
xfc->keyCombinations = NULL;
|
||||
}
|
||||
|
||||
if (xfc->actionScript)
|
||||
{
|
||||
free(xfc->actionScript);
|
||||
xfc->actionScript = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void xf_kbd_set_keypress(xfContext* xfc, BYTE keycode, KeySym keysym)
|
||||
void xf_keyboard_init(xfContext* xfc)
|
||||
{
|
||||
if (keycode >= 8)
|
||||
xfc->pressed_keys[keycode] = keysym;
|
||||
else
|
||||
xf_keyboard_clear(xfc);
|
||||
|
||||
xfc->KeyboardLayout = xfc->instance->settings->KeyboardLayout;
|
||||
xfc->KeyboardLayout = freerdp_keyboard_init(xfc->KeyboardLayout);
|
||||
xfc->instance->settings->KeyboardLayout = xfc->KeyboardLayout;
|
||||
|
||||
if (xfc->modifierMap)
|
||||
XFreeModifiermap(xfc->modifierMap);
|
||||
|
||||
xfc->modifierMap = XGetModifierMapping(xfc->display);
|
||||
|
||||
xf_keyboard_action_script_init(xfc);
|
||||
}
|
||||
|
||||
void xf_keyboard_free(xfContext* xfc)
|
||||
{
|
||||
if (xfc->modifierMap)
|
||||
{
|
||||
XFreeModifiermap(xfc->modifierMap);
|
||||
xfc->modifierMap = NULL;
|
||||
}
|
||||
|
||||
xf_keyboard_action_script_free(xfc);
|
||||
}
|
||||
|
||||
void xf_keyboard_clear(xfContext* xfc)
|
||||
{
|
||||
ZeroMemory(xfc->KeyboardState, 256 * sizeof(BOOL));
|
||||
}
|
||||
|
||||
void xf_keyboard_key_press(xfContext* xfc, BYTE keycode, KeySym keysym)
|
||||
{
|
||||
if (keycode < 8)
|
||||
return;
|
||||
}
|
||||
|
||||
void xf_kbd_unset_keypress(xfContext* xfc, BYTE keycode)
|
||||
{
|
||||
if (keycode >= 8)
|
||||
xfc->pressed_keys[keycode] = NoSymbol;
|
||||
else
|
||||
xfc->KeyboardState[keycode] = keysym;
|
||||
|
||||
if (xf_keyboard_handle_special_keys(xfc, keysym))
|
||||
return;
|
||||
|
||||
xf_keyboard_send_key(xfc, TRUE, keycode);
|
||||
}
|
||||
|
||||
void xf_kbd_release_all_keypress(xfContext* xfc)
|
||||
void xf_keyboard_key_release(xfContext* xfc, BYTE keycode)
|
||||
{
|
||||
if (keycode < 8)
|
||||
return;
|
||||
|
||||
xfc->KeyboardState[keycode] = NoSymbol;
|
||||
|
||||
xf_keyboard_send_key(xfc, FALSE, keycode);
|
||||
}
|
||||
|
||||
void xf_keyboard_release_all_keypress(xfContext* xfc)
|
||||
{
|
||||
int keycode;
|
||||
DWORD rdp_scancode;
|
||||
|
||||
for (keycode = 0; keycode < ARRAYSIZE(xfc->pressed_keys); keycode++)
|
||||
for (keycode = 0; keycode < ARRAYSIZE(xfc->KeyboardState); keycode++)
|
||||
{
|
||||
if (xfc->pressed_keys[keycode] != NoSymbol)
|
||||
if (xfc->KeyboardState[keycode] != NoSymbol)
|
||||
{
|
||||
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
|
||||
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, rdp_scancode);
|
||||
xfc->pressed_keys[keycode] = NoSymbol;
|
||||
xfc->KeyboardState[keycode] = NoSymbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL xf_kbd_key_pressed(xfContext* xfc, KeySym keysym)
|
||||
BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym)
|
||||
{
|
||||
KeyCode keycode = XKeysymToKeycode(xfc->display, keysym);
|
||||
return (xfc->pressed_keys[keycode] == keysym);
|
||||
return (xfc->KeyboardState[keycode] == keysym);
|
||||
}
|
||||
|
||||
void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
||||
void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
||||
{
|
||||
DWORD rdp_scancode;
|
||||
rdpInput* input;
|
||||
@@ -105,7 +194,7 @@ void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
||||
fprintf(stderr, "Unknown key with X keycode 0x%02x\n", keycode);
|
||||
}
|
||||
else if (rdp_scancode == RDP_SCANCODE_PAUSE &&
|
||||
!xf_kbd_key_pressed(xfc, XK_Control_L) && !xf_kbd_key_pressed(xfc, XK_Control_R))
|
||||
!xf_keyboard_key_pressed(xfc, XK_Control_L) && !xf_keyboard_key_pressed(xfc, XK_Control_R))
|
||||
{
|
||||
/* Pause without Ctrl has to be sent as Ctrl + NumLock. */
|
||||
if (down)
|
||||
@@ -123,13 +212,13 @@ void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
||||
if ((rdp_scancode == RDP_SCANCODE_CAPSLOCK) && (down == FALSE))
|
||||
{
|
||||
UINT32 syncFlags;
|
||||
syncFlags = xf_kbd_get_toggle_keys_state(xfc);
|
||||
syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
|
||||
input->SynchronizeEvent(input, syncFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int xf_kbd_read_keyboard_state(xfContext* xfc)
|
||||
int xf_keyboard_read_keyboard_state(xfContext* xfc)
|
||||
{
|
||||
int dummy;
|
||||
Window wdummy;
|
||||
@@ -145,10 +234,11 @@ int xf_kbd_read_keyboard_state(xfContext* xfc)
|
||||
XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
|
||||
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym)
|
||||
BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym)
|
||||
{
|
||||
int offset;
|
||||
int modifierpos, key, keysymMask = 0;
|
||||
@@ -159,11 +249,11 @@ BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym)
|
||||
|
||||
for (modifierpos = 0; modifierpos < 8; modifierpos++)
|
||||
{
|
||||
offset = xfc->modifier_map->max_keypermod * modifierpos;
|
||||
offset = xfc->modifierMap->max_keypermod * modifierpos;
|
||||
|
||||
for (key = 0; key < xfc->modifier_map->max_keypermod; key++)
|
||||
for (key = 0; key < xfc->modifierMap->max_keypermod; key++)
|
||||
{
|
||||
if (xfc->modifier_map->modifiermap[offset + key] == keycode)
|
||||
if (xfc->modifierMap->modifiermap[offset + key] == keycode)
|
||||
{
|
||||
keysymMask |= 1 << modifierpos;
|
||||
}
|
||||
@@ -173,26 +263,26 @@ BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym)
|
||||
return (state & keysymMask) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
int xf_kbd_get_toggle_keys_state(xfContext* xfc)
|
||||
UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc)
|
||||
{
|
||||
int state;
|
||||
int toggle_keys_state = 0;
|
||||
UINT32 toggleKeysState = 0;
|
||||
|
||||
state = xf_kbd_read_keyboard_state(xfc);
|
||||
state = xf_keyboard_read_keyboard_state(xfc);
|
||||
|
||||
if (xf_kbd_get_key_state(xfc, state, XK_Scroll_Lock))
|
||||
toggle_keys_state |= KBD_SYNC_SCROLL_LOCK;
|
||||
if (xf_kbd_get_key_state(xfc, state, XK_Num_Lock))
|
||||
toggle_keys_state |= KBD_SYNC_NUM_LOCK;
|
||||
if (xf_kbd_get_key_state(xfc, state, XK_Caps_Lock))
|
||||
toggle_keys_state |= KBD_SYNC_CAPS_LOCK;
|
||||
if (xf_kbd_get_key_state(xfc, state, XK_Kana_Lock))
|
||||
toggle_keys_state |= KBD_SYNC_KANA_LOCK;
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Scroll_Lock))
|
||||
toggleKeysState |= KBD_SYNC_SCROLL_LOCK;
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Num_Lock))
|
||||
toggleKeysState |= KBD_SYNC_NUM_LOCK;
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Caps_Lock))
|
||||
toggleKeysState |= KBD_SYNC_CAPS_LOCK;
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Kana_Lock))
|
||||
toggleKeysState |= KBD_SYNC_KANA_LOCK;
|
||||
|
||||
return toggle_keys_state;
|
||||
return toggleKeysState;
|
||||
}
|
||||
|
||||
void xf_kbd_focus_in(xfContext* xfc)
|
||||
void xf_keyboard_focus_in(xfContext* xfc)
|
||||
{
|
||||
rdpInput* input;
|
||||
UINT32 syncFlags;
|
||||
@@ -200,39 +290,141 @@ void xf_kbd_focus_in(xfContext* xfc)
|
||||
Window wdummy;
|
||||
UINT32 state = 0;
|
||||
|
||||
if (xfc->display && xfc->window)
|
||||
{
|
||||
input = xfc->instance->input;
|
||||
syncFlags = xf_kbd_get_toggle_keys_state(xfc);
|
||||
XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
|
||||
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
|
||||
if (xfc->display && xfc->window)
|
||||
{
|
||||
input = xfc->instance->input;
|
||||
syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
|
||||
XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
|
||||
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, KeySym keysym)
|
||||
{
|
||||
int index;
|
||||
int count;
|
||||
int exitCode;
|
||||
int status = 1;
|
||||
FILE* keyScript;
|
||||
const char* keyStr;
|
||||
BOOL match = FALSE;
|
||||
char* keyCombination;
|
||||
char buffer[1024] = { 0 };
|
||||
char command[1024] = { 0 };
|
||||
char combination[1024] = { 0 };
|
||||
|
||||
if (!xfc->actionScript)
|
||||
return 1;
|
||||
|
||||
if ((keysym == XK_Shift_L) || (keysym == XK_Shift_R) ||
|
||||
(keysym == XK_Alt_L) || (keysym == XK_Alt_R) ||
|
||||
(keysym == XK_Control_L) || (keysym == XK_Control_R))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
keyStr = XKeysymToString(keysym);
|
||||
|
||||
if (mod->Shift)
|
||||
strcat(combination, "Shift+");
|
||||
|
||||
if (mod->Ctrl)
|
||||
strcat(combination, "Ctrl+");
|
||||
|
||||
if (mod->Alt)
|
||||
strcat(combination, "Alt+");
|
||||
|
||||
strcat(combination, keyStr);
|
||||
|
||||
count = ArrayList_Count(xfc->keyCombinations);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
keyCombination = (char*) ArrayList_GetItem(xfc->keyCombinations, index);
|
||||
|
||||
if (_stricmp(keyCombination, combination) == 0)
|
||||
{
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
return 1;
|
||||
|
||||
sprintf_s(command, sizeof(command), "%s key %s",
|
||||
xfc->actionScript, combination);
|
||||
|
||||
keyScript = popen(command, "r");
|
||||
|
||||
if (keyScript < 0)
|
||||
return -1;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
|
||||
{
|
||||
strtok(buffer, "\n");
|
||||
|
||||
if (strcmp(buffer, "key-local") == 0)
|
||||
status = 0;
|
||||
}
|
||||
|
||||
exitCode = pclose(keyScript);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xk_keyboard_get_modifier_keys(xfContext* xfc, XF_MODIFIER_KEYS* mod)
|
||||
{
|
||||
mod->LeftShift = xf_keyboard_key_pressed(xfc, XK_Shift_L);
|
||||
mod->RightShift = xf_keyboard_key_pressed(xfc, XK_Shift_R);
|
||||
mod->Shift = mod->LeftShift || mod->RightShift;
|
||||
|
||||
mod->LeftAlt = xf_keyboard_key_pressed(xfc, XK_Alt_L);
|
||||
mod->RightAlt = xf_keyboard_key_pressed(xfc, XK_Alt_R);
|
||||
mod->Alt = mod->LeftAlt || mod->RightAlt;
|
||||
|
||||
mod->LeftCtrl = xf_keyboard_key_pressed(xfc, XK_Control_L);
|
||||
mod->RightCtrl = xf_keyboard_key_pressed(xfc, XK_Control_R);
|
||||
mod->Ctrl = mod->LeftCtrl || mod->RightCtrl;
|
||||
|
||||
mod->LeftSuper = xf_keyboard_key_pressed(xfc, XK_Super_L);
|
||||
mod->RightSuper = xf_keyboard_key_pressed(xfc, XK_Super_R);
|
||||
mod->Super = mod->LeftSuper || mod->RightSuper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
{
|
||||
XF_MODIFIER_KEYS mod = { 0 };
|
||||
|
||||
xk_keyboard_get_modifier_keys(xfc, &mod);
|
||||
|
||||
if (!xf_keyboard_execute_action_script(xfc, &mod, keysym))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (keysym == XK_Return)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L) || xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L) || xf_kbd_key_pressed(xfc, XK_Control_R)))
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
/* Ctrl-Alt-Enter: toggle full screen */
|
||||
xf_toggle_fullscreen(xfc);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (keysym == XK_period)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
//Zoom in (scale larger)
|
||||
/* Zoom In (scale larger) */
|
||||
|
||||
double s = xfc->settings->ScalingFactor;
|
||||
|
||||
s += 0.1;
|
||||
|
||||
if (s > 2.0)
|
||||
s = 2.0;
|
||||
|
||||
@@ -258,15 +450,14 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
|
||||
if (keysym == XK_comma)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
//Zoom out (scale smaller)
|
||||
/* Zoom Out (scale smaller) */
|
||||
|
||||
double s = xfc->settings->ScalingFactor;
|
||||
|
||||
s -= 0.1;
|
||||
|
||||
if (s < 0.5)
|
||||
s = 0.5;
|
||||
|
||||
@@ -293,11 +484,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
|
||||
if (keysym == XK_KP_4)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
|
||||
{
|
||||
@@ -315,11 +502,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
|
||||
if (keysym == XK_KP_6)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
|
||||
{
|
||||
@@ -336,11 +519,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
|
||||
if (keysym == XK_KP_8)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
@@ -356,11 +535,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
|
||||
if (keysym == XK_KP_2)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
@@ -374,7 +549,6 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,17 +25,37 @@
|
||||
#include "xf_client.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
void xf_kbd_init(xfContext* xfc);
|
||||
void xf_kbd_clear(xfContext* xfc);
|
||||
void xf_kbd_set_keypress(xfContext* xfc, BYTE keycode, KeySym keysym);
|
||||
void xf_kbd_unset_keypress(xfContext* xfc, BYTE keycode);
|
||||
void xf_kbd_release_all_keypress(xfContext* xfc);
|
||||
BOOL xf_kbd_key_pressed(xfContext* xfc, KeySym keysym);
|
||||
void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode);
|
||||
int xf_kbd_read_keyboard_state(xfContext* xfc);
|
||||
BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym);
|
||||
int xf_kbd_get_toggle_keys_state(xfContext* xfc);
|
||||
void xf_kbd_focus_in(xfContext* xfc);
|
||||
BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym);
|
||||
#define XF_ACTION_SCRIPT "~/.config/freerdp/action.sh"
|
||||
|
||||
struct _XF_MODIFIER_KEYS
|
||||
{
|
||||
BOOL Shift;
|
||||
BOOL LeftShift;
|
||||
BOOL RightShift;
|
||||
BOOL Alt;
|
||||
BOOL LeftAlt;
|
||||
BOOL RightAlt;
|
||||
BOOL Ctrl;
|
||||
BOOL LeftCtrl;
|
||||
BOOL RightCtrl;
|
||||
BOOL Super;
|
||||
BOOL LeftSuper;
|
||||
BOOL RightSuper;
|
||||
};
|
||||
typedef struct _XF_MODIFIER_KEYS XF_MODIFIER_KEYS;
|
||||
|
||||
void xf_keyboard_init(xfContext* xfc);
|
||||
void xf_keyboard_free(xfContext* xfc);
|
||||
void xf_keyboard_clear(xfContext* xfc);
|
||||
void xf_keyboard_key_press(xfContext* xfc, BYTE keycode, KeySym keysym);
|
||||
void xf_keyboard_key_release(xfContext* xfc, BYTE keycode);
|
||||
void xf_keyboard_release_all_keypress(xfContext* xfc);
|
||||
BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym);
|
||||
void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode);
|
||||
int xf_keyboard_read_keyboard_state(xfContext* xfc);
|
||||
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);
|
||||
|
||||
#endif /* __XF_KEYBOARD_H */
|
||||
|
||||
@@ -125,9 +125,13 @@ struct xf_context
|
||||
BOOL mouse_active;
|
||||
BOOL suppress_output;
|
||||
BOOL fullscreen_toggle;
|
||||
UINT32 keyboard_layout_id;
|
||||
BOOL pressed_keys[256];
|
||||
XModifierKeymap* modifier_map;
|
||||
UINT32 KeyboardLayout;
|
||||
BOOL KeyboardState[256];
|
||||
XModifierKeymap* modifierMap;
|
||||
wArrayList* keyCombinations;
|
||||
wArrayList* xevents;
|
||||
char* actionScript;
|
||||
|
||||
XSetWindowAttributes attribs;
|
||||
BOOL complex_regions;
|
||||
VIRTUAL_SCREEN vscreen;
|
||||
|
||||
Reference in New Issue
Block a user