1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00

Added unicode-key support for xorg (Linux/FreeBSD)

This commit is contained in:
Bryan Roe
2020-11-18 17:01:15 -08:00
parent 2fc2206eb9
commit 4ffe75c873
5 changed files with 105 additions and 8 deletions

View File

@@ -15,10 +15,14 @@ limitations under the License.
*/
#include "linux_events.h"
#include "microstack/ILibParsers.h"
static const int g_keymapLen = 96; // Modify this when you change anything in g_keymap.
extern int change_display;
x11tst_struct *x11tst_exports = NULL;
extern void kvm_keyboard_unmap_unicode_key(Display *display, int keycode);
extern int kvm_keyboard_map_unicode_key(Display *display, uint16_t unicode);
static struct keymap_t g_keymap[] = {
{ XK_BackSpace, VK_BACK },
@@ -180,31 +184,59 @@ void MouseAction(double absX, double absY, int button, short wheel, Display *dis
x11tst_exports->XFlush(display);
}
void KeyAction(unsigned char vk, int up, Display *display) {
void KeyAction(unsigned char vk, int up, Display *display)
{
int i = 0;
unsigned int keysym = 0;
unsigned int keycode = 0;
if (change_display) {
if (change_display)
{
return;
}
for (i = 0; i < g_keymapLen; i++) {
if (g_keymap[i].vk == vk) {
for (i = 0; i < g_keymapLen; i++)
{
if (g_keymap[i].vk == vk)
{
keysym = g_keymap[i].keysym;
break;
}
}
if (keysym == 0) {
if (keysym == 0)
{
keycode = x11tst_exports->XKeysymToKeycode(display, vk);
}
else {
else
{
keycode = x11tst_exports->XKeysymToKeycode(display, keysym);
}
//printf("%x %x %d %d\n", keysym, vk, keycode, up);
if (keycode != 0) {
if (keycode != 0)
{
if (!x11tst_exports->XTestFakeKeyEvent(display, keycode, !up, 0)) { return; }
x11tst_exports->XFlush(display);
}
}
void KeyActionUnicode(uint16_t unicode, int up, Display *display)
{
if (change_display) { return; }
int i;
if (up == 0)
{
int keycode = kvm_keyboard_map_unicode_key(display, unicode); // Create a key mapping on an unmapped key
if (keycode > 0)
{
x11tst_exports->XTestFakeKeyEvent(display, keycode, 1, 0);
x11tst_exports->XFlush(display);
usleep(10000); // We need a short sleep between KeyDown and KeyUp, to register correctly.
x11tst_exports->XTestFakeKeyEvent(display, keycode, 0, 0);
x11tst_exports->XFlush(display);
kvm_keyboard_unmap_unicode_key(display, keycode); // Delete the key mapping we created above
}
}
}

View File

@@ -23,6 +23,8 @@ limitations under the License.
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "microstack/ILibParsers.h"
typedef struct x11tst_struct
{
@@ -399,5 +401,6 @@ struct keymap_t {
extern void MouseAction(double absX, double absY, int button, short wheel, Display *display);
extern void KeyAction(unsigned char vk, int up, Display *display);
extern void KeyActionUnicode(uint16_t unicode, int up, Display *display);
#endif /* LINUX_EVENTS_H_ */

View File

@@ -133,6 +133,10 @@ typedef struct x11_struct
int(*XGetWindowAttributes)(Display *d, Window w, XWindowAttributes *a);
void(*XChangeWindowAttributes)(Display *d, Window w, unsigned long valuemask, XSetWindowAttributes *a);
int(*XQueryPointer)(Display *d, Window w, Window *rr, Window *cr, int *rx, int *ry, int *wx, int *wy, unsigned int *mr);
int(*XDisplayKeycodes)(Display *display, int *min_keycodes_return, int *max_keycodes_return);
KeySym(*XGetKeyboardMapping)(Display *display, KeyCode first_keycode, int keycode_count, int *keysyms_per_keycode_return);
KeySym(*XStringToKeysym)(char *string);
int(*XChangeKeyboardMapping)(Display *display, int first_keycode, int keysyms_per_keycode, KeySym *keysyms, int num_codes);
}x11_struct;
x11_struct *x11_exports = NULL;
@@ -146,6 +150,50 @@ typedef struct xfixes_struct
}xfixes_struct;
xfixes_struct *xfixes_exports = NULL;
void kvm_keyboard_unmap_unicode_key(Display *display, int keycode)
{
// Delete a keymapping that we created previously
KeySym keysym_list[] = { 0 };
x11_exports->XChangeKeyboardMapping(display, keycode, 1, keysym_list, 1);
x11_exports->XFlush(display);
}
int kvm_keyboard_map_unicode_key(Display *display, uint16_t unicode)
{
KeySym *keysyms = NULL;
int keysyms_per_keycode = 0;
int keycode_low, keycode_high;
int empty_keycode = 0;
int i, j, keycodeIndex;
char unicodestring[6];
// Convert the unicode character to something xorg will understand
if (sprintf_s(unicodestring, sizeof(unicodestring), "U%04X", unicode) < 0) { return(-1); }
// Get the keycode range that is supported on this platform
x11_exports->XDisplayKeycodes(display, &keycode_low, &keycode_high);
keysyms = x11_exports->XGetKeyboardMapping(display, keycode_low, keycode_high - keycode_low, &keysyms_per_keycode);
// Find an unmapped key
for (i = keycode_low; i <= keycode_high; ++i)
{
int empty = 1;
for (j = 0; j < keysyms_per_keycode; ++j)
{
keycodeIndex = (i - keycode_low) * keysyms_per_keycode + j;
if (keysyms[keycodeIndex] != 0) { empty = 0; } else { break; }
}
if (empty) { empty_keycode = i; break; } // Found it!
}
x11_exports->XFree(keysyms);
x11_exports->XFlush(display);
// Map the unicode character to one of the unused keys above
KeySym sym = x11_exports->XStringToKeysym(unicodestring);
KeySym keysym_list[] = { sym };
x11_exports->XChangeKeyboardMapping(display, empty_keycode, 1, keysym_list, 1);
x11_exports->XFlush(display);
return(empty_keycode);
}
void kvm_send_error(char *msg)
{
@@ -507,6 +555,11 @@ int kvm_init(int displayNo)
((void**)x11_exports)[14] = (void*)dlsym(x11_exports->x11_lib, "XGetWindowAttributes");
((void**)x11_exports)[15] = (void*)dlsym(x11_exports->x11_lib, "XChangeWindowAttributes");
((void**)x11_exports)[16] = (void*)dlsym(x11_exports->x11_lib, "XQueryPointer");
((void**)x11_exports)[17] = (void*)dlsym(x11_exports->x11_lib, "XDisplayKeycodes");
((void**)x11_exports)[18] = (void*)dlsym(x11_exports->x11_lib, "XGetKeyboardMapping");
((void**)x11_exports)[19] = (void*)dlsym(x11_exports->x11_lib, "XStringToKeysym");
((void**)x11_exports)[20] = (void*)dlsym(x11_exports->x11_lib, "XChangeKeyboardMapping");
((void**)x11tst_exports)[4] = (void*)x11_exports->XFlush;
((void**)x11tst_exports)[5] = (void*)x11_exports->XKeysymToKeycode;
@@ -609,6 +662,10 @@ int kvm_server_inputdata(char* block, int blocklen)
switch (type)
{
case MNG_KVM_KEY_UNICODE: // Unicode Key
if (size != 7) break;
if (g_enableEvents) KeyActionUnicode(((((unsigned char)block[5]) << 8) + ((unsigned char)block[6])), block[4], eventdisplay);
break;
case MNG_KVM_KEY: // Key
{
if (size != 6) break;

File diff suppressed because one or more lines are too long

View File

@@ -311,6 +311,11 @@ function monitorinfo()
this._X11.CreateMethod('XBlackPixel');
this._X11.CreateMethod('XWhitePixel');
this._X11.CreateMethod('Xutf8SetWMProperties');
this._X11.CreateMethod('XDisplayKeycodes');
this._X11.CreateMethod('XGetKeyboardMapping');
this._X11.CreateMethod('XStringToKeysym');
this._X11.CreateMethod('XChangeKeyboardMapping');
}
var ch = require('child_process').execFile('/bin/sh', ['sh']);