Skip to content

Instantly share code, notes, and snippets.

@Noitidart
Last active August 21, 2016 21:17
Show Gist options
  • Save Noitidart/9026d03b83a4cf493c1744e46884a139 to your computer and use it in GitHub Desktop.
Save Noitidart/9026d03b83a4cf493c1744e46884a139 to your computer and use it in GitHub Desktop.
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_selection_notify_event_t = ctypes.StructType('xcb_selection_notify_event_t', [
{ response_type: ctypes.uint8_t },
{ pad0: ctypes.uint8_t },
{ sequence: ctypes.uint16_t },
{ time: ctypes.uint32_t },
{ requestor: ctypes.uint32_t },
{ selection: ctypes.uint32_t },
{ target: ctypes.uint32_t },
{ property: 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 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 XCB_SELECTION_NOTIFY = 31;
var XCB_EVENT_MASK_PROPERTY_CHANGE = 4194304;
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);
var chgValueList = ctypes.uint32_t.array()([
XCB_EVENT_MASK_PROPERTY_CHANGE
]);
var rez_chg = xcb_change_window_attributes(conn, screens.data.contents.root, XCB_CW_EVENT_MASK, chgValueList);
console.log('rez_chg:', rez_chg);
}
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());
if (evt.contents.response_type == XCB_SELECTION_NOTIFY) {
console.log('got sel notif');
var sel_ev = ctypes.cast(evt, xcb_selection_notify_event_t.ptr);
console.log(sel_ev);
}
free(evt);
}
}, 1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment