Esempio n. 1
0
def main(argv):
    display = Display()

    if not display.has_extension('XFIXES'):
        if display.query_extension('XFIXES') is None:
            print('XFIXES extension not supported', file=sys.stderr)
            return 1

    xfixes_version = display.xfixes_query_version()
    print('Found XFIXES version %s.%s' % (
      xfixes_version.major_version,
      xfixes_version.minor_version,
    ), file=sys.stderr)

    screen = display.screen()

    print('Hiding cursor ...', file=sys.stderr)
    screen.root.xfixes_hide_cursor()
    display.sync()

    time.sleep(5)

    print('Showing cursor ...', file=sys.stderr)
    screen.root.xfixes_hide_cursor()
    display.sync()
Esempio n. 2
0
def run_sensor(mouse):
    record_dpy = Display()

    # Check if the extension is present
    if not record_dpy.has_extension("RECORD"):
        print("RECORD extension not found")
        sys.exit(1)

    r = record_dpy.record_get_version(0, 0)
    print("RECORD extension version %d.%d" % (r.major_version, r.minor_version))


    # Create a recording context; we only want key and mouse events
    ctx = record_dpy.record_create_context(
        0,
        [record.AllClients],
        [{
                'core_requests': (0, 0),
                'core_replies': (0, 0),
                'ext_requests': (0, 0, 0, 0),
                'ext_replies': (0, 0, 0, 0),
                'delivered_events': (0, 0),
                'device_events': (X.ButtonPress, X.MotionNotify),
                'errors': (0, 0),
                'client_started': False,
                'client_died': False,
        }])

    # Enable the context; this only returns after a call to record_disable_context,
    # while calling the callback function in the meantime
    record_dpy.record_enable_context(ctx, record_callback(record_dpy, mouse))

    # Finally free the context
    record_dpy.record_free_context(ctx)
Esempio n. 3
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-t",
                        "--timeout",
                        help="specify a timeout interval between 1 and infinity",
                        type=int,
                        required=True)

    args = parser.parse_args()

    display = Display()

    if not display.has_extension('XFIXES'):
        if display.query_extension('XFIXES') is None:
            print('XFIXES extension not supported', file=sys.stderr)
            return 1

    xfixes_version = display.xfixes_query_version()
    print('Found XFIXES version %s.%s' % (
        xfixes_version.major_version,
        xfixes_version.minor_version,
    ), file=sys.stderr)

    screen = display.screen()

    mouse = Mouse(display, screen, args.timeout)
    mouse.start()

    run_sensor(mouse)
Esempio n. 4
0
def main(argv):
    display = Display()

    if not display.has_extension('XFIXES'):
        if display.query_extension('XFIXES') is None:
            print('XFIXES extension not supported', file=sys.stderr)
            return 1

    xfixes_version = display.xfixes_query_version()
    print('Found XFIXES version %s.%s' % (
        xfixes_version.major_version,
        xfixes_version.minor_version,
    ),
          file=sys.stderr)

    screen = display.screen()

    print('Hiding cursor ...', file=sys.stderr)
    screen.root.xfixes_hide_cursor()
    display.sync()

    time.sleep(5)

    print('Showing cursor ...', file=sys.stderr)
    screen.root.xfixes_hide_cursor()
    display.sync()
Esempio n. 5
0
class Record:
    def __init__(self):

        self.record_thread = threading.Thread(
            target=self._record, name='x keyboard listener thread')
        self.recording_connection = Display()
        self.recording_connection.set_error_handler(
            self._record_display_error_handler)

        if not self.recording_connection.has_extension("RECORD"):
            raise Exception("RECORD extension not found")

        r = self.recording_connection.record_get_version(0, 0)
        print("RECORD extension version %d.%d" %
              (r.major_version, r.minor_version))
        self.context = self.recording_connection.record_create_context(
            0, [record.AllClients], CONTEXT_FILTER)

    def start(self):
        self.recording_connection.sync()
        self.record_thread.start()

    def stop(self):
        if self.record_thread.is_alive():
            conn = Display()
            conn.record_disable_context(self.context)
            conn.close()
            print('display stopped recording')
            self.record_thread.join()
        print('recording thread ended')

    #
    # xlib plugs
    #
    def _record(self):
        self.recording_connection.record_enable_context(
            self.context, self.handler)
        self.recording_connection.record_free_context(self.context)
        self.recording_connection.close()

    def _record_display_error_handler(self, exception, *args):
        print('Error at record display: {}'.format(exception), file=sys.stderr)

    def handler(self, reply):
        data = reply.data
        while len(data):
            event, data = rq.EventField(None).parse_binary_value(
                data, self.recording_connection.display, None, None)

            if event.type == X.KeyPress:
                format_key_event(event)
def main(argv):
    if len(sys.argv) != 2:
        sys.exit(
            'usage: {0} SELECTION\n\n'
            'SELECTION is typically PRIMARY, SECONDARY or CLIPBOARD.\n'.format(
                sys.argv[0]))

    display = Display()

    sel_name = sys.argv[1]
    sel_atom = display.get_atom(sel_name)

    if not display.has_extension('XFIXES'):
        if display.query_extension('XFIXES') is None:
            print('XFIXES extension not supported', file=sys.stderr)
            return 1

    xfixes_version = display.xfixes_query_version()
    print('Found XFIXES version %s.%s' % (
        xfixes_version.major_version,
        xfixes_version.minor_version,
    ),
          file=sys.stderr)

    screen = display.screen()

    mask = xfixes.XFixesSetSelectionOwnerNotifyMask | \
           xfixes.XFixesSelectionWindowDestroyNotifyMask | \
           xfixes.XFixesSelectionClientCloseNotifyMask

    display.xfixes_select_selection_input(screen.root, sel_atom, mask)

    while True:
        e = display.next_event()
        print(e)

        if (e.type,
                e.sub_code) == display.extension_event.SetSelectionOwnerNotify:
            print('SetSelectionOwner: owner=0x{0:08x}'.format(e.owner.id))
        elif (e.type, e.sub_code
              ) == display.extension_event.SelectionWindowDestroyNotify:
            print('SelectionWindowDestroy: owner=0x{0:08x}'.format(e.owner.id))
        elif (e.type, e.sub_code
              ) == display.extension_event.SelectionClientCloseNotify:
            print('SelectionClientClose: owner=0x{0:08x}'.format(e.owner.id))
Esempio n. 7
0
def main(argv):
    parser = OptionParser()

    parser.add_option('--generate', action='store_true', default=False)
    parser.add_option('--proto', default='MIT-MAGIC-COOKIE-1')
    parser.add_option('--trusted', action='store_true', default=False)
    parser.add_option('--untrusted', action='store_true', default=False)

    parser.add_option('--revoke', action='store_true', default=False)

    opts, args = parser.parse_args(argv[1:])

    if opts.trusted and opts.untrusted:
        parser.error('--trusted and --untrusted cannot be combined')

    if not any((opts.generate, opts.revoke)):
        parser.error('specify --generate or --revoke')

    display = Display()

    if not display.has_extension('SECURITY'):
        if display.query_extension('SECURITY') is None:
            print('SECURITY extension not supported', file=sys.stderr)
            return 1

    security_version = display.security_query_version()
    print('SECURITY version %s.%s' % (
        security_version.major_version,
        security_version.minor_version,
    ),
          file=sys.stderr)

    if opts.generate:
        kwargs = {}
        if opts.trusted:
            kwargs['trust_level'] = security.SecurityClientTrusted
        elif opts.untrusted:
            kwargs['trust_level'] = security.SecurityClientUntrusted
        reply = display.security_generate_authorization(opts.proto, **kwargs)
        print(reply.authid)

    elif opts.revoke:
        for arg in args:
            authid = int(arg, 10)
            display.security_revoke_authorization(authid)
Esempio n. 8
0
def main(argv):
    parser = OptionParser()

    parser.add_option('--generate', action='store_true', default=False)
    parser.add_option('--proto', default='MIT-MAGIC-COOKIE-1')
    parser.add_option('--trusted', action='store_true', default=False)
    parser.add_option('--untrusted', action='store_true', default=False)

    parser.add_option('--revoke', action='store_true', default=False)

    opts, args = parser.parse_args(argv[1:])

    if opts.trusted and opts.untrusted:
        parser.error('--trusted and --untrusted cannot be combined')

    if not any((opts.generate, opts.revoke)):
        parser.error('specify --generate or --revoke')

    display = Display()

    if not display.has_extension('SECURITY'):
        if display.query_extension('SECURITY') is None:
            print('SECURITY extension not supported', file=sys.stderr)
            return 1

    security_version = display.security_query_version()
    print('SECURITY version %s.%s' % (
      security_version.major_version,
      security_version.minor_version,
    ), file=sys.stderr)

    if opts.generate:
        kwargs = {}
        if opts.trusted:
            kwargs['trust_level'] = security.SecurityClientTrusted
        elif opts.untrusted:
            kwargs['trust_level'] = security.SecurityClientUntrusted
        reply = display.security_generate_authorization(opts.proto, **kwargs)
        print(reply.authid)

    elif opts.revoke:
        for arg in args:
            authid = int(arg, 10)
            display.security_revoke_authorization(authid)
Esempio n. 9
0
import sys
import os

# Change path so we find Xlib
from pprint import pprint

from Xlib.display import Display
from Xlib.ext.nvcontrol import Gpu, Cooler

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

if __name__ == '__main__':
    display = Display()
    # Check for extension
    if not display.has_extension('NV-CONTROL'):
        sys.stderr.write('{}: server does not have the NV-CONTROL extension\n'.format(sys.argv[0]))
        ext = display.query_extension('NV-CONTROL')
        print(ext)
        sys.stderr.write("\n".join(display.list_extensions()))
        if ext is None:
            sys.exit(1)

    gpu = Gpu(0)
    fan = Cooler(0)

    perf_level = 3

    dic = {
        'get_gpu_count': display.nvcontrol_get_gpu_count(),
        'get_vram': display.nvcontrol_get_vram(gpu),
Esempio n. 10
0
class KeyListener(threading.Thread):
    ''' Usage: 
        keylistener = KeyListener()
        Initially:
        keylistener.addKeyListener("L_CTRL+L_SHIFT+y", callable)
        Note that it is necessary to bind all possible combinations
        because an order of key presses can be different, for example,
        "L_CTRL+y+L_SHIFT"
        Now:
        keylistener.addKeyListener("Control_L+c+c", callable)
    '''
    def __init__(self):
        threading.Thread.__init__(self)
        self.finished = threading.Event()
        self.contextEventMask = [X.KeyPress, X.MotionNotify]
        # Give these some initial values
        # Hook to our display.
        self.local_dpy = Display()
        self.record_dpy = Display()
        self.pressed = []
        self.listeners = {}
        self.character = None
        ''' 0: Nothing caught; 1: Read buffer and call main module;
            2: Call main module
        '''
        self.status = 0

    ''' need the following because XK.keysym_to_string() only does
        printable chars rather than being the correct inverse of
        XK.string_to_keysym()
    '''

    def lookup_keysym(self, keysym):
        for name in dir(XK):
            if name.startswith("XK_") and getattr(XK, name) == keysym:
                return name.lstrip("XK_")
        return '[%d]' % keysym

    def processevents(self, reply):
        if reply.category != record.FromServer:
            return
        if reply.client_swapped:
            print_v('* received swapped protocol data, cowardly ignored')
            return
        # I added 'str', since we receive an error without it
        if not len(str(reply.data)) or ord(str(reply.data[0])) < 2:
            # not an event
            return
        data = reply.data
        while len(data):
            event, data = rq.EventField(None).parse_binary_value(
                data, self.record_dpy.display, None, None)
            keycode = event.detail
            keysym = self.local_dpy.keycode_to_keysym(event.detail, 0)
            self.character = self.lookup_keysym(keysym)
            if self.character:
                if event.type == X.KeyPress:
                    self.press()
                elif event.type == X.KeyRelease:
                    self.release()

    def run(self):
        # Check if the extension is present
        if not self.record_dpy.has_extension('RECORD'):
            print_v('RECORD extension not found')
            sys.exit(1)
        r = self.record_dpy.record_get_version(0, 0)
        mes = 'RECORD extension version {}.{}'.format(r.major_version,
                                                      r.minor_version)
        print_v(mes)
        # Create a recording context; we only want key events
        self.ctx = self.record_dpy.record_create_context(
            0,
            [record.AllClients],
            [{
                'core_requests': (0, 0),
                'core_replies': (0, 0),
                'ext_requests': (0, 0, 0, 0),
                'ext_replies': (0, 0, 0, 0),
                'delivered_events': (0, 0)
                # (X.KeyPress, X.ButtonPress)
                ,
                'device_events': tuple(self.contextEventMask),
                'errors': (0, 0),
                'client_started': False,
                'client_died': False,
            }])
        ''' Enable the context; this only returns after a call to
            record_disable_context, while calling the callback function
            in the meantime
        '''
        self.record_dpy.record_enable_context(self.ctx, self.processevents)
        # Finally free the context
        self.record_dpy.record_free_context(self.ctx)

    def cancel(self):
        self.finished.set()
        self.local_dpy.record_disable_context(self.ctx)
        self.local_dpy.flush()

    def append(self):
        if len(self.pressed) > 0:
            if self.pressed[0] in ('Control_L', 'Control_R', 'Alt_L', 'Alt_R'):
                self.pressed.append(self.character)

    def press(self):
        if len(self.pressed) == 2:
            if self.pressed[1] == 'grave':
                self.pressed = []
        elif len(self.pressed) == 3:
            self.pressed = []
        if self.character in ('Control_L', 'Control_R', 'Alt_L', 'Alt_R'):
            self.pressed = [self.character]
        elif self.character in ('c', 'Insert', 'grave'):
            self.append()
        action = self.listeners.get(tuple(self.pressed), False)
        print_v('Current action:', str(tuple(self.pressed)))
        if action:
            action()

    def release(self):
        """must be called whenever a key release event has occurred."""
        # A released Control key is not taken into account
        # A cyrillic 'с' symbol is recognized as Latin 'c'
        if not self.character in ('c', 'Insert', 'grave'):
            self.pressed = []

    def addKeyListener(self, hotkeys, callable):
        keys = tuple(hotkeys.split('+'))
        print_v('Added new keylistener for :', str(keys))
        self.listeners[keys] = callable

    def check(self):  # Returns 0..2
        if self.status:
            print_v('Hotkey has been caught!')
            status = self.status
            self.status = 0
            return status

    def set_status(self, status=0):
        self.status = status
        print_v('Setting status to %d!' % self.status)
Esempio n. 11
0
from Xlib.display import Display
from Xlib import X, threaded
from Xlib.ext import record
from Xlib.protocol import rq
import time
import threading

debug_key_event = False
debug_key_press = False
debug_new_listener = False

local_dpy = Display()
record_dpy = Display()

# Check if the extension is present
if not record_dpy.has_extension('RECORD'):
    print('KeyListener Error: RECORD extension not found')
    sys.exit(1)
r = record_dpy.record_get_version(0, 0)
print(
    f'KeyListener: RECORD extension version {r.major_version}.{r.minor_version}'
)

keysym_map = {
    32: 'SPACE',
    39: '\'',
    44: ',',
    45: '-',
    46: '.',
    47: '/',
    48: '0',
Esempio n. 12
0
class KeyboardListener:
    def __init__(self, callback=None, on_error=None):
        self.on_error = on_error
        self.callback = callback
        # XLib errors are received asynchronously, thus the need for a running state flag
        self.stopped = False

        self.record_thread = threading.Thread(
            target=self._record, name='x keyboard listener thread')
        self.well_thread = threading.Thread(target=self._drop_key,
                                            daemon=True,
                                            name='hotkey well thread')

        self.recording_connection = Display()
        self.well_connection = Display()
        self.recording_connection.set_error_handler(
            self._record_display_error_handler)
        self.well_connection.set_error_handler(
            self._local_display_error_handler)

        if not self.recording_connection.has_extension("RECORD"):
            raise Exception("RECORD extension not found")

        r = self.recording_connection.record_get_version(0, 0)
        print("RECORD extension version %d.%d" %
              (r.major_version, r.minor_version))
        self.context = self.recording_connection.record_create_context(
            0, [record.AllClients], CONTEXT_FILTER)

        self.mod_keys_set = set()
        for mods in self.well_connection.get_modifier_mapping():
            for mod in mods:
                self.mod_keys_set.add(mod)

        self.root = self.well_connection.screen().root
        self.root.change_attributes(event_mask=X.KeyPressMask
                                    | X.KeyReleaseMask)
        self.modifiers_count = self.modified_count = 0
        self.code_map = {}
        self.composed_code_map = {}
        self.composed_mapping_first_code = None
        self.multiplier = ''

    #
    # API
    #
    def bind(self, key):
        if self.stopped:
            return
        if len(key.accelerators) == 1:
            self._bind_single_accelerator(key)
        elif len(key.accelerators) == 2:
            self._bind_composed_accelerator(key)
        self.well_connection.sync()
        if self.stopped:
            print('Unable to bind: {}'.format(', '.join(key.accelerators)),
                  file=sys.stderr)

    def start(self):
        self.well_connection.sync()
        self.recording_connection.sync()
        if self.stopped:
            return
        self.well_thread.start()
        self.record_thread.start()

    def stop(self):
        self.stopped = True
        if self.record_thread.is_alive():
            self.well_connection.record_disable_context(self.context)
            self.well_connection.close()
            print('display stopped recording')
            self.record_thread.join()
        print('recording thread ended')

    #
    # Thread targets
    #
    def _drop_key(self):
        while not self.stopped:
            self.well_connection.next_event()

    def _record(self):
        self.recording_connection.record_enable_context(
            self.context, self.handler)
        self.recording_connection.record_free_context(self.context)
        self.recording_connection.close()

    def _record_display_error_handler(self, exception, *args):
        print('Error at record display: {}'.format(exception), file=sys.stderr)
        if not self.stopped:
            self.stopped = True
            self.on_error()

    def _local_display_error_handler(self, exception, *args):
        print('Error at local display: {}'.format(exception), file=sys.stderr)
        if not self.stopped:
            self.stopped = True
            self.on_error()

    #
    # Internal API
    #
    def _grab_keys(self, code, mask):
        self.root.grab_key(code, mask, True, X.GrabModeAsync, X.GrabModeAsync)
        self.root.grab_key(code, mask | X.Mod2Mask, True, X.GrabModeAsync,
                           X.GrabModeAsync)

    def _bind_single_accelerator(self, key):
        gdk_keyval, code, mask = parse_accelerator(key.accelerators[0])

        self._grab_keys(code, mask)

        if code not in self.code_map:
            self.code_map[code] = {}

        self.code_map[code][mask] = key

    def _bind_composed_accelerator(self, key):
        gdk_keyval, code, mask = parse_accelerator(key.accelerators[0])
        second_gdk_keyval, second_code, second_mask = parse_accelerator(
            key.accelerators[1])

        self._grab_keys(code, mask)

        if code not in self.composed_code_map:
            self.composed_code_map[code] = {}
        if mask not in self.composed_code_map[code]:
            self.composed_code_map[code][mask] = {}
        if second_code not in self.composed_code_map[code][mask]:
            self.composed_code_map[code][mask][second_code] = {}

        if second_mask in self.composed_code_map[code][mask][second_code]:
            raise Exception('key ({}) already mapped'.format(', '.join(
                key.accelerators)))

        self.composed_code_map[code][mask][second_code][second_mask] = key

    #
    # Event handling
    #
    def handler(self, reply):
        data = reply.data
        while len(data):
            event, data = rq.EventField(None).parse_binary_value(
                data, self.recording_connection.display, None, None)

            if event.detail in self.mod_keys_set:
                self.modifiers_count += 1 if event.type == X.KeyPress else -1
                self.modified_count = 0
                continue

            if self.modifiers_count:
                self.modified_count += 1 if event.type == X.KeyPress else -1

            if event.type == X.KeyPress:
                self.handle_keypress(event)

    def handle_keypress(self, event):
        _wasmapped, keyval, egroup, level, consumed = Gdk.Keymap.get_default(
        ).translate_keyboard_state(event.detail, Gdk.ModifierType(event.state),
                                   0)

        code = event.detail
        event.keyval = keyval  # TODO: explain
        mask = normalize_state(event.state)

        if self.composed_mapping_first_code and self.composed_mapping_first_code != (
                code, mask):

            key_name = Gdk.keyval_name(event.keyval)
            if not mask and key_name and key_name.isdigit():
                self.multiplier = self.multiplier + key_name
                return

            second_code_map = self.composed_code_map[
                self.composed_mapping_first_code[0]][
                    self.composed_mapping_first_code[1]]
            if code in second_code_map and mask in second_code_map[code]:
                multiplier_int = int(self.multiplier) if self.multiplier else 1
                self.callback(second_code_map[code][mask],
                              event,
                              multiplier=multiplier_int)

            self.composed_mapping_first_code = None

        elif self.modified_count == 1:

            if code in self.code_map and mask in self.code_map[code]:
                self.callback(self.code_map[code][mask], event)

            if code in self.composed_code_map and mask in self.composed_code_map[
                    code]:
                self.composed_mapping_first_code = (code, mask)

        self.multiplier = ''
Esempio n. 13
0
class GlobalHotkeyManagerX11(GlobalHotkeyManagerBase):
    def __init__(self):
        self._text_to_native = {
            '-': 'minus',
            '+': 'plus',
            '=': 'equal',
            '[': 'bracketleft',
            ']': 'bracketright',
            '|': 'bar',
            ';': 'semicolon',
            '\'': 'quoteright',
            ',': 'comma',
            '.': 'period',
            '/': 'slash',
            '\\': 'backslash',
            '`': 'asciitilde',
        }
        GlobalHotkeyManagerBase.__init__(self)

        self._error = False
        self._display = Display()
        self._poller = X11EventPoller()
        self._poller.keyPressed.connect(self.x11_event)
        self._poller.start()

        # Check if the extension is present
        if not self._display.has_extension('RECORD'):
            raise Exception('RECORD extension not found')

    def destroy(self):
        # self._poller.destroy()
        # should destroy event poller thread, no clue how
        pass

    # noinspection PyUnusedLocal
    def x11_event(self, event, data):
        if event.type == X.KeyPress:
            key = (event.detail, int(event.state) & (X.ShiftMask | X.ControlMask | X.Mod1Mask | X.Mod4Mask))
            if key in self.shortcuts:
                # noinspection PyCallByClass,PyTypeChecker
                QTimer.singleShot(0, self.shortcuts[key])
        return False

    def _native_modifiers(self, modifiers):
        # ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
        native = 0
        modifiers = int(modifiers)
        if modifiers & Qt.ShiftModifier:
            native |= X.ShiftMask
        if modifiers & Qt.ControlModifier:
            native |= X.ControlMask
        if modifiers & Qt.AltModifier:
            native |= X.Mod1Mask
        if modifiers & Qt.MetaModifier:
            native |= X.Mod4Mask
        
        # TODO: resolve these?
        # if (modifiers & Qt.MetaModifier)
        # if (modifiers & Qt.KeypadModifier)
        # if (modifiers & Qt.GroupSwitchModifier)
        return native

    def _native_keycode(self, key):
        keysym = QKeySequence(key).toString()
        if keysym in self._text_to_native:
            keysym = self._text_to_native[keysym]
        return self._display.keysym_to_keycode(XK.string_to_keysym(keysym))

    # noinspection PyUnusedLocal
    def _on_error(self, e, data):
        if e.code in (X.BadAccess, X.BadValue, X.BadWindow):
            if e.major_opcode in (33, 34):                          # X_GrabKey, X_UngrabKey
                self._error = True
                # char errstr[256];
                # XGetErrorText(dpy, err->error_code, errstr, 256);
        return 0

    def _register_shortcut(self, receiver, native_key, native_mods, winid=None):
        window = self._display.screen().root
        self._error = False

        window.grab_key(native_key, native_mods, True, X.GrabModeAsync, X.GrabModeAsync, self._on_error)
        self._display.sync()
        if not self._error:
            self.shortcuts[(native_key, native_mods)] = receiver
        return not self._error

    def _unregister_shortcut(self, native_key, native_mods, window_id):
        display = Display()
        window = display.screen().root
        self._error = False
        window.ungrab_key(native_key, native_mods, self._on_error)
        display.sync()
        try:
            del self.shortcuts[(native_key, native_mods)]
        except KeyError:
            pass
        return not self._error