Last active
September 22, 2017 17:40
-
-
Save Noitidart/3870a1e5ab341fe8604cf516ff7c93cb to your computer and use it in GitHub Desktop.
_ff-addon-snippet-xcbGrabKey - Trying to create a global hotkey with XCB. [jsctypes] [xcb] [unix] [linux] [*nix]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Cu.import('resource://gre/modules/ctypes.jsm'); | |
var libxcb; | |
try { | |
libxcb = ctypes.open('libxcb.so'); | |
} catch(ignore) { | |
libxcb = ctypes.open('libxcb.so.1'); | |
} | |
var libkey; | |
try { | |
libkey = ctypes.open('libxcb-keysyms.so'); | |
} catch(ignore) { | |
libkey = ctypes.open('libxcb-keysyms.so.1'); | |
} | |
var libutil; | |
try { | |
libutil = ctypes.open('libxcb-util.so'); | |
} catch(ignore) { | |
libutil = ctypes.open('libxcb-util.so.1'); | |
} | |
var xcb_setup_t = ctypes.StructType('xcb_setup_t', [ // https://github.com/netzbasis/openbsd-xenocara/blob/e6500f41b55e38013ac9b489f66fe49df6b8b68c/lib/libxcb/src/xproto.h#L453 | |
{ status: ctypes.uint8_t }, | |
{ pad0: ctypes.uint8_t }, | |
{ protocol_major_version: ctypes.uint16_t }, | |
{ protocol_minor_version: ctypes.uint16_t }, | |
{ length: ctypes.uint16_t }, | |
{ release_number: ctypes.uint32_t }, | |
{ resource_id_base: ctypes.uint32_t }, | |
{ resource_id_mask: ctypes.uint32_t }, | |
{ motion_buffer_size: ctypes.uint32_t }, | |
{ vendor_len: ctypes.uint16_t }, | |
{ maximum_request_length: ctypes.uint16_t }, | |
{ roots_len: ctypes.uint8_t }, | |
{ pixmap_formats_len: ctypes.uint8_t }, | |
{ image_byte_order: ctypes.uint8_t }, | |
{ bitmap_format_bit_order: ctypes.uint8_t }, | |
{ bitmap_format_scanline_unit: ctypes.uint8_t }, | |
{ bitmap_format_scanline_pad: ctypes.uint8_t }, | |
{ min_keycode: ctypes.uint8_t }, | |
{ max_keycode: ctypes.uint8_t }, | |
{ pad1: ctypes.uint8_t.array(4) } | |
]); | |
// var xcb_setup_t = ctypes.voidptr_t; | |
var xcb_screen_t = ctypes.StructType('xcb_screen_t', [ | |
{ root: ctypes.uint32_t }, | |
{ default_colormap: ctypes.uint32_t }, | |
{ white_pixel: ctypes.uint32_t }, | |
{ black_pixel: ctypes.uint32_t }, | |
{ current_input_masks: ctypes.uint32_t }, | |
{ width_in_pixels: ctypes.uint16_t }, | |
{ height_in_pixels: ctypes.uint16_t }, | |
{ width_in_millimeters: ctypes.uint16_t }, | |
{ height_in_millimeters: ctypes.uint16_t }, | |
{ min_installed_maps: ctypes.uint16_t }, | |
{ max_installed_maps: ctypes.uint16_t }, | |
{ root_visual: ctypes.uint32_t }, | |
{ backing_stores: ctypes.uint8_t }, | |
{ save_unders: ctypes.uint8_t }, | |
{ root_depth: ctypes.uint8_t }, | |
{ allowed_depths_len: ctypes.uint8_t } | |
]); | |
var xcb_screen_iterator_t = ctypes.StructType('xcb_screen_iterator_t', [ | |
{ data: xcb_screen_t.ptr }, | |
{ rem: ctypes.int }, | |
{ index: ctypes.int } | |
]); | |
var xcb_void_cookie_t = ctypes.StructType('xcb_void_cookie_t', [ | |
{ sequence: ctypes.unsigned_int } | |
]); | |
var xcb_generic_event_t = ctypes.StructType('xcb_generic_event_t', [ | |
{ response_type: ctypes.uint8_t }, | |
{ pad0: ctypes.uint8_t }, | |
{ sequence: ctypes.uint16_t }, | |
{ pad: ctypes.uint32_t.array(7) }, | |
{ full_sequence: ctypes.uint32_t } | |
]); | |
var xcb_connect = libxcb.declare('xcb_connect', ctypes.default_abi, ctypes.voidptr_t, ctypes.char.ptr, ctypes.int.ptr); // http://xcb.freedesktop.org/PublicApi/#index2h2 | |
var xcb_connection_has_error = libxcb.declare('xcb_connection_has_error', ctypes.default_abi, ctypes.int, ctypes.voidptr_t); // https://xcb.freedesktop.org/manual/group__XCB__Core__API.html#ga70a6bade94bd2824db552abcf5fbdbe3 | |
var xcb_key_symbols_alloc = libkey.declare('xcb_key_symbols_alloc', ctypes.default_abi, ctypes.voidptr_t, ctypes.voidptr_t); // http://www.opensource.apple.com/source/X11libs/X11libs-60/xcb-util/xcb-util-0.3.6/keysyms/xcb_keysyms.h | |
var xcb_key_symbols_get_keycode = libkey.declare('xcb_key_symbols_get_keycode', ctypes.default_abi, ctypes.uint8_t.ptr, ctypes.voidptr_t, ctypes.uint32_t); // http://www.opensource.apple.com/source/X11libs/X11libs-60/xcb-util/xcb-util-0.3.6/keysyms/xcb_keysyms.h | |
var free = libxcb.declare('free', ctypes.default_abi, ctypes.void_t, ctypes.voidptr_t); // i guessed on this one | |
var xcb_allow_events = libxcb.declare('xcb_allow_events', ctypes.default_abi, xcb_void_cookie_t, ctypes.voidptr_t, ctypes.uint8_t, ctypes.uint32_t); // http://www.x.org/releases/X11R7.7/doc/man/man3/xcb_allow_events.3.xhtml | |
var xcb_aux_sync = libutil.declare('xcb_aux_sync', ctypes.default_abi, ctypes.int, ctypes.voidptr_t); // http://www.x.org/archive/X11R7.5/doc/libxcb/tutorial/index.html | |
var xcb_change_window_attributes = libxcb.declare('xcb_change_window_attributes', ctypes.default_abi, xcb_void_cookie_t, ctypes.voidptr_t, ctypes.uint32_t, ctypes.uint32_t, ctypes.uint32_t.ptr); // https://xcb.freedesktop.org/manual/group__XCB____API.html#ga3724f4ccfdfa063439258831b75f6224 | |
var xcb_disconnect = libxcb.declare('xcb_disconnect', ctypes.default_abi, ctypes.void_t, ctypes.voidptr_t); // http://xcb.freedesktop.org/PublicApi/#index5h2 | |
var xcb_flush = libxcb.declare('xcb_flush', ctypes.default_abi, ctypes.int, ctypes.voidptr_t); // http://xcb.freedesktop.org/PublicApi/#index13h2 | |
var xcb_generate_id = libxcb.declare('xcb_generate_id', ctypes.default_abi, ctypes.uint32_t, ctypes.voidptr_t); // http://xcb.freedesktop.org/PublicApi/#index16h2 | |
var xcb_get_setup = libxcb.declare('xcb_get_setup', ctypes.default_abi, xcb_setup_t.ptr, ctypes.voidptr_t); // http://xcb.freedesktop.org/PublicApi/#index7h2 | |
var xcb_grab_key = libxcb.declare('xcb_grab_key', ctypes.default_abi, xcb_void_cookie_t, ctypes.voidptr_t, ctypes.uint8_t, ctypes.uint32_t, ctypes.uint16_t, ctypes.uint8_t, ctypes.uint8_t, ctypes.uint8_t); // http://www.x.org/releases/X11R7.7/doc/man/man3/xcb_grab_key.3.xhtml | |
var xcb_key_symbols_free = libkey.declare('xcb_key_symbols_free', ctypes.default_abi, ctypes.void_t, ctypes.voidptr_t); // http://www.opensource.apple.com/source/X11libs/X11libs-60/xcb-util/xcb-util-0.3.6/keysyms/xcb_keysyms.h | |
var xcb_poll_for_event = libxcb.declare('xcb_poll_for_event', ctypes.default_abi, xcb_generic_event_t.ptr, ctypes.voidptr_t); // https://xcb.freedesktop.org/PublicApi/#index11h2 | |
var xcb_screen_next = libxcb.declare('xcb_screen_next', ctypes.default_abi, ctypes.void_t, ctypes.voidptr_t); // https://github.com/emmanueldenloye/firefox-pentadactyl/blob/52bcaf3a49f81350110210a90552690b2db332a0/unused_plugins/fix-focus.js#L244 | |
var xcb_setup_roots_iterator = libxcb.declare('xcb_setup_roots_iterator', ctypes.default_abi, xcb_screen_iterator_t, xcb_setup_t.ptr); // https://github.com/netzbasis/openbsd-xenocara/blob/e6500f41b55e38013ac9b489f66fe49df6b8b68c/lib/libxcb/src/xproto.h#L5409 | |
var xcb_ungrab_key = libxcb.declare('xcb_ungrab_key', ctypes.default_abi, xcb_void_cookie_t, ctypes.voidptr_t, ctypes.uint32_t, ctypes.uint32_t, ctypes.uint16_t); // http://www.x.org/archive/current/doc/man/man3/xcb_ungrab_key.3.xhtml | |
var xcb_wait_for_event = libxcb.declare('xcb_wait_for_event', ctypes.default_abi, xcb_generic_event_t.ptr, ctypes.voidptr_t); // http://xcb.freedesktop.org/PublicApi/#index10h2 | |
// var xcb_grab_key_checked = libxcb.declare('xcb_grab_key_checked ', ctypes.default_abi, xcb_void_cookie_t, ctypes.voidptr_t, ctypes.uint8_t, ctypes.uint32_t, ctypes.uint16_t, ctypes.uint32_t, ctypes.uint8_t, ctypes.uint8_t); // http://libxcb.sourcearchive.com/documentation/1.1/group__XCB____API_gc0b5bb243475091e33be64bd2db95f14.html#gc0b5bb243475091e33be64bd2db95f14 | |
var conn = xcb_connect(null, null); | |
console.log('conn:', conn.toString()); | |
var keysyms = xcb_key_symbols_alloc(conn); | |
console.log('keysyms:', keysyms.toString()); | |
var XK_A = 0x0041; // lower case "a" // https://github.com/semonalbertyeah/noVNC_custom/blob/60daa01208a7e25712d17f67282497626de5704d/include/keysym.js#L216 | |
var XK_Print = 0xff61; | |
var XK_Space = 0x0020; | |
var XCB_EVENT_MASK_KEY_PRESS = 1; | |
var XCB_EVENT_MASK_BUTTON_PRESS = 4; | |
var XCB_EVENT_MASK_EXPOSURE = 32768; | |
var XCB_CW_EVENT_MASK = 2048; | |
var XCB_NO_SYMBOL = 0; | |
var keycodesPtr = xcb_key_symbols_get_keycode(keysyms, XK_A); | |
console.log('keycodesPtr:', keycodesPtr.toString()); | |
var keycodesArr = []; | |
var keycodesArrC = ctypes.cast(keycodesPtr, ctypes.uint8_t.array(10).ptr).contents; | |
console.log('keycodesArrC:', keycodesArrC.toString()); | |
for (var i=0; i<keycodesArrC.length; i++) { | |
if (keycodesArrC[i] == XCB_NO_SYMBOL) { | |
break; | |
} | |
keycodesArr.push(keycodesArrC[i]); | |
} | |
console.log('keycodesArr:', keycodesArr); | |
if (!keycodesArr.length) { | |
throw new Error('no keycodes!! so nothing to grab!'); | |
} | |
free(keycodesPtr); | |
xcb_key_symbols_free(keysyms); | |
var setup = xcb_get_setup(conn); | |
console.log('setup:', setup.contents); | |
var screens = xcb_setup_roots_iterator(setup); | |
var grabWins = []; // so iterate through these and ungrab on remove of hotkey | |
var screensCnt = screens.rem; | |
console.log('screensCnt:', screensCnt); | |
for (var i=0; i<screensCnt; i++) { | |
console.log('screen[' + i + ']:', screens); | |
console.log('screen[' + i + '].data:', screens.data.contents); | |
for (var j=0; j<keycodesArr.length; j++) { | |
var rez_grab = xcb_grab_key(conn, 1, screens.data.contents.root, 32768 /*XCB_MOD_MASK_ANY*/, keycodesArr[j], 1 /*XCB_GRAB_MODE_ASYNC*/, 1 /*XCB_GRAB_MODE_ASYNC*/); | |
console.log('rez_grab:', rez_grab); | |
} | |
var chgValueList = ctypes.uint32_t.array()([ | |
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_KEY_PRESS | |
]); | |
var rez_chg = xcb_change_window_attributes(conn, screens.data.contents.root, XCB_CW_EVENT_MASK, chgValueList); | |
console.log('rez_chg:', rez_chg); | |
grabWins.push(screens.data.contents.root); | |
xcb_screen_next(screens.address()); | |
} | |
var rez_flush = xcb_flush(conn); | |
console.log('rez_flush:', rez_flush); | |
var xcbpoll = setInterval(function() { | |
var evt = xcb_poll_for_event(conn); | |
console.log('evt:', evt.toString()); | |
if (!evt.isNull()) { | |
console.error('evt.contents:', evt.contents, 'evt.pad:', evt.contents.pad.toString()); | |
free(evt); | |
} | |
}, 1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
README
Rev1
Rev2
Rev3
Rev4
Rev5
Rev6
xcb_grab_key_checked
as it seems to not be found inlibxcb
norlibkey