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:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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
@@ -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']);
|
||||
|
||||
Reference in New Issue
Block a user