diff --git a/meshcore/KVM/Linux/linux_events.c b/meshcore/KVM/Linux/linux_events.c index 3d6f247..c3992c3 100644 --- a/meshcore/KVM/Linux/linux_events.c +++ b/meshcore/KVM/Linux/linux_events.c @@ -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 + } + } +} \ No newline at end of file diff --git a/meshcore/KVM/Linux/linux_events.h b/meshcore/KVM/Linux/linux_events.h index d448045..e3b0459 100644 --- a/meshcore/KVM/Linux/linux_events.h +++ b/meshcore/KVM/Linux/linux_events.h @@ -23,6 +23,8 @@ limitations under the License. #include #include #include +#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_ */ diff --git a/meshcore/KVM/Linux/linux_kvm.c b/meshcore/KVM/Linux/linux_kvm.c index c5ebe66..b71eee6 100644 --- a/meshcore/KVM/Linux/linux_kvm.c +++ b/meshcore/KVM/Linux/linux_kvm.c @@ -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; diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index de38078..879e004 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -2260,7 +2260,7 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) #endif // monitor-info: Refer to modules/monitor-info.js - duk_peval_string_noresult(ctx, "addCompressedModule('monitor-info', Buffer.from('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', 'base64'));"); + duk_peval_string_noresult(ctx, "addCompressedModule('monitor-info', Buffer.from('eJztPWl320aS3/2e/0NHLxOQY5gSJcXrUOb4MRJlc6PDT6RjZSUPFyKbIiIQ4ALgoXG0v32r+gAaQAMEKeWaDV5iSd3V1dXVdfRRKGz//fmzQ29679u345Ds7tRfk44bUoccev7U863Q9tznz54/O7EH1A3okMzcIfVJOKakNbUG8EPUmORH6gcATXZrO6SCAFuiaqt68PzZvTcjE+ueuF5IZgEFDHZARrZDCV0O6DQktksG3mTq2JY7oGRhh2PWi8BRe/7sJ4HBuwktALYAfAp/jVQwYoVILYFnHIbTxvb2YrGoWYzSmuffbjscLtg+6Ry2z7rtl0AttvjoOjQIiE//Z2b7MMybe2JNgZiBdQMkOtaCeD6xbn0KdaGHxC58O7TdW5ME3ihcWD59/mxoB6Fv38zCBJ8kaTBeFQA4Zblkq9Ulne4W+b7V7XTN588+dXrvzz/2yKfWxUXrrNdpd8n5BTk8Pzvq9DrnZ/DXMWmd/UR+6JwdmYQCl6AXupz6SD2QaCMH6RDY1aU00f3I4+QEUzqwR/YABuXezqxbSm69OfVdGAuZUn9iBziLARA3fP7MsSd2yIQgyI4IOvn7NjJvbvlk6nvQlJKm5GHFEEUGTj+CfPjgBTbiAqB9Wda1/4WNXsu/T21XFNXJmzcx3Km1VMu/FeX9s3av/+m03+21eu3+Rfv0/Mc2wOwcoAhsbwMxExjd9gzIDZFGGGF4r2vaOjpC3LKdNRxur2rSO3/37gR725WtQu/2FsQl2ag7u4FZnw3CmU8v6BBYMwhPreAOGlbYWHZ3JIdU0DMvtEf3CcD6dxEroYdTbwj4po41oGzEvOay1W/1zk8VFp8Cwe87Z71u//jj2SGXIokx6jkGOmofnl+0kmB1CXYIwuWGpyBsKDhNsrcnKz6151iTILeukosMORyDzNHk4HfTQHzgyFYpFC33Xlb27qdytM+fjWbugMnTLQ1P7JuOO/Iqjn3jWhNaff7sC7cD9ohUYEIGQHMNmBWCHkzIV01iOLY7WxpV8gVk2vcWpGKcu849CWZTMHxCQwXMAXmQZgXpGYxtZ6hKOivoi16Mao0u6eAYbFvF2L6x3e1gbJjkyoAfn3GwiIa1qAXh0JuF8MMHbIahq/PcijG0QgswRMOtDMYz945Tbges+YsmYYW10OuCiXFvK0h0pjfbraHdopWtBRgOCibJGQ48d2Tfkl+ItbgjxheQXtsNyde75MG4dunSDq/drSSihWWHbaioVA9UtkSompnh1YCmiQL+b8DBaLQvyBZ5OQX+gXeYEmMLCoQQYlUt8GoGVEIPxvW1axDjn4bg9cvjf0b8HpHrravrrQM00xW7WT+w3zTPjg9evLCBSERpgOF2gOVf2yZBMTbJVhWmRZRiyVX9M6/ahboK1tkjb9mMAXavdgECCqHexHogc9Dcgk7Hi4E1bW7tyP5HHiMBfrxpIhKkA/5AftmjCscIBVdYCCh/du8AJWLbqjabuwjGUEcgwMiChqz3RtQ0B2pniSRzSqEExoJYCfsfHjlQ5E/oYQPCWVCBv4A1X8FAEbvg9tbfgi/X10gz/Nsg8M/fAvjHxN+mVjjOlrKes8U40ETpA5RX7K+a9bfA5AZ0yuhhk4M/l/CToTIZj2AMDxFNn4H/D9eR1hkrtS707/kvwtZJTZyDMvxn9/ysNrX8gFZytFGix8en4HNAL+ay8EF0bYWDcQXNaaob2eDLg9LiIWGVJ55rhx6MDcxybI+ZwvXPb34GN9hBn2sIuJcIKDWYQ91OVBvRf0dd6tuDUxjU2HKMmA9aG98E1Avb3ds1stRz9LAO9fd2oQvZW+3Qp1ZIz2DFM6fgcpb3FYMD1YaOY6gMUzGIZqc0HHvDitF2Z5MjG8TRuj/lQws0Te9gzUWdld1LsBwCouokCe/AIVpB2PZ9z1f4FLUDh4neEvpWfWhHzJQEVRgmJcvmrRDJQbJWCoRLF3IxWIntLaxPPQeWmSbA4cx7fjWNPh6UIjjQ1xciGzdIFk0j+g1W4tQZNRiJJgiu49xYgzv+N+MuMEVI0DvHu7GcQwFS2a+Sh4MSxNQk0prChgREKSzDxRG4I2geUca1oed9CP1KBj45fSWIAybNnDCADq4+rzcsdJVJ3qhO89wV4szkZAwYwJQNBzAXJm7p9DOKD6on61UZZx+2i7DM4+V8yhiOXCRSAv0btAm1I1i+jCo7Jqm/qoLL/n42GlG/UtWMNzFuwZvadBaMK+Cm6CgECbqBcmsIG9+93ZN2ZYeZ7GmmfB/K2T45U/Maam68MPQmmao6+LQH/RQmRiWliU0ICrJiEHBHfrtidH7tR8thO5gCGKGifh6ih2xxDu04pVx8hQnUGD2cHfgvX950dVw5qnw0sNDPlQep9hUjsnRNAxZKnKrILqqWsMLQ5g2ec0dTqeEKdWCrm0sYt1FZTc6oqI6UhzS7HxKO+iHhnhkdud5P7F4y3g92qse2H4TIftj1LyhxxbnGENQQzyloiCcBLiVsm8A2/Zf1Oq5YfMu3aUDYeYfExwc6GNPBnepReMkqh7JM8QBWbF8xhCfegJ089KHnk8731SSYhvmIblmvC9us7AmBETeAxNCxG49FKvYST3RE22oWqMCuiUY1h7q34RjZXie//CJxXdnLzzW23MMaWGBrkBd0gE+0xluzHT7c3taGdARzKbfQTC5NYqT4C5b+C7DQmdFGgnpcDcf7oLznBgzVXQGMRofkw5aYpEKXObxZMc4czDpTpvGFOuYWzLZUM+rOrzIM/Iz7i01ZXowZJ6DkkPiKfanjpmZgKQQPJXSx1+2V1MUwCHOUEWpWaqNovaY6ilYZfRTlfxaFBCYnFFIl/y+NFE+hRiIH19PIFM+LMa+rkWQdlVxfKduXZZWSLvOUEmpWKqVovaZSilYZpRTlfxalBCYnlFIl/y+lFE+hUiIH11PKFM+LMf+abnJ9nTzuXLa7JbVyZC9pkKOXrG6lZkYY1tTNqF1GO6OaP4t+MoYnNDQ5hL90VDyFOsq5uJ6WZji/CvvvoqnykE8UgdJqt80jn9KbYJh7bLzZRhc0+cl2ujh/eNOpno7Dny9hmobUN6rxjvdq53P1MdsSwFNzRLVuzp5sw1BuSGzfsPaYUgu7tcdENl1wlRsUW3etPaiUY3ySQZX0WOWGJdzW2gPL2JI1hhafjhWrOD8ZQy+3pgWIxksx3AFvqlncQ3tihyH12QGfGFPoz2i1NmAHuAymYtzNJ10eXXBEQ2AGHWZvdACmv6zX+wH159Q/9mYu3pOPLCegadDT817nuH980nqHkRq5xgdDOzDyo986OZFljSj+g5g50Bftbue/2gnoej40i7tJ4t4tgO6cdU45dgm9VwDdukxD7+dDH56cd9tJSr6tKtx5SLOxvwzZkSaPKklWwWxkrb0sXGHwfQouWTN3+DD1q+iMP/nmG6KzoNpyNEKr1VXxWpkrBI1ZeBKqStkQboCwSfk1a9Sk+N5U61dzFnURytQl6iUPV5K2SrsCL9H+E1hFb9EKReSffiVfjMfxAiouVzZo7bkuZaJ7NpvcUH8jDGCLwi51OJ4NMLA/3x1u2pLzcNPWXYyK3BjHER1ZMyc89BxwD9Z0YwRd8AV0A94d0SD0vfuNyfetxQm43A1acol7T/HOc+Pmn+xhOF6/9TGFVf+ZNdmA7mNnFmzSI0zPbynZ72jYCr3JZmOExlwgNrdOeKvsu0jC+m1Prelm8viFTNgvDWJcnsHCl62MDLwIxktzFBnc7TXY6il/q74mcpcukMuJ4u69OzDW7sG4PJ9Sd2NT/IG6Q9u9Xb/hheeFmxoAbrY77nS2gRJzo3UIy9CNG5+PNubX40gHZnMJ2KBpeOz59NbH5fdmzcVqcaPGaK4fs14AFGfoq5z3NtujbNA+8vXnC3eTJQOimN0smMhioPpGGD6dgnULvYHnbDKIEGZwM+PKbMParb53rMHdB9j0Ouu3/TS2Q7ph21k4ei2Zha7AFiKzmbv+gd4PYL42YDi4JGh841n+ENzDdCM7xyOvex4gCu438Et8xV2GjMw5IT48uP9xcenqMxhj1C31fX0QOh6LaD0Qb5cIbFfK9AHtmWB2fSC7+uQGDqXOP9QnZ1vGqYuC441pQF5aSxkUf5kJaU5NRboI45oe1TfduGvApom0Vh9kW2KGRDw1e6tkDZ5tb5NL0mXnPGSEnkYPVnhwpjkuUo/OSiyj6MTWH02JI6xfYcLkyQjiX40+9We2J00vBT1kT6w5sDzJEMdBL16QN6T+uuzpypL3F9CwZ08oyIUS+xyOrZBrpxXGR0ryrBDqQD1NUt+Bh0dEFhzSZE+v4tMopaqczPAJZ/JyS8NGyjLJaNG8Y0kkOylbDBKtEyy4T+wgxGDrhJHCl2JMAjZ66FA///QMFYy9P4O2SCOZ0VzpqFo5YaL7zFltAdM1EfR28NG1w3v1YFAUFRwLSpYmbscuj971Dz9eXLTPev2jdveH3vkH4zMbOkOXsFsPGTpm7hEd4Iu64nxDJShdVxlyH28SvjArPr88XUzY+jF70Paj5dv4XmxlfyfNNWw4EQ2l3EUI0GEr286YnDz8Rp+fccuXE42qSTJdSjrjkPB9NSKce4WPUTx29D6jikOhL3nol2aZmRmdrmRvl0U+S8pM8q0mhDfqF4xGy3G8BR22BvxVW2UOM5VZikaOdRvkz+X237M6kPdO6Am/FDCLWiRfEJWN6thI3yy6fFjdg3rz0EygzoUWb/wK2N1iWHnvEMHvFcPLm4cIfr8Qnt89RMDfpowRf1taLfmj69ljNE0jYytUNyLvg2cj9fjCd3EfXPQzhP4K6px643od5ebGFwcj51nV7lRtlsKlSdhfw3AMvpMdxgKRtvuJl8Bv72WhtZSF1pIXFpv4QKEpTzZea2UPswhAo/iV/l/4q/yaey5JKi6P3ZnjoPeOiJaF/MVPwPlLM8oBkLnoZdjEGBPY5Gj12HjmgIPsli8afjmBRoxpXqRRrC/Cy01Qkhdkvxjt/YZoXxejZWK4Ier6bjFuLttp5DoRYvNbstNXxZ1K1NmwAtGxRrLK9by7Qpwi3DldpwR9nZ5XyIZEndvx5mNeIT6xXdKoo2K1kyeYWZsYkbNyXbWw7oNzt+dNM4uqqCZG70fH7OWWyIvJGRjwSTcEg/kY76umFUHfm1mf8s5YP60bb/5knfVb38PyKeoy2+lywDJ+FPiH716liRVtyhnVvb3qAck+29upXCPh/ZQWdaMVSNhEvSZvyf5r0lipFHu7jBB8Nw4lLwSvn+xPnezalPcS4cJcRJU1KNpBinaUaVKAVCKBJqBowpnQfwwTvn2FXb5e3WWKL5k0OZJNeARZc652PqfZFIvpY9n0ah9oxtVXCTYpJNXTJDFVfiwxe7tADLqTMsRIIeZdF9g5cUelt0EgILnZg37JyRZkSpkoMo1jeyjOBDoDlo8pMo3Jmj+Xaeze2dMns4zdHzof+r1W94fvWxd/QAOpPk9iLJvN12/3Xzf+EGaS0bLT+G0MJHb27avGb2caUUwfw5lX+43NbOJTWkUkZG+38ee1hymL+CtkRBFBoFCZmxOF5TGJbu76PgtDhX8PooKfWcHPmhs8QI35fWLjk7FPLMZSOWuuXbY+9t6fX3R6P2Hoc6LqqNP9cNL6qeTrSmr+E2DTJeNTdGmKKSFeBpQnEjSqCPHRHubXL8aeNbFBUHSXTZJIWLMDnRUjHoNhckJqS2sWjj1QzcymV4dAjDRqLSRNc/6fnU4BG+VuYUKrhARVopQuKSegY7Vupys6iNNflLjqElwdMVaigcILaoxhqBjbQPR2OJlug3F0w65jzSmMOxHFRI4tAOe3huw4rUEMKycyCkUOZbKixZDTgqccoZmNvZbBQRxvlGSyEogkmcSyeWh0zmaymcl9g5nNWHVz58B+o3TEsqyVknveSEdYFOQUGy5bf+XuJXPP7IhcMztRbhkFtxpCqSLGgccZZ7IN+B4724LT3xA/5d+dIeAwpWw3IiHPiIDmsMAm/ygjpNZw+Mnz74KpNaDv+f2bQp2kf0V/QvoCzA2XXYzlSJqCI7K8TO/7y+GkIhIP2cPiy8gV+SN51xWerClN9RMljJRPUdpDLcyTpD/MYI4TSfJoi5cechF/DCbDKPZC/oIJDLEaUyWqqRD/24jTTi4dmcFv11ya11vb15i/jyejXF4tHUz3l01ImSQsEbiRnMS8JHjaoA2NBMuER2iV5aGYTFD2oH2Vkbum4SQ/HSbw+sRbUP/QgnXBauFn4i0zgmnAEt44tZDhHhp2dIHn0EJ5V1YtMEyNeZ3xq3lS6O6hCMHUHjWo/s31AsW+OMDq7RZGSbE0kagcQpGAedqmzaYwOm+3Gt99913UDBuF4T3TPm8yAfuqaqDQL6Fc4Gcsk1xDv7Bmuo4ziFosOegNVpFrkTnz63qzeb3FlFemM4Xab74hNyyh5jX8paTUxPyXJvvvesv8um6CHiMcBolsrLcoJKF3R9mdeJ4W8QEYZmYBwt5mYq2Vd9v3yiypQpZ3EHjaEN2z/J3xOjMqRqbRJUantN15I/41k1Aws9pB4lhHwp6spAp2Tz2QSnKCIkCOMJU4JuyCLQPmVAfXumAZxS9FRJntBiFLpW67LH8XShURWmqyWCSZChwwsARf0cK6pu2865EFNXzMF45Zw0KP3PizkCUWx15CE5OmU3c2oZg2HiAsx5GLb+jCW7g8rzqqFqPGxBzjSCeQETISYHVs+547wT3NXCydA/1S7AlNBz5lzEcG7klNSAL7ajMCtqDQiEy5N2azrnphqciZfM/1IjWNiVsRG8nfdHepVl+FoubEYsr1uYsSy3CUD6Vk3eLCnLW7cj/HCad14GDbHFfYhH+kl68rupLdrXKBYASOYcv/ATa+jluUcwKIoerOHOwrzdmOlyQPn4QNM94aSeuldqis/KN+Sxo1TadskRIvsKHEJMoioIgRj0p/weM4c6wpPvlBuJ8oUDhzhq4REnyFXbGEzEJFPAk8YgXEIo4VhMA0zPVBRyC2MESHhgH5eQbljufdscQsopm+W5a5ZaW0F9CNz5pSz9lEYtHX7N1K9ix7fzIlkLSVkfwStOGT1YAnk3OB/hGyjk9BIpmNVWGTYGmuAjIFKNOArwV/0F+jQDN3HjKPjn469ur+zGVfDvH4IiNA74JLUUusKdKLEf4VErEAkMuRHF/z/8O7c3ctlu+K18YV/neq68bjDwTjzruER8cvOJDf1aWzD8MEJvy/NMkc/ktnWZCP9P3LDXw/OnNm/5bS/j3Csz8mT9U0UCWWHcfiS63KaSzK77bBPhCRIBi/77AtFr+5Lz3hsyr3VGUa0M0tOtguWLhr38koQUDu5MoHJxkkoblzAP++mcpN2cGLF/D35lSzA7rgCnB81h2Zr4mNjQQGAuQF+LGoypzLb1XRbyn1zcK5UumbX+3wkH55+bCCyJKE4oNmIb6WmMNGtQRNouEjHRg+BQIhHyYYwEKMxvv9XeJ6w1ZShiU/bhEtFpRPW4hE7rlHa/G6ssH9R7wkf5v6GzZzplxBCmB5Xp7Emcpx0ogNUOKzGtV0MpQCNL1urxwaACxA074siQYAC9CwdFDlEDHQ7Nwl0t4nZ3EhLyW6ADOteM7wx+R0vjtd9QUShNS/boXYTLLVDxD3lvatvLgjtDnYQHOn+O50ndvEucyOE2GLKqLbYqyKSnGd87/J91J5lSK9cxlNr2SiUb4VI38pw435rsqKedxY32yObS7Oz3ufOmeJhoKiODMCgu5US+FrHfY6P7bl21Y6tErgELTIzgAPFkq/tlWNKYhndsI/d5bFASWaMLN6HePMXkVR99hcxGHoG/wHwu+viCLKfoFNITLxqkQ6XRGOHyDEFJjql95MRlxS8Grs7Xk+F2oPRzQY+PYUNJc1V7UqVYXrJms4jEsrEYGpTEYggfxeE6/grGGA7zAm33jNdlzrK84yHwqVQuBMqMZoqFEO/Oxeu9BOpKe+vrO7r7qZxRi/hCkCbWQMAB+0yBmSrOMfssh1NDo8icwnSWwmkJ+J6V+w843KZTsvTA3ZE8lXiTRkAyugqY/8NfJW9Eq/BUwtCqwtohWBUyxKWoQUd1cMTM91bmzF69WRn+E6xl6u1kHf0vBw5uOv0XV5JXcZlrMiystfO+RpqHJ4rmulSayYdaG6q/25yXO6CWaxOCSuxPmZIJlhBgjVGqMjUxI+lkm+OBdv88akJ3MwZmaimnCE67y5rIhC9MYy3iZnusBgKz7dbCkQhwwk7o1Ta5Gsd53rxCN1z5uVHi2tX6XISfXNX0JXiSu3FkrC20PV7QllTZxOItSNzV4/WwkX/KsMVGjZThk4/gGePMgYVolNzKTcEkZ0HsVizncVPxkXJW0Li2J8tc9+pD5sagLLTMYQE4ZrssGYglR1ADiDwb+EfeSfSkqe5KaMVBwag5iiduXsuj7WIHmwmHE//Huq7KNLZISZ3PCMcMBlMxa29Kvt4gezL7lhN0PLX9iuEVuXiTecObTGN2SBiLZMfHvwoAhn4kNJWpS1OCF7Ijs7R/t/3aj63A==', 'base64'));"); // service-host. Refer to modules/service-host.js duk_peval_string_noresult(ctx, "addCompressedModule('service-host', Buffer.from('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', 'base64'));"); diff --git a/modules/monitor-info.js b/modules/monitor-info.js index e457d69..8a6fb33 100644 --- a/modules/monitor-info.js +++ b/modules/monitor-info.js @@ -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']);