Merge branch 'xkeys' of github.com:awakecoding/FreeRDP

This commit is contained in:
Marc-André Moreau
2014-03-25 12:27:22 -04:00
7 changed files with 432 additions and 155 deletions

View File

@@ -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)

View File

@@ -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);

View File

@@ -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, ...);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;