diff options
| author | Syndamia <kamen.d.mladenov@protonmail.com> | 2020-09-29 22:43:00 +0300 |
|---|---|---|
| committer | Syndamia <kamen.d.mladenov@protonmail.com> | 2020-09-29 22:43:00 +0300 |
| commit | 9a24decd41726ef54fa6613d09829f3f65627b22 (patch) | |
| tree | e65d5dbc8623cf4b257abaa8fb9047f3c97fe5a0 /Python/venv1/Lib/site-packages/keyboard | |
| parent | 6f4cfe7b5c6c74d83b03e18870aeb6977db6c0de (diff) | |
| download | Self-learning-9a24decd41726ef54fa6613d09829f3f65627b22.tar Self-learning-9a24decd41726ef54fa6613d09829f3f65627b22.tar.gz Self-learning-9a24decd41726ef54fa6613d09829f3f65627b22.zip | |
Removed python setup files
Diffstat (limited to 'Python/venv1/Lib/site-packages/keyboard')
34 files changed, 0 insertions, 5932 deletions
diff --git a/Python/venv1/Lib/site-packages/keyboard/__init__.py b/Python/venv1/Lib/site-packages/keyboard/__init__.py deleted file mode 100644 index 5d8f305..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__init__.py +++ /dev/null @@ -1,1155 +0,0 @@ -# -*- coding: utf-8 -*- -""" -keyboard -======== - -Take full control of your keyboard with this small Python library. Hook global events, register hotkeys, simulate key presses and much more. - -## Features - -- **Global event hook** on all keyboards (captures keys regardless of focus). -- **Listen** and **send** keyboard events. -- Works with **Windows** and **Linux** (requires sudo), with experimental **OS X** support (thanks @glitchassassin!). -- **Pure Python**, no C modules to be compiled. -- **Zero dependencies**. Trivial to install and deploy, just copy the files. -- **Python 2 and 3**. -- Complex hotkey support (e.g. `ctrl+shift+m, ctrl+space`) with controllable timeout. -- Includes **high level API** (e.g. [record](#keyboard.record) and [play](#keyboard.play), [add_abbreviation](#keyboard.add_abbreviation)). -- Maps keys as they actually are in your layout, with **full internationalization support** (e.g. `Ctrl+ç`). -- Events automatically captured in separate thread, doesn't block main program. -- Tested and documented. -- Doesn't break accented dead keys (I'm looking at you, pyHook). -- Mouse support available via project [mouse](https://github.com/boppreh/mouse) (`pip install mouse`). - -## Usage - -Install the [PyPI package](https://pypi.python.org/pypi/keyboard/): - - pip install keyboard - -or clone the repository (no installation required, source files are sufficient): - - git clone https://github.com/boppreh/keyboard - -or [download and extract the zip](https://github.com/boppreh/keyboard/archive/master.zip) into your project folder. - -Then check the [API docs below](https://github.com/boppreh/keyboard#api) to see what features are available. - - -## Example - - -```py -import keyboard - -keyboard.press_and_release('shift+s, space') - -keyboard.write('The quick brown fox jumps over the lazy dog.') - -keyboard.add_hotkey('ctrl+shift+a', print, args=('triggered', 'hotkey')) - -# Press PAGE UP then PAGE DOWN to type "foobar". -keyboard.add_hotkey('page up, page down', lambda: keyboard.write('foobar')) - -# Blocks until you press esc. -keyboard.wait('esc') - -# Record events until 'esc' is pressed. -recorded = keyboard.record(until='esc') -# Then replay back at three times the speed. -keyboard.play(recorded, speed_factor=3) - -# Type @@ then press space to replace with abbreviation. -keyboard.add_abbreviation('@@', 'my.long.email@example.com') - -# Block forever, like `while True`. -keyboard.wait() -``` - -## Known limitations: - -- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21) -- Media keys on Linux may appear nameless (scan-code only) or not at all. [#20](https://github.com/boppreh/keyboard/issues/20) -- Key suppression/blocking only available on Windows. [#22](https://github.com/boppreh/keyboard/issues/22) -- To avoid depending on X, the Linux parts reads raw device files (`/dev/input/input*`) -but this requries root. -- Other applications, such as some games, may register hooks that swallow all -key events. In this case `keyboard` will be unable to report events. -- This program makes no attempt to hide itself, so don't use it for keyloggers or online gaming bots. Be responsible. -""" -from __future__ import print_function as _print_function - -import re as _re -import itertools as _itertools -import collections as _collections -from threading import Thread as _Thread, Lock as _Lock -import time as _time -# Python2... Buggy on time changes and leap seconds, but no other good option (https://stackoverflow.com/questions/1205722/how-do-i-get-monotonic-time-durations-in-python). -_time.monotonic = getattr(_time, 'monotonic', None) or _time.time - -try: - # Python2 - long, basestring - _is_str = lambda x: isinstance(x, basestring) - _is_number = lambda x: isinstance(x, (int, long)) - import Queue as _queue - # threading.Event is a function in Python2 wrappin _Event (?!). - from threading import _Event as _UninterruptibleEvent -except NameError: - # Python3 - _is_str = lambda x: isinstance(x, str) - _is_number = lambda x: isinstance(x, int) - import queue as _queue - from threading import Event as _UninterruptibleEvent -_is_list = lambda x: isinstance(x, (list, tuple)) - -# Just a dynamic object to store attributes for the closures. -class _State(object): pass - -# The "Event" class from `threading` ignores signals when waiting and is -# impossible to interrupt with Ctrl+C. So we rewrite `wait` to wait in small, -# interruptible intervals. -class _Event(_UninterruptibleEvent): - def wait(self): - while True: - if _UninterruptibleEvent.wait(self, 0.5): - break - -import platform as _platform -if _platform.system() == 'Windows': - from. import _winkeyboard as _os_keyboard -elif _platform.system() == 'Linux': - from. import _nixkeyboard as _os_keyboard -elif _platform.system() == 'Darwin': - from. import _darwinkeyboard as _os_keyboard -else: - raise OSError("Unsupported platform '{}'".format(_platform.system())) - -from ._keyboard_event import KEY_DOWN, KEY_UP, KeyboardEvent -from ._generic import GenericListener as _GenericListener -from ._canonical_names import all_modifiers, sided_modifiers, normalize_name - -_modifier_scan_codes = set() -def is_modifier(key): - """ - Returns True if `key` is a scan code or name of a modifier key. - """ - if _is_str(key): - return key in all_modifiers - else: - if not _modifier_scan_codes: - scan_codes = (key_to_scan_codes(name, False) for name in all_modifiers) - _modifier_scan_codes.update(*scan_codes) - return key in _modifier_scan_codes - -_pressed_events_lock = _Lock() -_pressed_events = {} -_physically_pressed_keys = _pressed_events -_logically_pressed_keys = {} -class _KeyboardListener(_GenericListener): - transition_table = { - #Current state of the modifier, per `modifier_states`. - #| - #| Type of event that triggered this modifier update. - #| | - #| | Type of key that triggered this modiier update. - #| | | - #| | | Should we send a fake key press? - #| | | | - #| | | => | Accept the event? - #| | | | | - #| | | | | Next state. - #v v v v v v - ('free', KEY_UP, 'modifier'): (False, True, 'free'), - ('free', KEY_DOWN, 'modifier'): (False, False, 'pending'), - ('pending', KEY_UP, 'modifier'): (True, True, 'free'), - ('pending', KEY_DOWN, 'modifier'): (False, True, 'allowed'), - ('suppressed', KEY_UP, 'modifier'): (False, False, 'free'), - ('suppressed', KEY_DOWN, 'modifier'): (False, False, 'suppressed'), - ('allowed', KEY_UP, 'modifier'): (False, True, 'free'), - ('allowed', KEY_DOWN, 'modifier'): (False, True, 'allowed'), - - ('free', KEY_UP, 'hotkey'): (False, None, 'free'), - ('free', KEY_DOWN, 'hotkey'): (False, None, 'free'), - ('pending', KEY_UP, 'hotkey'): (False, None, 'suppressed'), - ('pending', KEY_DOWN, 'hotkey'): (False, None, 'suppressed'), - ('suppressed', KEY_UP, 'hotkey'): (False, None, 'suppressed'), - ('suppressed', KEY_DOWN, 'hotkey'): (False, None, 'suppressed'), - ('allowed', KEY_UP, 'hotkey'): (False, None, 'allowed'), - ('allowed', KEY_DOWN, 'hotkey'): (False, None, 'allowed'), - - ('free', KEY_UP, 'other'): (False, True, 'free'), - ('free', KEY_DOWN, 'other'): (False, True, 'free'), - ('pending', KEY_UP, 'other'): (True, True, 'allowed'), - ('pending', KEY_DOWN, 'other'): (True, True, 'allowed'), - # Necessary when hotkeys are removed after beign triggered, such as - # TestKeyboard.test_add_hotkey_multistep_suppress_modifier. - ('suppressed', KEY_UP, 'other'): (False, False, 'allowed'), - ('suppressed', KEY_DOWN, 'other'): (True, True, 'allowed'), - ('allowed', KEY_UP, 'other'): (False, True, 'allowed'), - ('allowed', KEY_DOWN, 'other'): (False, True, 'allowed'), - } - - def init(self): - _os_keyboard.init() - - self.active_modifiers = set() - self.blocking_hooks = [] - self.blocking_keys = _collections.defaultdict(list) - self.nonblocking_keys = _collections.defaultdict(list) - self.blocking_hotkeys = _collections.defaultdict(list) - self.nonblocking_hotkeys = _collections.defaultdict(list) - self.filtered_modifiers = _collections.Counter() - self.is_replaying = False - - # Supporting hotkey suppression is harder than it looks. See - # https://github.com/boppreh/keyboard/issues/22 - self.modifier_states = {} # "alt" -> "allowed" - - def pre_process_event(self, event): - for key_hook in self.nonblocking_keys[event.scan_code]: - key_hook(event) - - with _pressed_events_lock: - hotkey = tuple(sorted(_pressed_events)) - for callback in self.nonblocking_hotkeys[hotkey]: - callback(event) - - return event.scan_code or (event.name and event.name != 'unknown') - - def direct_callback(self, event): - """ - This function is called for every OS keyboard event and decides if the - event should be blocked or not, and passes a copy of the event to - other, non-blocking, listeners. - - There are two ways to block events: remapped keys, which translate - events by suppressing and re-emitting; and blocked hotkeys, which - suppress specific hotkeys. - """ - # Pass through all fake key events, don't even report to other handlers. - if self.is_replaying: - return True - - if not all(hook(event) for hook in self.blocking_hooks): - return False - - event_type = event.event_type - scan_code = event.scan_code - - # Update tables of currently pressed keys and modifiers. - with _pressed_events_lock: - if event_type == KEY_DOWN: - if is_modifier(scan_code): self.active_modifiers.add(scan_code) - _pressed_events[scan_code] = event - hotkey = tuple(sorted(_pressed_events)) - if event_type == KEY_UP: - self.active_modifiers.discard(scan_code) - if scan_code in _pressed_events: del _pressed_events[scan_code] - - # Mappings based on individual keys instead of hotkeys. - for key_hook in self.blocking_keys[scan_code]: - if not key_hook(event): - return False - - # Default accept. - accept = True - - if self.blocking_hotkeys: - if self.filtered_modifiers[scan_code]: - origin = 'modifier' - modifiers_to_update = set([scan_code]) - else: - modifiers_to_update = self.active_modifiers - if is_modifier(scan_code): - modifiers_to_update = modifiers_to_update | {scan_code} - callback_results = [callback(event) for callback in self.blocking_hotkeys[hotkey]] - if callback_results: - accept = all(callback_results) - origin = 'hotkey' - else: - origin = 'other' - - for key in sorted(modifiers_to_update): - transition_tuple = (self.modifier_states.get(key, 'free'), event_type, origin) - should_press, new_accept, new_state = self.transition_table[transition_tuple] - if should_press: press(key) - if new_accept is not None: accept = new_accept - self.modifier_states[key] = new_state - - if accept: - if event_type == KEY_DOWN: - _logically_pressed_keys[scan_code] = event - elif event_type == KEY_UP and scan_code in _logically_pressed_keys: - del _logically_pressed_keys[scan_code] - - # Queue for handlers that won't block the event. - self.queue.put(event) - - return accept - - def listen(self): - _os_keyboard.listen(self.direct_callback) - -_listener = _KeyboardListener() - -def key_to_scan_codes(key, error_if_missing=True): - """ - Returns a list of scan codes associated with this key (name or scan code). - """ - if _is_number(key): - return (key,) - elif _is_list(key): - return sum((key_to_scan_codes(i) for i in key), ()) - elif not _is_str(key): - raise ValueError('Unexpected key type ' + str(type(key)) + ', value (' + repr(key) + ')') - - normalized = normalize_name(key) - if normalized in sided_modifiers: - left_scan_codes = key_to_scan_codes('left ' + normalized, False) - right_scan_codes = key_to_scan_codes('right ' + normalized, False) - return left_scan_codes + tuple(c for c in right_scan_codes if c not in left_scan_codes) - - try: - # Put items in ordered dict to remove duplicates. - t = tuple(_collections.OrderedDict((scan_code, True) for scan_code, modifier in _os_keyboard.map_name(normalized))) - e = None - except (KeyError, ValueError) as exception: - t = () - e = exception - - if not t and error_if_missing: - raise ValueError('Key {} is not mapped to any known key.'.format(repr(key)), e) - else: - return t - -def parse_hotkey(hotkey): - """ - Parses a user-provided hotkey into nested tuples representing the - parsed structure, with the bottom values being lists of scan codes. - Also accepts raw scan codes, which are then wrapped in the required - number of nestings. - - Example: - - parse_hotkey("alt+shift+a, alt+b, c") - # Keys: ^~^ ^~~~^ ^ ^~^ ^ ^ - # Steps: ^~~~~~~~~~^ ^~~~^ ^ - - # ((alt_codes, shift_codes, a_codes), (alt_codes, b_codes), (c_codes,)) - """ - if _is_number(hotkey) or len(hotkey) == 1: - scan_codes = key_to_scan_codes(hotkey) - step = (scan_codes,) - steps = (step,) - return steps - elif _is_list(hotkey): - if not any(map(_is_list, hotkey)): - step = tuple(key_to_scan_codes(k) for k in hotkey) - steps = (step,) - return steps - return hotkey - - steps = [] - for step in _re.split(r',\s?', hotkey): - keys = _re.split(r'\s?\+\s?', step) - steps.append(tuple(key_to_scan_codes(key) for key in keys)) - return tuple(steps) - -def send(hotkey, do_press=True, do_release=True): - """ - Sends OS events that perform the given *hotkey* hotkey. - - - `hotkey` can be either a scan code (e.g. 57 for space), single key - (e.g. 'space') or multi-key, multi-step hotkey (e.g. 'alt+F4, enter'). - - `do_press` if true then press events are sent. Defaults to True. - - `do_release` if true then release events are sent. Defaults to True. - - send(57) - send('ctrl+alt+del') - send('alt+F4, enter') - send('shift+s') - - Note: keys are released in the opposite order they were pressed. - """ - _listener.is_replaying = True - - parsed = parse_hotkey(hotkey) - for step in parsed: - if do_press: - for scan_codes in step: - _os_keyboard.press(scan_codes[0]) - - if do_release: - for scan_codes in reversed(step): - _os_keyboard.release(scan_codes[0]) - - _listener.is_replaying = False - -# Alias. -press_and_release = send - -def press(hotkey): - """ Presses and holds down a hotkey (see `send`). """ - send(hotkey, True, False) - -def release(hotkey): - """ Releases a hotkey (see `send`). """ - send(hotkey, False, True) - -def is_pressed(hotkey): - """ - Returns True if the key is pressed. - - is_pressed(57) #-> True - is_pressed('space') #-> True - is_pressed('ctrl+space') #-> True - """ - _listener.start_if_necessary() - - if _is_number(hotkey): - # Shortcut. - with _pressed_events_lock: - return hotkey in _pressed_events - - steps = parse_hotkey(hotkey) - if len(steps) > 1: - raise ValueError("Impossible to check if multi-step hotkeys are pressed (`a+b` is ok, `a, b` isn't).") - - # Convert _pressed_events into a set - with _pressed_events_lock: - pressed_scan_codes = set(_pressed_events) - for scan_codes in steps[0]: - if not any(scan_code in pressed_scan_codes for scan_code in scan_codes): - return False - return True - -def call_later(fn, args=(), delay=0.001): - """ - Calls the provided function in a new thread after waiting some time. - Useful for giving the system some time to process an event, without blocking - the current execution flow. - """ - thread = _Thread(target=lambda: (_time.sleep(delay), fn(*args))) - thread.start() - -_hooks = {} -def hook(callback, suppress=False, on_remove=lambda: None): - """ - Installs a global listener on all available keyboards, invoking `callback` - each time a key is pressed or released. - - The event passed to the callback is of type `keyboard.KeyboardEvent`, - with the following attributes: - - - `name`: an Unicode representation of the character (e.g. "&") or - description (e.g. "space"). The name is always lower-case. - - `scan_code`: number representing the physical key, e.g. 55. - - `time`: timestamp of the time the event occurred, with as much precision - as given by the OS. - - Returns the given callback for easier development. - """ - if suppress: - _listener.start_if_necessary() - append, remove = _listener.blocking_hooks.append, _listener.blocking_hooks.remove - else: - append, remove = _listener.add_handler, _listener.remove_handler - - append(callback) - def remove_(): - del _hooks[callback] - del _hooks[remove_] - remove(callback) - on_remove() - _hooks[callback] = _hooks[remove_] = remove_ - return remove_ - -def on_press(callback, suppress=False): - """ - Invokes `callback` for every KEY_DOWN event. For details see `hook`. - """ - return hook(lambda e: e.event_type == KEY_UP or callback(e), suppress=suppress) - -def on_release(callback, suppress=False): - """ - Invokes `callback` for every KEY_UP event. For details see `hook`. - """ - return hook(lambda e: e.event_type == KEY_DOWN or callback(e), suppress=suppress) - -def hook_key(key, callback, suppress=False): - """ - Hooks key up and key down events for a single key. Returns the event handler - created. To remove a hooked key use `unhook_key(key)` or - `unhook_key(handler)`. - - Note: this function shares state with hotkeys, so `clear_all_hotkeys` - affects it aswell. - """ - _listener.start_if_necessary() - store = _listener.blocking_keys if suppress else _listener.nonblocking_keys - scan_codes = key_to_scan_codes(key) - for scan_code in scan_codes: - store[scan_code].append(callback) - - def remove_(): - del _hooks[callback] - del _hooks[key] - del _hooks[remove_] - for scan_code in scan_codes: - store[scan_code].remove(callback) - _hooks[callback] = _hooks[key] = _hooks[remove_] = remove_ - return remove_ - -def on_press_key(key, callback, suppress=False): - """ - Invokes `callback` for KEY_DOWN event related to the given key. For details see `hook`. - """ - return hook_key(key, lambda e: e.event_type == KEY_UP or callback(e), suppress=suppress) - -def on_release_key(key, callback, suppress=False): - """ - Invokes `callback` for KEY_UP event related to the given key. For details see `hook`. - """ - return hook_key(key, lambda e: e.event_type == KEY_DOWN or callback(e), suppress=suppress) - -def unhook(remove): - """ - Removes a previously added hook, either by callback or by the return value - of `hook`. - """ - _hooks[remove]() -unhook_key = unhook - -def unhook_all(): - """ - Removes all keyboard hooks in use, including hotkeys, abbreviations, word - listeners, `record`ers and `wait`s. - """ - _listener.start_if_necessary() - _listener.blocking_keys.clear() - _listener.nonblocking_keys.clear() - del _listener.blocking_hooks[:] - del _listener.handlers[:] - unhook_all_hotkeys() - -def block_key(key): - """ - Suppresses all key events of the given key, regardless of modifiers. - """ - return hook_key(key, lambda e: False, suppress=True) -unblock_key = unhook_key - -def remap_key(src, dst): - """ - Whenever the key `src` is pressed or released, regardless of modifiers, - press or release the hotkey `dst` instead. - """ - def handler(event): - if event.event_type == KEY_DOWN: - press(dst) - else: - release(dst) - return False - return hook_key(src, handler, suppress=True) -unremap_key = unhook_key - -def parse_hotkey_combinations(hotkey): - """ - Parses a user-provided hotkey. Differently from `parse_hotkey`, - instead of each step being a list of the different scan codes for each key, - each step is a list of all possible combinations of those scan codes. - """ - def combine_step(step): - # A single step may be composed of many keys, and each key can have - # multiple scan codes. To speed up hotkey matching and avoid introducing - # event delays, we list all possible combinations of scan codes for these - # keys. Hotkeys are usually small, and there are not many combinations, so - # this is not as insane as it sounds. - return (tuple(sorted(scan_codes)) for scan_codes in _itertools.product(*step)) - - return tuple(tuple(combine_step(step)) for step in parse_hotkey(hotkey)) - -def _add_hotkey_step(handler, combinations, suppress): - """ - Hooks a single-step hotkey (e.g. 'shift+a'). - """ - container = _listener.blocking_hotkeys if suppress else _listener.nonblocking_hotkeys - - # Register the scan codes of every possible combination of - # modfiier + main key. Modifiers have to be registered in - # filtered_modifiers too, so suppression and replaying can work. - for scan_codes in combinations: - for scan_code in scan_codes: - if is_modifier(scan_code): - _listener.filtered_modifiers[scan_code] += 1 - container[scan_codes].append(handler) - - def remove(): - for scan_codes in combinations: - for scan_code in scan_codes: - if is_modifier(scan_code): - _listener.filtered_modifiers[scan_code] -= 1 - container[scan_codes].remove(handler) - return remove - -_hotkeys = {} -def add_hotkey(hotkey, callback, args=(), suppress=False, timeout=1, trigger_on_release=False): - """ - Invokes a callback every time a hotkey is pressed. The hotkey must - be in the format `ctrl+shift+a, s`. This would trigger when the user holds - ctrl, shift and "a" at once, releases, and then presses "s". To represent - literal commas, pluses, and spaces, use their names ('comma', 'plus', - 'space'). - - - `args` is an optional list of arguments to passed to the callback during - each invocation. - - `suppress` defines if successful triggers should block the keys from being - sent to other programs. - - `timeout` is the amount of seconds allowed to pass between key presses. - - `trigger_on_release` if true, the callback is invoked on key release instead - of key press. - - The event handler function is returned. To remove a hotkey call - `remove_hotkey(hotkey)` or `remove_hotkey(handler)`. - before the hotkey state is reset. - - Note: hotkeys are activated when the last key is *pressed*, not released. - Note: the callback is executed in a separate thread, asynchronously. For an - example of how to use a callback synchronously, see `wait`. - - Examples: - - # Different but equivalent ways to listen for a spacebar key press. - add_hotkey(' ', print, args=['space was pressed']) - add_hotkey('space', print, args=['space was pressed']) - add_hotkey('Space', print, args=['space was pressed']) - # Here 57 represents the keyboard code for spacebar; so you will be - # pressing 'spacebar', not '57' to activate the print function. - add_hotkey(57, print, args=['space was pressed']) - - add_hotkey('ctrl+q', quit) - add_hotkey('ctrl+alt+enter, space', some_callback) - """ - if args: - callback = lambda callback=callback: callback(*args) - - _listener.start_if_necessary() - - steps = parse_hotkey_combinations(hotkey) - - event_type = KEY_UP if trigger_on_release else KEY_DOWN - if len(steps) == 1: - # Deciding when to allow a KEY_UP event is far harder than I thought, - # and any mistake will make that key "sticky". Therefore just let all - # KEY_UP events go through as long as that's not what we are listening - # for. - handler = lambda e: (event_type == KEY_DOWN and e.event_type == KEY_UP and e.scan_code in _logically_pressed_keys) or (event_type == e.event_type and callback()) - remove_step = _add_hotkey_step(handler, steps[0], suppress) - def remove_(): - remove_step() - del _hotkeys[hotkey] - del _hotkeys[remove_] - del _hotkeys[callback] - # TODO: allow multiple callbacks for each hotkey without overwriting the - # remover. - _hotkeys[hotkey] = _hotkeys[remove_] = _hotkeys[callback] = remove_ - return remove_ - - state = _State() - state.remove_catch_misses = None - state.remove_last_step = None - state.suppressed_events = [] - state.last_update = float('-inf') - - def catch_misses(event, force_fail=False): - if ( - event.event_type == event_type - and state.index - and event.scan_code not in allowed_keys_by_step[state.index] - ) or ( - timeout - and _time.monotonic() - state.last_update >= timeout - ) or force_fail: # Weird formatting to ensure short-circuit. - - state.remove_last_step() - - for event in state.suppressed_events: - if event.event_type == KEY_DOWN: - press(event.scan_code) - else: - release(event.scan_code) - del state.suppressed_events[:] - - index = 0 - set_index(0) - return True - - def set_index(new_index): - state.index = new_index - - if new_index == 0: - # This is done for performance reasons, avoiding a global key hook - # that is always on. - state.remove_catch_misses = lambda: None - elif new_index == 1: - state.remove_catch_misses() - # Must be `suppress=True` to ensure `send` has priority. - state.remove_catch_misses = hook(catch_misses, suppress=True) - - if new_index == len(steps) - 1: - def handler(event): - if event.event_type == KEY_UP: - remove() - set_index(0) - accept = event.event_type == event_type and callback() - if accept: - return catch_misses(event, force_fail=True) - else: - state.suppressed_events[:] = [event] - return False - remove = _add_hotkey_step(handler, steps[state.index], suppress) - else: - # Fix value of next_index. - def handler(event, new_index=state.index+1): - if event.event_type == KEY_UP: - remove() - set_index(new_index) - state.suppressed_events.append(event) - return False - remove = _add_hotkey_step(handler, steps[state.index], suppress) - state.remove_last_step = remove - state.last_update = _time.monotonic() - return False - set_index(0) - - allowed_keys_by_step = [ - set().union(*step) - for step in steps - ] - - def remove_(): - state.remove_catch_misses() - state.remove_last_step() - del _hotkeys[hotkey] - del _hotkeys[remove_] - del _hotkeys[callback] - # TODO: allow multiple callbacks for each hotkey without overwriting the - # remover. - _hotkeys[hotkey] = _hotkeys[remove_] = _hotkeys[callback] = remove_ - return remove_ -register_hotkey = add_hotkey - -def remove_hotkey(hotkey_or_callback): - """ - Removes a previously hooked hotkey. Must be called wtih the value returned - by `add_hotkey`. - """ - _hotkeys[hotkey_or_callback]() -unregister_hotkey = clear_hotkey = remove_hotkey - -def unhook_all_hotkeys(): - """ - Removes all keyboard hotkeys in use, including abbreviations, word listeners, - `record`ers and `wait`s. - """ - # Because of "alises" some hooks may have more than one entry, all of which - # are removed together. - _listener.blocking_hotkeys.clear() - _listener.nonblocking_hotkeys.clear() -unregister_all_hotkeys = remove_all_hotkeys = clear_all_hotkeys = unhook_all_hotkeys - -def remap_hotkey(src, dst, suppress=True, trigger_on_release=False): - """ - Whenever the hotkey `src` is pressed, suppress it and send - `dst` instead. - - Example: - - remap('alt+w', 'ctrl+up') - """ - def handler(): - active_modifiers = sorted(modifier for modifier, state in _listener.modifier_states.items() if state == 'allowed') - for modifier in active_modifiers: - release(modifier) - send(dst) - for modifier in reversed(active_modifiers): - press(modifier) - return False - return add_hotkey(src, handler, suppress=suppress, trigger_on_release=trigger_on_release) -unremap_hotkey = remove_hotkey - -def stash_state(): - """ - Builds a list of all currently pressed scan codes, releases them and returns - the list. Pairs well with `restore_state` and `restore_modifiers`. - """ - # TODO: stash caps lock / numlock /scrollock state. - with _pressed_events_lock: - state = sorted(_pressed_events) - for scan_code in state: - _os_keyboard.release(scan_code) - return state - -def restore_state(scan_codes): - """ - Given a list of scan_codes ensures these keys, and only these keys, are - pressed. Pairs well with `stash_state`, alternative to `restore_modifiers`. - """ - _listener.is_replaying = True - - with _pressed_events_lock: - current = set(_pressed_events) - target = set(scan_codes) - for scan_code in current - target: - _os_keyboard.release(scan_code) - for scan_code in target - current: - _os_keyboard.press(scan_code) - - _listener.is_replaying = False - -def restore_modifiers(scan_codes): - """ - Like `restore_state`, but only restores modifier keys. - """ - restore_state((scan_code for scan_code in scan_codes if is_modifier(scan_code))) - -def write(text, delay=0, restore_state_after=True, exact=None): - """ - Sends artificial keyboard events to the OS, simulating the typing of a given - text. Characters not available on the keyboard are typed as explicit unicode - characters using OS-specific functionality, such as alt+codepoint. - - To ensure text integrity, all currently pressed keys are released before - the text is typed, and modifiers are restored afterwards. - - - `delay` is the number of seconds to wait between keypresses, defaults to - no delay. - - `restore_state_after` can be used to restore the state of pressed keys - after the text is typed, i.e. presses the keys that were released at the - beginning. Defaults to True. - - `exact` forces typing all characters as explicit unicode (e.g. - alt+codepoint or special events). If None, uses platform-specific suggested - value. - """ - if exact is None: - exact = _platform.system() == 'Windows' - - state = stash_state() - - # Window's typing of unicode characters is quite efficient and should be preferred. - if exact: - for letter in text: - if letter in '\n\b': - send(letter) - else: - _os_keyboard.type_unicode(letter) - if delay: _time.sleep(delay) - else: - for letter in text: - try: - entries = _os_keyboard.map_name(normalize_name(letter)) - scan_code, modifiers = next(iter(entries)) - except (KeyError, ValueError): - _os_keyboard.type_unicode(letter) - continue - - for modifier in modifiers: - press(modifier) - - _os_keyboard.press(scan_code) - _os_keyboard.release(scan_code) - - for modifier in modifiers: - release(modifier) - - if delay: - _time.sleep(delay) - - if restore_state_after: - restore_modifiers(state) - -def wait(hotkey=None, suppress=False, trigger_on_release=False): - """ - Blocks the program execution until the given hotkey is pressed or, - if given no parameters, blocks forever. - """ - if hotkey: - lock = _Event() - remove = add_hotkey(hotkey, lambda: lock.set(), suppress=suppress, trigger_on_release=trigger_on_release) - lock.wait() - remove_hotkey(remove) - else: - while True: - _time.sleep(1e6) - -def get_hotkey_name(names=None): - """ - Returns a string representation of hotkey from the given key names, or - the currently pressed keys if not given. This function: - - - normalizes names; - - removes "left" and "right" prefixes; - - replaces the "+" key name with "plus" to avoid ambiguity; - - puts modifier keys first, in a standardized order; - - sort remaining keys; - - finally, joins everything with "+". - - Example: - - get_hotkey_name(['+', 'left ctrl', 'shift']) - # "ctrl+shift+plus" - """ - if names is None: - _listener.start_if_necessary() - with _pressed_events_lock: - names = [e.name for e in _pressed_events.values()] - else: - names = [normalize_name(name) for name in names] - clean_names = set(e.replace('left ', '').replace('right ', '').replace('+', 'plus') for e in names) - # https://developer.apple.com/macos/human-interface-guidelines/input-and-output/keyboard/ - # > List modifier keys in the correct order. If you use more than one modifier key in a - # > hotkey, always list them in this order: Control, Option, Shift, Command. - modifiers = ['ctrl', 'alt', 'shift', 'windows'] - sorting_key = lambda k: (modifiers.index(k) if k in modifiers else 5, str(k)) - return '+'.join(sorted(clean_names, key=sorting_key)) - -def read_event(suppress=False): - """ - Blocks until a keyboard event happens, then returns that event. - """ - queue = _queue.Queue(maxsize=1) - hooked = hook(queue.put, suppress=suppress) - while True: - event = queue.get() - unhook(hooked) - return event - -def read_key(suppress=False): - """ - Blocks until a keyboard event happens, then returns that event's name or, - if missing, its scan code. - """ - event = read_event(suppress) - return event.name or event.scan_code - -def read_hotkey(suppress=True): - """ - Similar to `read_key()`, but blocks until the user presses and releases a - hotkey (or single key), then returns a string representing the hotkey - pressed. - - Example: - - read_hotkey() - # "ctrl+shift+p" - """ - queue = _queue.Queue() - fn = lambda e: queue.put(e) or e.event_type == KEY_DOWN - hooked = hook(fn, suppress=suppress) - while True: - event = queue.get() - if event.event_type == KEY_UP: - unhook(hooked) - with _pressed_events_lock: - names = [e.name for e in _pressed_events.values()] + [event.name] - return get_hotkey_name(names) - -def get_typed_strings(events, allow_backspace=True): - """ - Given a sequence of events, tries to deduce what strings were typed. - Strings are separated when a non-textual key is pressed (such as tab or - enter). Characters are converted to uppercase according to shift and - capslock status. If `allow_backspace` is True, backspaces remove the last - character typed. - - This function is a generator, so you can pass an infinite stream of events - and convert them to strings in real time. - - Note this functions is merely an heuristic. Windows for example keeps per- - process keyboard state such as keyboard layout, and this information is not - available for our hooks. - - get_type_strings(record()) #-> ['This is what', 'I recorded', ''] - """ - backspace_name = 'delete' if _platform.system() == 'Darwin' else 'backspace' - - shift_pressed = False - capslock_pressed = False - string = '' - for event in events: - name = event.name - - # Space is the only key that we _parse_hotkey to the spelled out name - # because of legibility. Now we have to undo that. - if event.name == 'space': - name = ' ' - - if 'shift' in event.name: - shift_pressed = event.event_type == 'down' - elif event.name == 'caps lock' and event.event_type == 'down': - capslock_pressed = not capslock_pressed - elif allow_backspace and event.name == backspace_name and event.event_type == 'down': - string = string[:-1] - elif event.event_type == 'down': - if len(name) == 1: - if shift_pressed ^ capslock_pressed: - name = name.upper() - string = string + name - else: - yield string - string = '' - yield string - -_recording = None -def start_recording(recorded_events_queue=None): - """ - Starts recording all keyboard events into a global variable, or the given - queue if any. Returns the queue of events and the hooked function. - - Use `stop_recording()` or `unhook(hooked_function)` to stop. - """ - recorded_events_queue = recorded_events_queue or _queue.Queue() - global _recording - _recording = (recorded_events_queue, hook(recorded_events_queue.put)) - return _recording - -def stop_recording(): - """ - Stops the global recording of events and returns a list of the events - captured. - """ - global _recording - if not _recording: - raise ValueError('Must call "start_recording" before.') - recorded_events_queue, hooked = _recording - unhook(hooked) - return list(recorded_events_queue.queue) - -def record(until='escape', suppress=False, trigger_on_release=False): - """ - Records all keyboard events from all keyboards until the user presses the - given hotkey. Then returns the list of events recorded, of type - `keyboard.KeyboardEvent`. Pairs well with - `play(events)`. - - Note: this is a blocking function. - Note: for more details on the keyboard hook and events see `hook`. - """ - start_recording() - wait(until, suppress=suppress, trigger_on_release=trigger_on_release) - return stop_recording() - -def play(events, speed_factor=1.0): - """ - Plays a sequence of recorded events, maintaining the relative time - intervals. If speed_factor is <= 0 then the actions are replayed as fast - as the OS allows. Pairs well with `record()`. - - Note: the current keyboard state is cleared at the beginning and restored at - the end of the function. - """ - state = stash_state() - - last_time = None - for event in events: - if speed_factor > 0 and last_time is not None: - _time.sleep((event.time - last_time) / speed_factor) - last_time = event.time - - key = event.scan_code or event.name - press(key) if event.event_type == KEY_DOWN else release(key) - - restore_modifiers(state) -replay = play - -_word_listeners = {} -def add_word_listener(word, callback, triggers=['space'], match_suffix=False, timeout=2): - """ - Invokes a callback every time a sequence of characters is typed (e.g. 'pet') - and followed by a trigger key (e.g. space). Modifiers (e.g. alt, ctrl, - shift) are ignored. - - - `word` the typed text to be matched. E.g. 'pet'. - - `callback` is an argument-less function to be invoked each time the word - is typed. - - `triggers` is the list of keys that will cause a match to be checked. If - the user presses some key that is not a character (len>1) and not in - triggers, the characters so far will be discarded. By default the trigger - is only `space`. - - `match_suffix` defines if endings of words should also be checked instead - of only whole words. E.g. if true, typing 'carpet'+space will trigger the - listener for 'pet'. Defaults to false, only whole words are checked. - - `timeout` is the maximum number of seconds between typed characters before - the current word is discarded. Defaults to 2 seconds. - - Returns the event handler created. To remove a word listener use - `remove_word_listener(word)` or `remove_word_listener(handler)`. - - Note: all actions are performed on key down. Key up events are ignored. - Note: word mathes are **case sensitive**. - """ - state = _State() - state.current = '' - state.time = -1 - - def handler(event): - name = event.name - if event.event_type == KEY_UP or name in all_modifiers: return - - if timeout and event.time - state.time > timeout: - state.current = '' - state.time = event.time - - matched = state.current == word or (match_suffix and state.current.endswith(word)) - if name in triggers and matched: - callback() - state.current = '' - elif len(name) > 1: - state.current = '' - else: - state.current += name - - hooked = hook(handler) - def remove(): - hooked() - del _word_listeners[word] - del _word_listeners[handler] - del _word_listeners[remove] - _word_listeners[word] = _word_listeners[handler] = _word_listeners[remove] = remove - # TODO: allow multiple word listeners and removing them correctly. - return remove - -def remove_word_listener(word_or_handler): - """ - Removes a previously registered word listener. Accepts either the word used - during registration (exact string) or the event handler returned by the - `add_word_listener` or `add_abbreviation` functions. - """ - _word_listeners[word_or_handler]() - -def add_abbreviation(source_text, replacement_text, match_suffix=False, timeout=2): - """ - Registers a hotkey that replaces one typed text with another. For example - - add_abbreviation('tm', u'™') - - Replaces every "tm" followed by a space with a ™ symbol (and no space). The - replacement is done by sending backspace events. - - - `match_suffix` defines if endings of words should also be checked instead - of only whole words. E.g. if true, typing 'carpet'+space will trigger the - listener for 'pet'. Defaults to false, only whole words are checked. - - `timeout` is the maximum number of seconds between typed characters before - the current word is discarded. Defaults to 2 seconds. - - For more details see `add_word_listener`. - """ - replacement = '\b'*(len(source_text)+1) + replacement_text - callback = lambda: write(replacement) - return add_word_listener(source_text, callback, match_suffix=match_suffix, timeout=timeout) - -# Aliases. -register_word_listener = add_word_listener -register_abbreviation = add_abbreviation -remove_abbreviation = remove_word_listener
\ No newline at end of file diff --git a/Python/venv1/Lib/site-packages/keyboard/__main__.py b/Python/venv1/Lib/site-packages/keyboard/__main__.py deleted file mode 100644 index 3acc6f6..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__main__.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -import keyboard -import fileinput -import json -import sys - -def print_event_json(event): - print(event.to_json(ensure_ascii=sys.stdout.encoding != 'utf-8')) - sys.stdout.flush() -keyboard.hook(print_event_json) - -parse_event_json = lambda line: keyboard.KeyboardEvent(**json.loads(line)) -keyboard.play(parse_event_json(line) for line in fileinput.input())
\ No newline at end of file diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/__init__.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/__init__.cpython-37.pyc Binary files differdeleted file mode 100644 index fde91f0..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/__init__.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/__main__.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/__main__.cpython-37.pyc Binary files differdeleted file mode 100644 index 3150ae2..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/__main__.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_canonical_names.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_canonical_names.cpython-37.pyc Binary files differdeleted file mode 100644 index a53614d..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_canonical_names.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_darwinkeyboard.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_darwinkeyboard.cpython-37.pyc Binary files differdeleted file mode 100644 index 31d5952..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_darwinkeyboard.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_darwinmouse.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_darwinmouse.cpython-37.pyc Binary files differdeleted file mode 100644 index 2adcd9d..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_darwinmouse.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_generic.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_generic.cpython-37.pyc Binary files differdeleted file mode 100644 index 5015aeb..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_generic.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_keyboard_event.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_keyboard_event.cpython-37.pyc Binary files differdeleted file mode 100644 index fd5e6aa..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_keyboard_event.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_keyboard_tests.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_keyboard_tests.cpython-37.pyc Binary files differdeleted file mode 100644 index c79ac7b..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_keyboard_tests.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_mouse_event.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_mouse_event.cpython-37.pyc Binary files differdeleted file mode 100644 index fe34e94..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_mouse_event.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_mouse_tests.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_mouse_tests.cpython-37.pyc Binary files differdeleted file mode 100644 index 9529cb9..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_mouse_tests.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixcommon.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixcommon.cpython-37.pyc Binary files differdeleted file mode 100644 index ed27d59..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixcommon.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixkeyboard.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixkeyboard.cpython-37.pyc Binary files differdeleted file mode 100644 index 3ff8cfa..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixkeyboard.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixmouse.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixmouse.cpython-37.pyc Binary files differdeleted file mode 100644 index c573b2a..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_nixmouse.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_winkeyboard.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_winkeyboard.cpython-37.pyc Binary files differdeleted file mode 100644 index 39a80f5..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_winkeyboard.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_winmouse.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_winmouse.cpython-37.pyc Binary files differdeleted file mode 100644 index 694887c..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_winmouse.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_xlibkeyboard.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/_xlibkeyboard.cpython-37.pyc Binary files differdeleted file mode 100644 index a68a1d2..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/_xlibkeyboard.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/__pycache__/mouse.cpython-37.pyc b/Python/venv1/Lib/site-packages/keyboard/__pycache__/mouse.cpython-37.pyc Binary files differdeleted file mode 100644 index a693bb7..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/__pycache__/mouse.cpython-37.pyc +++ /dev/null diff --git a/Python/venv1/Lib/site-packages/keyboard/_canonical_names.py b/Python/venv1/Lib/site-packages/keyboard/_canonical_names.py deleted file mode 100644 index 003fd3b..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_canonical_names.py +++ /dev/null @@ -1,1246 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -try: - basestring -except NameError: - basestring = str - -import platform - -# Defaults to Windows canonical names (platform-specific overrides below) -canonical_names = { - 'escape': 'esc', - 'return': 'enter', - 'del': 'delete', - 'control': 'ctrl', - - 'left arrow': 'left', - 'up arrow': 'up', - 'down arrow': 'down', - 'right arrow': 'right', - - ' ': 'space', # Prefer to spell out keys that would be hard to read. - '\x1b': 'esc', - '\x08': 'backspace', - '\n': 'enter', - '\t': 'tab', - '\r': 'enter', - - 'scrlk': 'scroll lock', - 'prtscn': 'print screen', - 'prnt scrn': 'print screen', - 'snapshot': 'print screen', - 'ins': 'insert', - 'pause break': 'pause', - 'ctrll lock': 'caps lock', - 'capslock': 'caps lock', - 'number lock': 'num lock', - 'numlock': 'num lock', - 'space bar': 'space', - 'spacebar': 'space', - 'linefeed': 'enter', - 'win': 'windows', - - # Mac keys - 'command': 'windows', - 'cmd': 'windows', - 'control': 'ctrl', - 'option': 'alt', - - 'app': 'menu', - 'apps': 'menu', - 'application': 'menu', - 'applications': 'menu', - - 'pagedown': 'page down', - 'pageup': 'page up', - 'pgdown': 'page down', - 'pgup': 'page up', - - 'play/pause': 'play/pause media', - - 'num multiply': '*', - 'num divide': '/', - 'num add': '+', - 'num plus': '+', - 'num minus': '-', - 'num sub': '-', - 'num enter': 'enter', - 'num 0': '0', - 'num 1': '1', - 'num 2': '2', - 'num 3': '3', - 'num 4': '4', - 'num 5': '5', - 'num 6': '6', - 'num 7': '7', - 'num 8': '8', - 'num 9': '9', - - 'left win': 'left windows', - 'right win': 'right windows', - 'left control': 'left ctrl', - 'right control': 'right ctrl', - 'left menu': 'left alt', # Windows... - 'altgr': 'alt gr', - - # https://www.x.org/releases/X11R7.6/doc/libX11/Compose/en_US.UTF-8.html - # https://svn.apache.org/repos/asf/xmlgraphics/commons/tags/commons-1_0/src/java/org/apache/xmlgraphics/fonts/Glyphs.java - # Note this list has plenty of uppercase letters that are not being used - # at the moment, as normalization forces names to be lowercase. - "Aacute": "Á", - "aacute": "á", - "Aacutesmall": "", - "abovedot": "˙", - "Abreve": "Ă", - "abreve": "ă", - "Abreveacute": "Ắ", - "abreveacute": "ắ", - "Abrevebelowdot": "Ặ", - "abrevebelowdot": "ặ", - "Abrevegrave": "Ằ", - "abrevegrave": "ằ", - "Abrevehook": "Ẳ", - "abrevehook": "ẳ", - "Abrevetilde": "Ẵ", - "abrevetilde": "ẵ", - "Acircumflex": "Â", - "acircumflex": "â", - "Acircumflexacute": "Ấ", - "acircumflexacute": "ấ", - "Acircumflexbelowdot": "Ậ", - "acircumflexbelowdot": "ậ", - "Acircumflexgrave": "Ầ", - "acircumflexgrave": "ầ", - "Acircumflexhook": "Ẩ", - "acircumflexhook": "ẩ", - "Acircumflexsmall": "", - "Acircumflextilde": "Ẫ", - "acircumflextilde": "ẫ", - "acute": "´", - "Acute": "", - "acutecomb": "́", - "Acutesmall": "", - "add": "+", - "Adiaeresis": "Ä", - "adiaeresis": "ä", - "Adieresis": "Ä", - "adieresis": "ä", - "Adieresissmall": "", - "ae": "æ", - "AE": "Æ", - "AEacute": "Ǽ", - "aeacute": "ǽ", - "AEsmall": "", - "afii00208": "―", - "afii10017": "А", - "afii10018": "Б", - "afii10019": "В", - "afii10020": "Г", - "afii10021": "Д", - "afii10022": "Е", - "afii10023": "Ё", - "afii10024": "Ж", - "afii10025": "З", - "afii10026": "И", - "afii10027": "Й", - "afii10028": "К", - "afii10029": "Л", - "afii10030": "М", - "afii10031": "Н", - "afii10032": "О", - "afii10033": "П", - "afii10034": "Р", - "afii10035": "С", - "afii10036": "Т", - "afii10037": "У", - "afii10038": "Ф", - "afii10039": "Х", - "afii10040": "Ц", - "afii10041": "Ч", - "afii10042": "Ш", - "afii10043": "Щ", - "afii10044": "Ъ", - "afii10045": "Ы", - "afii10046": "Ь", - "afii10047": "Э", - "afii10048": "Ю", - "afii10049": "Я", - "afii10050": "Ґ", - "afii10051": "Ђ", - "afii10052": "Ѓ", - "afii10053": "Є", - "afii10054": "Ѕ", - "afii10055": "І", - "afii10056": "Ї", - "afii10057": "Ј", - "afii10058": "Љ", - "afii10059": "Њ", - "afii10060": "Ћ", - "afii10061": "Ќ", - "afii10062": "Ў", - "afii10063": "", - "afii10064": "", - "afii10065": "а", - "afii10066": "б", - "afii10067": "в", - "afii10068": "г", - "afii10069": "д", - "afii10070": "е", - "afii10071": "ё", - "afii10072": "ж", - "afii10073": "з", - "afii10074": "и", - "afii10075": "й", - "afii10076": "к", - "afii10077": "л", - "afii10078": "м", - "afii10079": "н", - "afii10080": "о", - "afii10081": "п", - "afii10082": "р", - "afii10083": "с", - "afii10084": "т", - "afii10085": "у", - "afii10086": "ф", - "afii10087": "х", - "afii10088": "ц", - "afii10089": "ч", - "afii10090": "ш", - "afii10091": "щ", - "afii10092": "ъ", - "afii10093": "ы", - "afii10094": "ь", - "afii10095": "э", - "afii10096": "ю", - "afii10097": "я", - "afii10098": "ґ", - "afii10099": "ђ", - "afii10100": "ѓ", - "afii10101": "є", - "afii10102": "ѕ", - "afii10103": "і", - "afii10104": "ї", - "afii10105": "ј", - "afii10106": "љ", - "afii10107": "њ", - "afii10108": "ћ", - "afii10109": "ќ", - "afii10110": "ў", - "afii10145": "Џ", - "afii10146": "Ѣ", - "afii10147": "Ѳ", - "afii10148": "Ѵ", - "afii10192": "", - "afii10193": "џ", - "afii10194": "ѣ", - "afii10195": "ѳ", - "afii10196": "ѵ", - "afii10831": "", - "afii10832": "", - "afii10846": "ә", - "afii299": "", - "afii300": "", - "afii301": "", - "afii57381": "٪", - "afii57388": "،", - "afii57392": "٠", - "afii57393": "١", - "afii57394": "٢", - "afii57395": "٣", - "afii57396": "٤", - "afii57397": "٥", - "afii57398": "٦", - "afii57399": "٧", - "afii57400": "٨", - "afii57401": "٩", - "afii57403": "؛", - "afii57407": "؟", - "afii57409": "ء", - "afii57410": "آ", - "afii57411": "أ", - "afii57412": "ؤ", - "afii57413": "إ", - "afii57414": "ئ", - "afii57415": "ا", - "afii57416": "ب", - "afii57417": "ة", - "afii57418": "ت", - "afii57419": "ث", - "afii57420": "ج", - "afii57421": "ح", - "afii57422": "خ", - "afii57423": "د", - "afii57424": "ذ", - "afii57425": "ر", - "afii57426": "ز", - "afii57427": "س", - "afii57428": "ش", - "afii57429": "ص", - "afii57430": "ض", - "afii57431": "ط", - "afii57432": "ظ", - "afii57433": "ع", - "afii57434": "غ", - "afii57440": "ـ", - "afii57441": "ف", - "afii57442": "ق", - "afii57443": "ك", - "afii57444": "ل", - "afii57445": "م", - "afii57446": "ن", - "afii57448": "و", - "afii57449": "ى", - "afii57450": "ي", - "afii57451": "ً", - "afii57452": "ٌ", - "afii57453": "ٍ", - "afii57454": "َ", - "afii57455": "ُ", - "afii57456": "ِ", - "afii57457": "ّ", - "afii57458": "ْ", - "afii57470": "ه", - "afii57505": "ڤ", - "afii57506": "پ", - "afii57507": "چ", - "afii57508": "ژ", - "afii57509": "گ", - "afii57511": "ٹ", - "afii57512": "ڈ", - "afii57513": "ڑ", - "afii57514": "ں", - "afii57519": "ے", - "afii57534": "ە", - "afii57636": "₪", - "afii57645": "־", - "afii57658": "׃", - "afii57664": "א", - "afii57665": "ב", - "afii57666": "ג", - "afii57667": "ד", - "afii57668": "ה", - "afii57669": "ו", - "afii57670": "ז", - "afii57671": "ח", - "afii57672": "ט", - "afii57673": "י", - "afii57674": "ך", - "afii57675": "כ", - "afii57676": "ל", - "afii57677": "ם", - "afii57678": "מ", - "afii57679": "ן", - "afii57680": "נ", - "afii57681": "ס", - "afii57682": "ע", - "afii57683": "ף", - "afii57684": "פ", - "afii57685": "ץ", - "afii57686": "צ", - "afii57687": "ק", - "afii57688": "ר", - "afii57689": "ש", - "afii57690": "ת", - "afii57694": "שׁ", - "afii57695": "שׂ", - "afii57700": "וֹ", - "afii57705": "ײַ", - "afii57716": "װ", - "afii57717": "ױ", - "afii57718": "ײ", - "afii57723": "וּ", - "afii57793": "ִ", - "afii57794": "ֵ", - "afii57795": "ֶ", - "afii57796": "ֻ", - "afii57797": "ָ", - "afii57798": "ַ", - "afii57799": "ְ", - "afii57800": "ֲ", - "afii57801": "ֱ", - "afii57802": "ֳ", - "afii57803": "ׂ", - "afii57804": "ׁ", - "afii57806": "ֹ", - "afii57807": "ּ", - "afii57839": "ֽ", - "afii57841": "ֿ", - "afii57842": "׀", - "afii57929": "ʼ", - "afii61248": "℅", - "afii61289": "ℓ", - "afii61352": "№", - "afii61573": "", - "afii61574": "", - "afii61575": "", - "afii61664": "", - "afii63167": "٭", - "afii64937": "ʽ", - "Agrave": "À", - "agrave": "à", - "Agravesmall": "", - "agudo": "´", - "aleph": "ℵ", - "Alpha": "Α", - "alpha": "α", - "Alphatonos": "Ά", - "alphatonos": "ά", - "Amacron": "Ā", - "amacron": "ā", - "ampersand": "&", - "ampersandsmall": "", - "angle": "∠", - "angleleft": "〈", - "angleright": "〉", - "anoteleia": "·", - "Aogonek": "Ą", - "aogonek": "ą", - "apostrophe": "'", - "approxequal": "≈", - "Aring": "Å", - "aring": "å", - "Aringacute": "Ǻ", - "aringacute": "ǻ", - "Aringsmall": "", - "arrowboth": "↔", - "arrowdblboth": "⇔", - "arrowdbldown": "⇓", - "arrowdblleft": "⇐", - "arrowdblright": "⇒", - "arrowdblup": "⇑", - "arrowdown": "↓", - "arrowhorizex": "", - "arrowleft": "←", - "arrowright": "→", - "arrowup": "↑", - "arrowupdn": "↕", - "arrowupdnbse": "↨", - "arrowvertex": "", - "asciicircum": "^", - "asciitilde": "~", - "Asmall": "", - "asterisk": "*", - "asteriskmath": "∗", - "asuperior": "", - "at": "@", - "Atilde": "Ã", - "atilde": "ã", - "Atildesmall": "", - "backslash": "\\", - "bar": "|", - "Beta": "Β", - "beta": "β", - "block": "█", - "braceex": "", - "braceleft": "{", - "braceleftbt": "", - "braceleftmid": "", - "bracelefttp": "", - "braceright": "}", - "bracerightbt": "", - "bracerightmid": "", - "bracerighttp": "", - "bracketleft": "[", - "bracketleftbt": "", - "bracketleftex": "", - "bracketlefttp": "", - "bracketright": "]", - "bracketrightbt": "", - "bracketrightex": "", - "bracketrighttp": "", - "breve": "˘", - "Brevesmall": "", - "brokenbar": "¦", - "Bsmall": "", - "bsuperior": "", - "bullet": "•", - "Cacute": "Ć", - "cacute": "ć", - "caron": "ˇ", - "Caron": "", - "Caronsmall": "", - "carriagereturn": "↵", - "Ccaron": "Č", - "ccaron": "č", - "Ccedilla": "Ç", - "ccedilla": "ç", - "Ccedillasmall": "", - "Ccircumflex": "Ĉ", - "ccircumflex": "ĉ", - "Cdotaccent": "Ċ", - "cdotaccent": "ċ", - "cedilla": "¸", - "Cedillasmall": "", - "cent": "¢", - "centinferior": "", - "centoldstyle": "", - "centsuperior": "", - "Chi": "Χ", - "chi": "χ", - "circle": "○", - "circlemultiply": "⊗", - "circleplus": "⊕", - "circumflex": "^", - "circumflex": "ˆ", - "Circumflexsmall": "", - "club": "♣", - "colon": ":", - "colonmonetary": "₡", - "ColonSign": "₡", - "comma": ",", - "commaaccent": "", - "commainferior": "", - "commasuperior": "", - "congruent": "≅", - "copyright": "©", - "copyrightsans": "", - "copyrightserif": "", - "CruzeiroSign": "₢", - "Csmall": "", - "currency": "¤", - "cyrBreve": "", - "cyrbreve": "", - "cyrFlex": "", - "cyrflex": "", - "dagger": "†", - "daggerdbl": "‡", - "dblGrave": "", - "dblgrave": "", - "Dcaron": "Ď", - "dcaron": "ď", - "Dcroat": "Đ", - "dcroat": "đ", - "degree": "°", - "Delta": "Δ", - "delta": "δ", - "diaeresis": "¨", - "diamond": "♦", - "dieresis": "¨", - "Dieresis": "", - "DieresisAcute": "", - "dieresisacute": "", - "DieresisGrave": "", - "dieresisgrave": "", - "Dieresissmall": "", - "dieresistonos": "΅", - "divide": "/", - "divide": "÷", - "division": "÷", - "dkshade": "▓", - "dnblock": "▄", - "dollar": "$", - "dollarinferior": "", - "dollaroldstyle": "", - "dollarsuperior": "", - "dong": "₫", - "DongSign": "₫", - "dot": ".", - "dotaccent": "˙", - "Dotaccentsmall": "", - "dotbelowcomb": "̣", - "dotlessi": "ı", - "dotlessj": "", - "dotmath": "⋅", - "Dsmall": "", - "dstroke": "đ", - "Dstroke": "Đ", - "dsuperior": "", - "Eacute": "É", - "eacute": "é", - "Eacutesmall": "", - "Ebreve": "Ĕ", - "ebreve": "ĕ", - "Ecaron": "Ě", - "ecaron": "ě", - "Ecircumflex": "Ê", - "ecircumflex": "ê", - "Ecircumflexacute": "Ế", - "ecircumflexacute": "ế", - "Ecircumflexbelowdot": "Ệ", - "ecircumflexbelowdot": "ệ", - "Ecircumflexgrave": "Ề", - "ecircumflexgrave": "ề", - "Ecircumflexhook": "Ể", - "ecircumflexhook": "ể", - "Ecircumflexsmall": "", - "Ecircumflextilde": "Ễ", - "ecircumflextilde": "ễ", - "EcuSign": "₠", - "Ediaeresis": "Ë", - "ediaeresis": "ë", - "Edieresis": "Ë", - "edieresis": "ë", - "Edieresissmall": "", - "Edotaccent": "Ė", - "edotaccent": "ė", - "Egrave": "È", - "egrave": "è", - "Egravesmall": "", - "eight": "8", - "eightinferior": "₈", - "eightoldstyle": "", - "eightsubscript": "₈", - "eightsuperior": "⁸", - "element": "∈", - "ellipsis": "…", - "Emacron": "Ē", - "emacron": "ē", - "emdash": "—", - "emptyset": "∅", - "endash": "–", - "enfilledcircbullet": "•", - "Eng": "Ŋ", - "eng": "ŋ", - "Eogonek": "Ę", - "eogonek": "ę", - "Epsilon": "Ε", - "epsilon": "ε", - "Epsilontonos": "Έ", - "epsilontonos": "έ", - "equal": "=", - "equivalence": "≡", - "Esmall": "", - "estimated": "℮", - "esuperior": "", - "Eta": "Η", - "eta": "η", - "Etatonos": "Ή", - "etatonos": "ή", - "ETH": "Ð", - "eth": "ð", - "Eth": "Ð", - "Ethsmall": "", - "euro": "€", - "Euro": "€", - "EuroSign": "€", - "exclam": "!", - "exclamdbl": "‼", - "exclamdown": "¡", - "exclamdownsmall": "", - "exclamsmall": "", - "existential": "∃", - "female": "♀", - "ff": "ff", - "ffi": "ffi", - "ffl": "ffl", - "FFrancSign": "₣", - "fi": "fi", - "figuredash": "‒", - "filledbox": "■", - "filledrect": "▬", - "five": "5", - "fiveeighths": "⅝", - "fiveinferior": "₅", - "fiveoldstyle": "", - "fivesubscript": "₅", - "fivesuperior": "⁵", - "fl": "fl", - "florin": "ƒ", - "four": "4", - "fourinferior": "₄", - "fouroldstyle": "", - "foursubscript": "₄", - "foursuperior": "⁴", - "fraction": "∕", - "franc": "₣", - "Fsmall": "", - "function": "ƒ", - "Gamma": "Γ", - "gamma": "γ", - "Gbreve": "Ğ", - "gbreve": "ğ", - "Gcaron": "Ǧ", - "gcaron": "ǧ", - "Gcircumflex": "Ĝ", - "gcircumflex": "ĝ", - "Gcommaaccent": "Ģ", - "gcommaaccent": "ģ", - "Gdotaccent": "Ġ", - "gdotaccent": "ġ", - "germandbls": "ß", - "gradient": "∇", - "grave": "`", - "Grave": "", - "gravecomb": "̀", - "Gravesmall": "", - "greater": ">", - "greaterequal": "≥", - "Gsmall": "", - "guillemotleft": "«", - "guillemotright": "»", - "guilsinglleft": "‹", - "guilsinglright": "›", - "H18533": "●", - "H18543": "▪", - "H18551": "▫", - "H22073": "□", - "hash": "#", - "hashtag": "#", - "Hbar": "Ħ", - "hbar": "ħ", - "Hcircumflex": "Ĥ", - "hcircumflex": "ĥ", - "heart": "♥", - "hookabovecomb": "̉", - "house": "⌂", - "Hsmall": "", - "hungarumlaut": "˝", - "Hungarumlaut": "", - "Hungarumlautsmall": "", - "hyphen": "", - "hypheninferior": "", - "hyphensuperior": "", - "Iacute": "Í", - "iacute": "í", - "Iacutesmall": "", - "Ibreve": "Ĭ", - "ibreve": "ĭ", - "Icircumflex": "Î", - "icircumflex": "î", - "Icircumflexsmall": "", - "Idiaeresis": "Ï", - "idiaeresis": "ï", - "Idieresis": "Ï", - "idieresis": "ï", - "Idieresissmall": "", - "Idotaccent": "İ", - "Ifraktur": "ℑ", - "Igrave": "Ì", - "igrave": "ì", - "Igravesmall": "", - "IJ": "IJ", - "ij": "ij", - "Imacron": "Ī", - "imacron": "ī", - "infinity": "∞", - "integral": "∫", - "integralbt": "⌡", - "integralex": "", - "integraltp": "⌠", - "intersection": "∩", - "invbullet": "◘", - "invcircle": "◙", - "invsmileface": "☻", - "Iogonek": "Į", - "iogonek": "į", - "Iota": "Ι", - "iota": "ι", - "Iotadieresis": "Ϊ", - "iotadieresis": "ϊ", - "iotadieresistonos": "ΐ", - "Iotatonos": "Ί", - "iotatonos": "ί", - "Ismall": "", - "isuperior": "", - "Itilde": "Ĩ", - "itilde": "ĩ", - "Jcircumflex": "Ĵ", - "jcircumflex": "ĵ", - "Jsmall": "", - "Kappa": "Κ", - "kappa": "κ", - "Kcommaaccent": "Ķ", - "kcommaaccent": "ķ", - "kgreenlandic": "ĸ", - "Ksmall": "", - "Lacute": "Ĺ", - "lacute": "ĺ", - "Lambda": "Λ", - "lambda": "λ", - "Lcaron": "Ľ", - "lcaron": "ľ", - "Lcommaaccent": "Ļ", - "lcommaaccent": "ļ", - "Ldot": "Ŀ", - "ldot": "ŀ", - "less": "<", - "lessequal": "≤", - "lfblock": "▌", - "lira": "₤", - "LiraSign": "₤", - "LL": "", - "ll": "", - "logicaland": "∧", - "logicalnot": "¬", - "logicalor": "∨", - "longs": "ſ", - "lozenge": "◊", - "Lslash": "Ł", - "lslash": "ł", - "Lslashsmall": "", - "Lsmall": "", - "lsuperior": "", - "ltshade": "░", - "macron": "¯", - "macron": "ˉ", - "Macron": "", - "Macronsmall": "", - "male": "♂", - "masculine": "º", - "MillSign": "₥", - "minplus": "+", - "minus": "-", - "minus": "−", - "minute": "′", - "Msmall": "", - "msuperior": "", - "mu": "µ", - "Mu": "Μ", - "mu": "μ", - "multiply": "*", - "multiply": "×", - "musicalnote": "♪", - "musicalnotedbl": "♫", - "Nacute": "Ń", - "nacute": "ń", - "NairaSign": "₦", - "napostrophe": "ʼn", - "Ncaron": "Ň", - "ncaron": "ň", - "Ncommaaccent": "Ņ", - "ncommaaccent": "ņ", - "NewSheqelSign": "₪", - "nine": "9", - "nineinferior": "₉", - "nineoldstyle": "", - "ninesubscript": "₉", - "ninesuperior": "⁹", - "nobreakspace": " ", - "notelement": "∉", - "notequal": "≠", - "notsign": "¬", - "notsubset": "⊄", - "Nsmall": "", - "nsuperior": "ⁿ", - "Ntilde": "Ñ", - "ntilde": "ñ", - "Ntildesmall": "", - "Nu": "Ν", - "nu": "ν", - "numbersign": "#", - "numerosign": "№", - "Oacute": "Ó", - "oacute": "ó", - "Oacutesmall": "", - "Obreve": "Ŏ", - "obreve": "ŏ", - "Ocircumflex": "Ô", - "ocircumflex": "ô", - "Ocircumflexacute": "Ố", - "ocircumflexacute": "ố", - "Ocircumflexbelowdot": "Ộ", - "ocircumflexbelowdot": "ộ", - "Ocircumflexgrave": "Ồ", - "ocircumflexgrave": "ồ", - "Ocircumflexhook": "Ổ", - "ocircumflexhook": "ổ", - "Ocircumflexsmall": "", - "Ocircumflextilde": "Ỗ", - "ocircumflextilde": "ỗ", - "Odiaeresis": "Ö", - "odiaeresis": "ö", - "Odieresis": "Ö", - "odieresis": "ö", - "Odieresissmall": "", - "oe": "œ", - "OE": "Œ", - "OEsmall": "", - "ogonek": "˛", - "Ogoneksmall": "", - "Ograve": "Ò", - "ograve": "ò", - "Ogravesmall": "", - "Ohorn": "Ơ", - "ohorn": "ơ", - "Ohornacute": "Ớ", - "ohornacute": "ớ", - "Ohornbelowdot": "Ợ", - "ohornbelowdot": "ợ", - "Ohorngrave": "Ờ", - "ohorngrave": "ờ", - "Ohornhook": "Ở", - "ohornhook": "ở", - "Ohorntilde": "Ỡ", - "ohorntilde": "ỡ", - "Ohungarumlaut": "Ő", - "ohungarumlaut": "ő", - "Omacron": "Ō", - "omacron": "ō", - "Omega": "Ω", - "omega": "ω", - "omega1": "ϖ", - "Omegatonos": "Ώ", - "omegatonos": "ώ", - "Omicron": "Ο", - "omicron": "ο", - "Omicrontonos": "Ό", - "omicrontonos": "ό", - "one": "1", - "onedotenleader": "․", - "oneeighth": "⅛", - "onefitted": "", - "onehalf": "½", - "oneinferior": "₁", - "oneoldstyle": "", - "onequarter": "¼", - "onesubscript": "₁", - "onesuperior": "¹", - "onethird": "⅓", - "openbullet": "◦", - "ordfeminine": "ª", - "ordmasculine": "º", - "orthogonal": "∟", - "Oslash": "Ø", - "oslash": "ø", - "Oslashacute": "Ǿ", - "oslashacute": "ǿ", - "Oslashsmall": "", - "Osmall": "", - "osuperior": "", - "Otilde": "Õ", - "otilde": "õ", - "Otildesmall": "", - "paragraph": "¶", - "parenleft": "(", - "parenleftbt": "", - "parenleftex": "", - "parenleftinferior": "₍", - "parenleftsuperior": "⁽", - "parenlefttp": "", - "parenright": ")", - "parenrightbt": "", - "parenrightex": "", - "parenrightinferior": "₎", - "parenrightsuperior": "⁾", - "parenrighttp": "", - "partialdiff": "∂", - "percent": "%", - "period": ".", - "periodcentered": "·", - "periodcentered": "∙", - "periodinferior": "", - "periodsuperior": "", - "perpendicular": "⊥", - "perthousand": "‰", - "peseta": "₧", - "PesetaSign": "₧", - "Phi": "Φ", - "phi": "φ", - "phi1": "ϕ", - "Pi": "Π", - "pi": "π", - "plus": "+", - "plusminus": "±", - "pound": "£", - "prescription": "℞", - "product": "∏", - "propersubset": "⊂", - "propersuperset": "⊃", - "proportional": "∝", - "Psi": "Ψ", - "psi": "ψ", - "Psmall": "", - "Qsmall": "", - "question": "?", - "questiondown": "¿", - "questiondownsmall": "", - "questionsmall": "", - "quotedbl": "\"", - "quotedblbase": "„", - "quotedblleft": "“", - "quotedblright": "”", - "quoteleft": "‘", - "quotereversed": "‛", - "quoteright": "’", - "quotesinglbase": "‚", - "quotesingle": "'", - "Racute": "Ŕ", - "racute": "ŕ", - "radical": "√", - "radicalex": "", - "Rcaron": "Ř", - "rcaron": "ř", - "Rcommaaccent": "Ŗ", - "rcommaaccent": "ŗ", - "reflexsubset": "⊆", - "reflexsuperset": "⊇", - "registered": "®", - "registersans": "", - "registerserif": "", - "revlogicalnot": "⌐", - "Rfraktur": "ℜ", - "Rho": "Ρ", - "rho": "ρ", - "ring": "˚", - "Ringsmall": "", - "Rsmall": "", - "rsuperior": "", - "rtblock": "▐", - "RupeeSign": "₨", - "rupiah": "", - "Sacute": "Ś", - "sacute": "ś", - "Scaron": "Š", - "scaron": "š", - "Scaronsmall": "", - "Scedilla": "", - "scedilla": "", - "Scircumflex": "Ŝ", - "scircumflex": "ŝ", - "Scommaaccent": "Ș", - "scommaaccent": "ș", - "second": "″", - "section": "§", - "semicolon": ";", - "seven": "7", - "seveneighths": "⅞", - "seveninferior": "₇", - "sevenoldstyle": "", - "sevensubscript": "₇", - "sevensuperior": "⁷", - "SF010000": "┌", - "SF020000": "└", - "SF030000": "┐", - "SF040000": "┘", - "SF050000": "┼", - "SF060000": "┬", - "SF070000": "┴", - "SF080000": "├", - "SF090000": "┤", - "SF100000": "─", - "SF110000": "│", - "SF190000": "╡", - "SF200000": "╢", - "SF210000": "╖", - "SF220000": "╕", - "SF230000": "╣", - "SF240000": "║", - "SF250000": "╗", - "SF260000": "╝", - "SF270000": "╜", - "SF280000": "╛", - "SF360000": "╞", - "SF370000": "╟", - "SF380000": "╚", - "SF390000": "╔", - "SF400000": "╩", - "SF410000": "╦", - "SF420000": "╠", - "SF430000": "═", - "SF440000": "╬", - "SF450000": "╧", - "SF460000": "╨", - "SF470000": "╤", - "SF480000": "╥", - "SF490000": "╙", - "SF500000": "╘", - "SF510000": "╒", - "SF520000": "╓", - "SF530000": "╫", - "SF540000": "╪", - "shade": "▒", - "Sigma": "Σ", - "sigma": "σ", - "sigma1": "ς", - "similar": "∼", - "similarequal": "≃", - "six": "6", - "sixinferior": "₆", - "sixoldstyle": "", - "sixsubscript": "₆", - "sixsuperior": "⁶", - "slash": "/", - "smileface": "☺", - "spade": "♠", - "ssharp": "§", - "ssharp": "ß", - "Ssharp": "ẞ", - "Ssmall": "", - "ssuperior": "", - "sterling": "£", - "subtract": "-", - "suchthat": "∋", - "summation": "∑", - "sun": "☼", - "Tau": "Τ", - "tau": "τ", - "Tbar": "Ŧ", - "tbar": "ŧ", - "Tcaron": "Ť", - "tcaron": "ť", - "Tcommaaccent": "Ț", - "tcommaaccent": "ț", - "Thai_baht": "฿", - "therefore": "∴", - "Theta": "Θ", - "theta": "θ", - "theta1": "ϑ", - "THORN": "Þ", - "thorn": "þ", - "Thorn": "Þ", - "Thornsmall": "", - "three": "3", - "threeeighths": "⅜", - "threeinferior": "₃", - "threeoldstyle": "", - "threequarters": "¾", - "threequartersemdash": "", - "threesubscript": "₃", - "threesuperior": "³", - "til": "~", - "tilde": "~", - "tilde": "˜", - "tildecomb": "̃", - "Tildesmall": "", - "tonos": "΄", - "trademark": "™", - "trademarksans": "", - "trademarkserif": "", - "triagdn": "▼", - "triaglf": "◄", - "triagrt": "►", - "triagup": "▲", - "Tsmall": "", - "tsuperior": "", - "two": "2", - "twodotenleader": "‥", - "twoinferior": "₂", - "twooldstyle": "", - "twosubscript": "₂", - "twosuperior": "²", - "twothirds": "⅔", - "Uacute": "Ú", - "uacute": "ú", - "Uacutesmall": "", - "Ubreve": "Ŭ", - "ubreve": "ŭ", - "Ucircumflex": "Û", - "ucircumflex": "û", - "Ucircumflexsmall": "", - "Udiaeresis": "Ü", - "udiaeresis": "ü", - "Udieresis": "Ü", - "udieresis": "ü", - "Udieresissmall": "", - "Ugrave": "Ù", - "ugrave": "ù", - "Ugravesmall": "", - "Uhorn": "Ư", - "uhorn": "ư", - "Uhornacute": "Ứ", - "uhornacute": "ứ", - "Uhornbelowdot": "Ự", - "uhornbelowdot": "ự", - "Uhorngrave": "Ừ", - "uhorngrave": "ừ", - "Uhornhook": "Ử", - "uhornhook": "ử", - "Uhorntilde": "Ữ", - "uhorntilde": "ữ", - "Uhungarumlaut": "Ű", - "uhungarumlaut": "ű", - "Umacron": "Ū", - "umacron": "ū", - "underscore": "_", - "underscoredbl": "‗", - "union": "∪", - "universal": "∀", - "Uogonek": "Ų", - "uogonek": "ų", - "upblock": "▀", - "Upsilon": "Υ", - "upsilon": "υ", - "Upsilon1": "ϒ", - "Upsilondieresis": "Ϋ", - "upsilondieresis": "ϋ", - "upsilondieresistonos": "ΰ", - "Upsilontonos": "Ύ", - "upsilontonos": "ύ", - "Uring": "Ů", - "uring": "ů", - "Usmall": "", - "Utilde": "Ũ", - "utilde": "ũ", - "Vsmall": "", - "Wacute": "Ẃ", - "wacute": "ẃ", - "Wcircumflex": "Ŵ", - "wcircumflex": "ŵ", - "Wdieresis": "Ẅ", - "wdieresis": "ẅ", - "weierstrass": "℘", - "Wgrave": "Ẁ", - "wgrave": "ẁ", - "WonSign": "₩", - "Wsmall": "", - "Xi": "Ξ", - "xi": "ξ", - "Xsmall": "", - "Yacute": "Ý", - "yacute": "ý", - "Yacutesmall": "", - "Ycircumflex": "Ŷ", - "ycircumflex": "ŷ", - "ydiaeresis": "ÿ", - "Ydieresis": "Ÿ", - "ydieresis": "ÿ", - "Ydieresissmall": "", - "yen": "¥", - "Ygrave": "Ỳ", - "ygrave": "ỳ", - "Ysmall": "", - "Zacute": "Ź", - "zacute": "ź", - "Zcaron": "Ž", - "zcaron": "ž", - "Zcaronsmall": "", - "Zdotaccent": "Ż", - "zdotaccent": "ż", - "zero": "0", - "zeroinferior": "₀", - "zerooldstyle": "", - "zerosubscript": "₀", - "zerosuperior": "⁰", - "zeta": "ζ", - "Zeta": "Ζ", - "Zsmall": "", -} -sided_modifiers = {'ctrl', 'alt', 'shift', 'windows'} -all_modifiers = {'alt', 'alt gr', 'ctrl', 'shift', 'windows'} | set('left ' + n for n in sided_modifiers) | set('right ' + n for n in sided_modifiers) - -# Platform-specific canonical overrides - -if platform.system() == 'Darwin': - canonical_names.update({ - "command": "command", - "windows": "command", - "cmd": "command", - "win": "command", - "backspace": "delete", - 'alt gr': 'alt' # Issue #117 - }) - all_modifiers = {'alt', 'ctrl', 'shift', 'windows'} -if platform.system() == 'Linux': - canonical_names.update({ - "select": "end", - "find": "home", - 'next': 'page down', - 'prior': 'page up', - }) - -def normalize_name(name): - """ - Given a key name (e.g. "LEFT CONTROL"), clean up the string and convert to - the canonical representation (e.g. "left ctrl") if one is known. - """ - if not name or not isinstance(name, basestring): - raise ValueError('Can only normalize non-empty string names. Unexpected '+ repr(name)) - - if len(name) > 1: - name = name.lower() - if name != '_' and '_' in name: - name = name.replace('_', ' ') - - return canonical_names.get(name, name) diff --git a/Python/venv1/Lib/site-packages/keyboard/_darwinkeyboard.py b/Python/venv1/Lib/site-packages/keyboard/_darwinkeyboard.py deleted file mode 100644 index 85670ee..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_darwinkeyboard.py +++ /dev/null @@ -1,442 +0,0 @@ -import ctypes -import ctypes.util -import Quartz -import time -import os -import threading -from AppKit import NSEvent -from ._keyboard_event import KeyboardEvent, KEY_DOWN, KEY_UP -from ._canonical_names import normalize_name - -try: # Python 2/3 compatibility - unichr -except NameError: - unichr = chr - -Carbon = ctypes.cdll.LoadLibrary(ctypes.util.find_library('Carbon')) - -class KeyMap(object): - non_layout_keys = dict((vk, normalize_name(name)) for vk, name in { - # Layout specific keys from https://stackoverflow.com/a/16125341/252218 - # Unfortunately no source for layout-independent keys was found. - 0x24: 'return', - 0x30: 'tab', - 0x31: 'space', - 0x33: 'delete', - 0x35: 'escape', - 0x37: 'command', - 0x38: 'shift', - 0x39: 'capslock', - 0x3a: 'option', - 0x3b: 'control', - 0x3c: 'right shift', - 0x3d: 'right option', - 0x3e: 'right control', - 0x3f: 'function', - 0x40: 'f17', - 0x48: 'volume up', - 0x49: 'volume down', - 0x4a: 'mute', - 0x4f: 'f18', - 0x50: 'f19', - 0x5a: 'f20', - 0x60: 'f5', - 0x61: 'f6', - 0x62: 'f7', - 0x63: 'f3', - 0x64: 'f8', - 0x65: 'f9', - 0x67: 'f11', - 0x69: 'f13', - 0x6a: 'f16', - 0x6b: 'f14', - 0x6d: 'f10', - 0x6f: 'f12', - 0x71: 'f15', - 0x72: 'help', - 0x73: 'home', - 0x74: 'page up', - 0x75: 'forward delete', - 0x76: 'f4', - 0x77: 'end', - 0x78: 'f2', - 0x79: 'page down', - 0x7a: 'f1', - 0x7b: 'left', - 0x7c: 'right', - 0x7d: 'down', - 0x7e: 'up', - }.items()) - layout_specific_keys = {} - def __init__(self): - # Virtual key codes are usually the same for any given key, unless you have a different - # keyboard layout. The only way I've found to determine the layout relies on (supposedly - # deprecated) Carbon APIs. If there's a more modern way to do this, please update this - # section. - - # Set up data types and exported values: - - CFTypeRef = ctypes.c_void_p - CFDataRef = ctypes.c_void_p - CFIndex = ctypes.c_uint64 - OptionBits = ctypes.c_uint32 - UniCharCount = ctypes.c_uint8 - UniChar = ctypes.c_uint16 - UniChar4 = UniChar * 4 - - class CFRange(ctypes.Structure): - _fields_ = [('loc', CFIndex), - ('len', CFIndex)] - - kTISPropertyUnicodeKeyLayoutData = ctypes.c_void_p.in_dll(Carbon, 'kTISPropertyUnicodeKeyLayoutData') - shiftKey = 0x0200 - alphaKey = 0x0400 - optionKey = 0x0800 - controlKey = 0x1000 - kUCKeyActionDisplay = 3 - kUCKeyTranslateNoDeadKeysBit = 0 - - # Set up function calls: - Carbon.CFDataGetBytes.argtypes = [CFDataRef] #, CFRange, UInt8 - Carbon.CFDataGetBytes.restype = None - Carbon.CFDataGetLength.argtypes = [CFDataRef] - Carbon.CFDataGetLength.restype = CFIndex - Carbon.CFRelease.argtypes = [CFTypeRef] - Carbon.CFRelease.restype = None - Carbon.LMGetKbdType.argtypes = [] - Carbon.LMGetKbdType.restype = ctypes.c_uint32 - Carbon.TISCopyCurrentKeyboardInputSource.argtypes = [] - Carbon.TISCopyCurrentKeyboardInputSource.restype = ctypes.c_void_p - Carbon.TISCopyCurrentASCIICapableKeyboardLayoutInputSource.argtypes = [] - Carbon.TISCopyCurrentASCIICapableKeyboardLayoutInputSource.restype = ctypes.c_void_p - Carbon.TISGetInputSourceProperty.argtypes = [ctypes.c_void_p, ctypes.c_void_p] - Carbon.TISGetInputSourceProperty.restype = ctypes.c_void_p - Carbon.UCKeyTranslate.argtypes = [ctypes.c_void_p, - ctypes.c_uint16, - ctypes.c_uint16, - ctypes.c_uint32, - ctypes.c_uint32, - OptionBits, # keyTranslateOptions - ctypes.POINTER(ctypes.c_uint32), # deadKeyState - UniCharCount, # maxStringLength - ctypes.POINTER(UniCharCount), # actualStringLength - UniChar4] - Carbon.UCKeyTranslate.restype = ctypes.c_uint32 - - # Get keyboard layout - klis = Carbon.TISCopyCurrentKeyboardInputSource() - k_layout = Carbon.TISGetInputSourceProperty(klis, kTISPropertyUnicodeKeyLayoutData) - if k_layout is None: - klis = Carbon.TISCopyCurrentASCIICapableKeyboardLayoutInputSource() - k_layout = Carbon.TISGetInputSourceProperty(klis, kTISPropertyUnicodeKeyLayoutData) - k_layout_size = Carbon.CFDataGetLength(k_layout) - k_layout_buffer = ctypes.create_string_buffer(k_layout_size) # TODO - Verify this works instead of initializing with empty string - Carbon.CFDataGetBytes(k_layout, CFRange(0, k_layout_size), ctypes.byref(k_layout_buffer)) - - # Generate character representations of key codes - for key_code in range(0, 128): - # TODO - Possibly add alt modifier to key map - non_shifted_char = UniChar4() - shifted_char = UniChar4() - keys_down = ctypes.c_uint32() - char_count = UniCharCount() - - retval = Carbon.UCKeyTranslate(k_layout_buffer, - key_code, - kUCKeyActionDisplay, - 0, # No modifier - Carbon.LMGetKbdType(), - kUCKeyTranslateNoDeadKeysBit, - ctypes.byref(keys_down), - 4, - ctypes.byref(char_count), - non_shifted_char) - - non_shifted_key = u''.join(unichr(non_shifted_char[i]) for i in range(char_count.value)) - - retval = Carbon.UCKeyTranslate(k_layout_buffer, - key_code, - kUCKeyActionDisplay, - shiftKey >> 8, # Shift - Carbon.LMGetKbdType(), - kUCKeyTranslateNoDeadKeysBit, - ctypes.byref(keys_down), - 4, - ctypes.byref(char_count), - shifted_char) - - shifted_key = u''.join(unichr(shifted_char[i]) for i in range(char_count.value)) - - self.layout_specific_keys[key_code] = (non_shifted_key, shifted_key) - # Cleanup - Carbon.CFRelease(klis) - - def character_to_vk(self, character): - """ Returns a tuple of (scan_code, modifiers) where ``scan_code`` is a numeric scan code - and ``modifiers`` is an array of string modifier names (like 'shift') """ - for vk in self.non_layout_keys: - if self.non_layout_keys[vk] == character.lower(): - return (vk, []) - for vk in self.layout_specific_keys: - if self.layout_specific_keys[vk][0] == character: - return (vk, []) - elif self.layout_specific_keys[vk][1] == character: - return (vk, ['shift']) - raise ValueError("Unrecognized character: {}".format(character)) - - def vk_to_character(self, vk, modifiers=[]): - """ Returns a character corresponding to the specified scan code (with given - modifiers applied) """ - if vk in self.non_layout_keys: - # Not a character - return self.non_layout_keys[vk] - elif vk in self.layout_specific_keys: - if 'shift' in modifiers: - return self.layout_specific_keys[vk][1] - return self.layout_specific_keys[vk][0] - else: - # Invalid vk - raise ValueError("Invalid scan code: {}".format(vk)) - - -class KeyController(object): - def __init__(self): - self.key_map = KeyMap() - self.current_modifiers = { - "shift": False, - "caps": False, - "alt": False, - "ctrl": False, - "cmd": False, - } - self.media_keys = { - 'KEYTYPE_SOUND_UP': 0, - 'KEYTYPE_SOUND_DOWN': 1, - 'KEYTYPE_BRIGHTNESS_UP': 2, - 'KEYTYPE_BRIGHTNESS_DOWN': 3, - 'KEYTYPE_CAPS_LOCK': 4, - 'KEYTYPE_HELP': 5, - 'POWER_KEY': 6, - 'KEYTYPE_MUTE': 7, - 'UP_ARROW_KEY': 8, - 'DOWN_ARROW_KEY': 9, - 'KEYTYPE_NUM_LOCK': 10, - 'KEYTYPE_CONTRAST_UP': 11, - 'KEYTYPE_CONTRAST_DOWN': 12, - 'KEYTYPE_LAUNCH_PANEL': 13, - 'KEYTYPE_EJECT': 14, - 'KEYTYPE_VIDMIRROR': 15, - 'KEYTYPE_PLAY': 16, - 'KEYTYPE_NEXT': 17, - 'KEYTYPE_PREVIOUS': 18, - 'KEYTYPE_FAST': 19, - 'KEYTYPE_REWIND': 20, - 'KEYTYPE_ILLUMINATION_UP': 21, - 'KEYTYPE_ILLUMINATION_DOWN': 22, - 'KEYTYPE_ILLUMINATION_TOGGLE': 23 - } - - def press(self, key_code): - """ Sends a 'down' event for the specified scan code """ - if key_code >= 128: - # Media key - ev = NSEvent.otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_( - 14, # type - (0, 0), # location - 0xa00, # flags - 0, # timestamp - 0, # window - 0, # ctx - 8, # subtype - ((key_code-128) << 16) | (0xa << 8), # data1 - -1 # data2 - ) - Quartz.CGEventPost(0, ev.CGEvent()) - else: - # Regular key - # Apply modifiers if necessary - event_flags = 0 - if self.current_modifiers["shift"]: - event_flags += Quartz.kCGEventFlagMaskShift - if self.current_modifiers["caps"]: - event_flags += Quartz.kCGEventFlagMaskAlphaShift - if self.current_modifiers["alt"]: - event_flags += Quartz.kCGEventFlagMaskAlternate - if self.current_modifiers["ctrl"]: - event_flags += Quartz.kCGEventFlagMaskControl - if self.current_modifiers["cmd"]: - event_flags += Quartz.kCGEventFlagMaskCommand - - # Update modifiers if necessary - if key_code == 0x37: # cmd - self.current_modifiers["cmd"] = True - elif key_code == 0x38 or key_code == 0x3C: # shift or right shift - self.current_modifiers["shift"] = True - elif key_code == 0x39: # caps lock - self.current_modifiers["caps"] = True - elif key_code == 0x3A: # alt - self.current_modifiers["alt"] = True - elif key_code == 0x3B: # ctrl - self.current_modifiers["ctrl"] = True - event = Quartz.CGEventCreateKeyboardEvent(None, key_code, True) - Quartz.CGEventSetFlags(event, event_flags) - Quartz.CGEventPost(Quartz.kCGHIDEventTap, event) - time.sleep(0.01) - - def release(self, key_code): - """ Sends an 'up' event for the specified scan code """ - if key_code >= 128: - # Media key - ev = NSEvent.otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_( - 14, # type - (0, 0), # location - 0xb00, # flags - 0, # timestamp - 0, # window - 0, # ctx - 8, # subtype - ((key_code-128) << 16) | (0xb << 8), # data1 - -1 # data2 - ) - Quartz.CGEventPost(0, ev.CGEvent()) - else: - # Regular key - # Update modifiers if necessary - if key_code == 0x37: # cmd - self.current_modifiers["cmd"] = False - elif key_code == 0x38 or key_code == 0x3C: # shift or right shift - self.current_modifiers["shift"] = False - elif key_code == 0x39: # caps lock - self.current_modifiers["caps"] = False - elif key_code == 0x3A: # alt - self.current_modifiers["alt"] = False - elif key_code == 0x3B: # ctrl - self.current_modifiers["ctrl"] = False - - # Apply modifiers if necessary - event_flags = 0 - if self.current_modifiers["shift"]: - event_flags += Quartz.kCGEventFlagMaskShift - if self.current_modifiers["caps"]: - event_flags += Quartz.kCGEventFlagMaskAlphaShift - if self.current_modifiers["alt"]: - event_flags += Quartz.kCGEventFlagMaskAlternate - if self.current_modifiers["ctrl"]: - event_flags += Quartz.kCGEventFlagMaskControl - if self.current_modifiers["cmd"]: - event_flags += Quartz.kCGEventFlagMaskCommand - event = Quartz.CGEventCreateKeyboardEvent(None, key_code, False) - Quartz.CGEventSetFlags(event, event_flags) - Quartz.CGEventPost(Quartz.kCGHIDEventTap, event) - time.sleep(0.01) - - def map_char(self, character): - if character in self.media_keys: - return (128+self.media_keys[character],[]) - else: - return self.key_map.character_to_vk(character) - def map_scan_code(self, scan_code): - if scan_code >= 128: - character = [k for k, v in enumerate(self.media_keys) if v == scan_code-128] - if len(character): - return character[0] - return None - else: - return self.key_map.vk_to_character(scan_code) - -class KeyEventListener(object): - def __init__(self, callback, blocking=False): - self.blocking = blocking - self.callback = callback - self.listening = True - self.tap = None - - def run(self): - """ Creates a listener and loops while waiting for an event. Intended to run as - a background thread. """ - self.tap = Quartz.CGEventTapCreate( - Quartz.kCGSessionEventTap, - Quartz.kCGHeadInsertEventTap, - Quartz.kCGEventTapOptionDefault, - Quartz.CGEventMaskBit(Quartz.kCGEventKeyDown) | - Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp) | - Quartz.CGEventMaskBit(Quartz.kCGEventFlagsChanged), - self.handler, - None) - loopsource = Quartz.CFMachPortCreateRunLoopSource(None, self.tap, 0) - loop = Quartz.CFRunLoopGetCurrent() - Quartz.CFRunLoopAddSource(loop, loopsource, Quartz.kCFRunLoopDefaultMode) - Quartz.CGEventTapEnable(self.tap, True) - - while self.listening: - Quartz.CFRunLoopRunInMode(Quartz.kCFRunLoopDefaultMode, 5, False) - - def handler(self, proxy, e_type, event, refcon): - scan_code = Quartz.CGEventGetIntegerValueField(event, Quartz.kCGKeyboardEventKeycode) - key_name = name_from_scancode(scan_code) - flags = Quartz.CGEventGetFlags(event) - event_type = "" - is_keypad = (flags & Quartz.kCGEventFlagMaskNumericPad) - if e_type == Quartz.kCGEventKeyDown: - event_type = "down" - elif e_type == Quartz.kCGEventKeyUp: - event_type = "up" - elif e_type == Quartz.kCGEventFlagsChanged: - if key_name.endswith("shift") and (flags & Quartz.kCGEventFlagMaskShift): - event_type = "down" - elif key_name == "caps lock" and (flags & Quartz.kCGEventFlagMaskAlphaShift): - event_type = "down" - elif (key_name.endswith("option") or key_name.endswith("alt")) and (flags & Quartz.kCGEventFlagMaskAlternate): - event_type = "down" - elif key_name == "ctrl" and (flags & Quartz.kCGEventFlagMaskControl): - event_type = "down" - elif key_name == "command" and (flags & Quartz.kCGEventFlagMaskCommand): - event_type = "down" - else: - event_type = "up" - - if self.blocking: - return None - - self.callback(KeyboardEvent(event_type, scan_code, name=key_name, is_keypad=is_keypad)) - return event - -key_controller = KeyController() - -""" Exported functions below """ - -def init(): - key_controller = KeyController() - -def press(scan_code): - """ Sends a 'down' event for the specified scan code """ - key_controller.press(scan_code) - -def release(scan_code): - """ Sends an 'up' event for the specified scan code """ - key_controller.release(scan_code) - -def map_name(name): - """ Returns a tuple of (scan_code, modifiers) where ``scan_code`` is a numeric scan code - and ``modifiers`` is an array of string modifier names (like 'shift') """ - yield key_controller.map_char(name) - -def name_from_scancode(scan_code): - """ Returns the name or character associated with the specified key code """ - return key_controller.map_scan_code(scan_code) - -def listen(callback): - if not os.geteuid() == 0: - raise OSError("Error 13 - Must be run as administrator") - KeyEventListener(callback).run() - -def type_unicode(character): - OUTPUT_SOURCE = Quartz.CGEventSourceCreate(Quartz.kCGEventSourceStateHIDSystemState) - # Key down - event = Quartz.CGEventCreateKeyboardEvent(OUTPUT_SOURCE, 0, True) - Quartz.CGEventKeyboardSetUnicodeString(event, len(character.encode('utf-16-le')) // 2, character) - Quartz.CGEventPost(Quartz.kCGSessionEventTap, event) - # Key up - event = Quartz.CGEventCreateKeyboardEvent(OUTPUT_SOURCE, 0, False) - Quartz.CGEventKeyboardSetUnicodeString(event, len(character.encode('utf-16-le')) // 2, character) - Quartz.CGEventPost(Quartz.kCGSessionEventTap, event)
\ No newline at end of file diff --git a/Python/venv1/Lib/site-packages/keyboard/_darwinmouse.py b/Python/venv1/Lib/site-packages/keyboard/_darwinmouse.py deleted file mode 100644 index b112dc0..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_darwinmouse.py +++ /dev/null @@ -1,173 +0,0 @@ -import os -import datetime -import threading -import Quartz -from ._mouse_event import ButtonEvent, WheelEvent, MoveEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN - -_button_mapping = { - LEFT: (Quartz.kCGMouseButtonLeft, Quartz.kCGEventLeftMouseDown, Quartz.kCGEventLeftMouseUp, Quartz.kCGEventLeftMouseDragged), - RIGHT: (Quartz.kCGMouseButtonRight, Quartz.kCGEventRightMouseDown, Quartz.kCGEventRightMouseUp, Quartz.kCGEventRightMouseDragged), - MIDDLE: (Quartz.kCGMouseButtonCenter, Quartz.kCGEventOtherMouseDown, Quartz.kCGEventOtherMouseUp, Quartz.kCGEventOtherMouseDragged) -} -_button_state = { - LEFT: False, - RIGHT: False, - MIDDLE: False -} -_last_click = { - "time": None, - "button": None, - "position": None, - "click_count": 0 -} - -class MouseEventListener(object): - def __init__(self, callback, blocking=False): - self.blocking = blocking - self.callback = callback - self.listening = True - - def run(self): - """ Creates a listener and loops while waiting for an event. Intended to run as - a background thread. """ - self.tap = Quartz.CGEventTapCreate( - Quartz.kCGSessionEventTap, - Quartz.kCGHeadInsertEventTap, - Quartz.kCGEventTapOptionDefault, - Quartz.CGEventMaskBit(Quartz.kCGEventLeftMouseDown) | - Quartz.CGEventMaskBit(Quartz.kCGEventLeftMouseUp) | - Quartz.CGEventMaskBit(Quartz.kCGEventRightMouseDown) | - Quartz.CGEventMaskBit(Quartz.kCGEventRightMouseUp) | - Quartz.CGEventMaskBit(Quartz.kCGEventOtherMouseDown) | - Quartz.CGEventMaskBit(Quartz.kCGEventOtherMouseUp) | - Quartz.CGEventMaskBit(Quartz.kCGEventMouseMoved) | - Quartz.CGEventMaskBit(Quartz.kCGEventScrollWheel), - self.handler, - None) - loopsource = Quartz.CFMachPortCreateRunLoopSource(None, self.tap, 0) - loop = Quartz.CFRunLoopGetCurrent() - Quartz.CFRunLoopAddSource(loop, loopsource, Quartz.kCFRunLoopDefaultMode) - Quartz.CGEventTapEnable(self.tap, True) - - while self.listening: - Quartz.CFRunLoopRunInMode(Quartz.kCFRunLoopDefaultMode, 5, False) - - def handler(self, proxy, e_type, event, refcon): - # TODO Separate event types by button/wheel/move - scan_code = Quartz.CGEventGetIntegerValueField(event, Quartz.kCGKeyboardEventKeycode) - key_name = name_from_scancode(scan_code) - flags = Quartz.CGEventGetFlags(event) - event_type = "" - is_keypad = (flags & Quartz.kCGEventFlagMaskNumericPad) - if e_type == Quartz.kCGEventKeyDown: - event_type = "down" - elif e_type == Quartz.kCGEventKeyUp: - event_type = "up" - - if self.blocking: - return None - - self.callback(KeyboardEvent(event_type, scan_code, name=key_name, is_keypad=is_keypad)) - return event - -# Exports - -def init(): - """ Initializes mouse state """ - pass - -def listen(queue): - """ Appends events to the queue (ButtonEvent, WheelEvent, and MoveEvent). """ - if not os.geteuid() == 0: - raise OSError("Error 13 - Must be run as administrator") - listener = MouseEventListener(lambda e: queue.put(e) or is_allowed(e.name, e.event_type == KEY_UP)) - t = threading.Thread(target=listener.run, args=()) - t.daemon = True - t.start() - -def press(button=LEFT): - """ Sends a down event for the specified button, using the provided constants """ - location = get_position() - button_code, button_down, _, _ = _button_mapping[button] - e = Quartz.CGEventCreateMouseEvent( - None, - button_down, - location, - button_code) - - # Check if this is a double-click (same location within the last 300ms) - if _last_click["time"] is not None and datetime.datetime.now() - _last_click["time"] < datetime.timedelta(seconds=0.3) and _last_click["button"] == button and _last_click["position"] == location: - # Repeated Click - _last_click["click_count"] = min(3, _last_click["click_count"]+1) - else: - # Not a double-click - Reset last click - _last_click["click_count"] = 1 - Quartz.CGEventSetIntegerValueField( - e, - Quartz.kCGMouseEventClickState, - _last_click["click_count"]) - Quartz.CGEventPost(Quartz.kCGHIDEventTap, e) - _button_state[button] = True - _last_click["time"] = datetime.datetime.now() - _last_click["button"] = button - _last_click["position"] = location - -def release(button=LEFT): - """ Sends an up event for the specified button, using the provided constants """ - location = get_position() - button_code, _, button_up, _ = _button_mapping[button] - e = Quartz.CGEventCreateMouseEvent( - None, - button_up, - location, - button_code) - - if _last_click["time"] is not None and _last_click["time"] > datetime.datetime.now() - datetime.timedelta(microseconds=300000) and _last_click["button"] == button and _last_click["position"] == location: - # Repeated Click - Quartz.CGEventSetIntegerValueField( - e, - Quartz.kCGMouseEventClickState, - _last_click["click_count"]) - Quartz.CGEventPost(Quartz.kCGHIDEventTap, e) - _button_state[button] = False - -def wheel(delta=1): - """ Sends a wheel event for the provided number of clicks. May be negative to reverse - direction. """ - location = get_position() - e = Quartz.CGEventCreateMouseEvent( - None, - Quartz.kCGEventScrollWheel, - location, - Quartz.kCGMouseButtonLeft) - e2 = Quartz.CGEventCreateScrollWheelEvent( - None, - Quartz.kCGScrollEventUnitLine, - 1, - delta) - Quartz.CGEventPost(Quartz.kCGHIDEventTap, e) - Quartz.CGEventPost(Quartz.kCGHIDEventTap, e2) - -def move_to(x, y): - """ Sets the mouse's location to the specified coordinates. """ - for b in _button_state: - if _button_state[b]: - e = Quartz.CGEventCreateMouseEvent( - None, - _button_mapping[b][3], # Drag Event - (x, y), - _button_mapping[b][0]) - break - else: - e = Quartz.CGEventCreateMouseEvent( - None, - Quartz.kCGEventMouseMoved, - (x, y), - Quartz.kCGMouseButtonLeft) - Quartz.CGEventPost(Quartz.kCGHIDEventTap, e) - -def get_position(): - """ Returns the mouse's location as a tuple of (x, y). """ - e = Quartz.CGEventCreate(None) - point = Quartz.CGEventGetLocation(e) - return (point.x, point.y)
\ No newline at end of file diff --git a/Python/venv1/Lib/site-packages/keyboard/_generic.py b/Python/venv1/Lib/site-packages/keyboard/_generic.py deleted file mode 100644 index 762858d..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_generic.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -from threading import Thread, Lock -import traceback -import functools - -try: - from queue import Queue -except ImportError: - from Queue import Queue - -class GenericListener(object): - lock = Lock() - - def __init__(self): - self.handlers = [] - self.listening = False - self.queue = Queue() - - def invoke_handlers(self, event): - for handler in self.handlers: - try: - if handler(event): - # Stop processing this hotkey. - return 1 - except Exception as e: - traceback.print_exc() - - def start_if_necessary(self): - """ - Starts the listening thread if it wans't already. - """ - self.lock.acquire() - try: - if not self.listening: - self.init() - - self.listening = True - self.listening_thread = Thread(target=self.listen) - self.listening_thread.daemon = True - self.listening_thread.start() - - self.processing_thread = Thread(target=self.process) - self.processing_thread.daemon = True - self.processing_thread.start() - finally: - self.lock.release() - - def pre_process_event(self, event): - raise NotImplementedError('This method should be implemented in the child class.') - - def process(self): - """ - Loops over the underlying queue of events and processes them in order. - """ - assert self.queue is not None - while True: - event = self.queue.get() - if self.pre_process_event(event): - self.invoke_handlers(event) - self.queue.task_done() - - def add_handler(self, handler): - """ - Adds a function to receive each event captured, starting the capturing - process if necessary. - """ - self.start_if_necessary() - self.handlers.append(handler) - - def remove_handler(self, handler): - """ Removes a previously added event handler. """ - while handler in self.handlers: - self.handlers.remove(handler) diff --git a/Python/venv1/Lib/site-packages/keyboard/_keyboard_event.py b/Python/venv1/Lib/site-packages/keyboard/_keyboard_event.py deleted file mode 100644 index 6d9f279..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_keyboard_event.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -from time import time as now -import json -from ._canonical_names import canonical_names, normalize_name - -try: - basestring -except NameError: - basestring = str - -KEY_DOWN = 'down' -KEY_UP = 'up' - -class KeyboardEvent(object): - event_type = None - scan_code = None - name = None - time = None - device = None - modifiers = None - is_keypad = None - - def __init__(self, event_type, scan_code, name=None, time=None, device=None, modifiers=None, is_keypad=None): - self.event_type = event_type - self.scan_code = scan_code - self.time = now() if time is None else time - self.device = device - self.is_keypad = is_keypad - self.modifiers = modifiers - if name: - self.name = normalize_name(name) - - def to_json(self, ensure_ascii=False): - attrs = dict( - (attr, getattr(self, attr)) for attr in ['event_type', 'scan_code', 'name', 'time', 'device', 'is_keypad'] - if not attr.startswith('_') and getattr(self, attr) is not None - ) - return json.dumps(attrs, ensure_ascii=ensure_ascii) - - def __repr__(self): - return 'KeyboardEvent({} {})'.format(self.name or 'Unknown {}'.format(self.scan_code), self.event_type) - - def __eq__(self, other): - return ( - isinstance(other, KeyboardEvent) - and self.event_type == other.event_type - and ( - not self.scan_code or not other.scan_code or self.scan_code == other.scan_code - ) and ( - not self.name or not other.name or self.name == other.name - ) - ) diff --git a/Python/venv1/Lib/site-packages/keyboard/_keyboard_tests.py b/Python/venv1/Lib/site-packages/keyboard/_keyboard_tests.py deleted file mode 100644 index f0e1432..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_keyboard_tests.py +++ /dev/null @@ -1,827 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Side effects are avoided using two techniques: - -- Low level OS requests (keyboard._os_keyboard) are mocked out by rewriting -the functions at that namespace. This includes a list of dummy keys. -- Events are pumped manually by the main test class, and accepted events -are tested against expected values. - -Fake user events are appended to `input_events`, passed through -keyboard,_listener.direct_callback, then, if accepted, appended to -`output_events`. Fake OS events (keyboard.press) are processed -and added to `output_events` immediately, mimicking real functionality. -""" -from __future__ import print_function - -import unittest -import time - -import keyboard -from ._keyboard_event import KeyboardEvent, KEY_DOWN, KEY_UP - -dummy_keys = { - 'space': [(0, [])], - - 'a': [(1, [])], - 'b': [(2, [])], - 'c': [(3, [])], - 'A': [(1, ['shift']), (-1, [])], - 'B': [(2, ['shift']), (-2, [])], - 'C': [(3, ['shift']), (-3, [])], - - 'alt': [(4, [])], - 'left alt': [(4, [])], - - 'left shift': [(5, [])], - 'right shift': [(6, [])], - - 'left ctrl': [(7, [])], - - 'backspace': [(8, [])], - 'caps lock': [(9, [])], - - '+': [(10, [])], - ',': [(11, [])], - '_': [(12, [])], - - 'none': [], - 'duplicated': [(20, []), (20, [])], -} - -def make_event(event_type, name, scan_code=None, time=0): - return KeyboardEvent(event_type=event_type, scan_code=scan_code or dummy_keys[name][0][0], name=name, time=time) - -# Used when manually pumping events. -input_events = [] -output_events = [] - -def send_instant_event(event): - if keyboard._listener.direct_callback(event): - output_events.append(event) - -# Mock out side effects. -keyboard._os_keyboard.init = lambda: None -keyboard._os_keyboard.listen = lambda callback: None -keyboard._os_keyboard.map_name = dummy_keys.__getitem__ -keyboard._os_keyboard.press = lambda scan_code: send_instant_event(make_event(KEY_DOWN, None, scan_code)) -keyboard._os_keyboard.release = lambda scan_code: send_instant_event(make_event(KEY_UP, None, scan_code)) -keyboard._os_keyboard.type_unicode = lambda char: output_events.append(KeyboardEvent(event_type=KEY_DOWN, scan_code=999, name=char)) - -# Shortcuts for defining test inputs and expected outputs. -# Usage: d_shift + d_a + u_a + u_shift -d_a = [make_event(KEY_DOWN, 'a')] -u_a = [make_event(KEY_UP, 'a')] -du_a = d_a+u_a -d_b = [make_event(KEY_DOWN, 'b')] -u_b = [make_event(KEY_UP, 'b')] -du_b = d_b+u_b -d_c = [make_event(KEY_DOWN, 'c')] -u_c = [make_event(KEY_UP, 'c')] -du_c = d_c+u_c -d_ctrl = [make_event(KEY_DOWN, 'left ctrl')] -u_ctrl = [make_event(KEY_UP, 'left ctrl')] -du_ctrl = d_ctrl+u_ctrl -d_shift = [make_event(KEY_DOWN, 'left shift')] -u_shift = [make_event(KEY_UP, 'left shift')] -du_shift = d_shift+u_shift -d_alt = [make_event(KEY_DOWN, 'alt')] -u_alt = [make_event(KEY_UP, 'alt')] -du_alt = d_alt+u_alt -du_backspace = [make_event(KEY_DOWN, 'backspace'), make_event(KEY_UP, 'backspace')] -du_capslock = [make_event(KEY_DOWN, 'caps lock'), make_event(KEY_UP, 'caps lock')] -d_space = [make_event(KEY_DOWN, 'space')] -u_space = [make_event(KEY_UP, 'space')] -du_space = [make_event(KEY_DOWN, 'space'), make_event(KEY_UP, 'space')] - -trigger = lambda e=None: keyboard.press(999) -triggered_event = [KeyboardEvent(KEY_DOWN, scan_code=999)] - -class TestKeyboard(unittest.TestCase): - def tearDown(self): - keyboard.unhook_all() - #self.assertEquals(keyboard._hooks, {}) - #self.assertEquals(keyboard._hotkeys, {}) - - def setUp(self): - #keyboard._hooks.clear() - #keyboard._hotkeys.clear() - del input_events[:] - del output_events[:] - keyboard._recording = None - keyboard._pressed_events.clear() - keyboard._physically_pressed_keys.clear() - keyboard._logically_pressed_keys.clear() - keyboard._hotkeys.clear() - keyboard._listener.init() - keyboard._word_listeners = {} - - def do(self, manual_events, expected=None): - input_events.extend(manual_events) - while input_events: - event = input_events.pop(0) - if keyboard._listener.direct_callback(event): - output_events.append(event) - if expected is not None: - to_names = lambda es: '+'.join(('d' if e.event_type == KEY_DOWN else 'u') + '_' + str(e.scan_code) for e in es) - self.assertEqual(to_names(output_events), to_names(expected)) - del output_events[:] - - keyboard._listener.queue.join() - - def test_event_json(self): - event = make_event(KEY_DOWN, u'á \'"', 999) - import json - self.assertEqual(event, KeyboardEvent(**json.loads(event.to_json()))) - - def test_is_modifier_name(self): - for name in keyboard.all_modifiers: - self.assertTrue(keyboard.is_modifier(name)) - def test_is_modifier_scan_code(self): - for i in range(10): - self.assertEqual(keyboard.is_modifier(i), i in [4, 5, 6, 7]) - - def test_key_to_scan_codes_brute(self): - for name, entries in dummy_keys.items(): - if name in ['none', 'duplicated']: continue - expected = tuple(scan_code for scan_code, modifiers in entries) - self.assertEqual(keyboard.key_to_scan_codes(name), expected) - def test_key_to_scan_code_from_scan_code(self): - for i in range(10): - self.assertEqual(keyboard.key_to_scan_codes(i), (i,)) - def test_key_to_scan_code_from_letter(self): - self.assertEqual(keyboard.key_to_scan_codes('a'), (1,)) - self.assertEqual(keyboard.key_to_scan_codes('A'), (1,-1)) - def test_key_to_scan_code_from_normalized(self): - self.assertEqual(keyboard.key_to_scan_codes('shift'), (5,6)) - self.assertEqual(keyboard.key_to_scan_codes('SHIFT'), (5,6)) - self.assertEqual(keyboard.key_to_scan_codes('ctrl'), keyboard.key_to_scan_codes('CONTROL')) - def test_key_to_scan_code_from_sided_modifier(self): - self.assertEqual(keyboard.key_to_scan_codes('left shift'), (5,)) - self.assertEqual(keyboard.key_to_scan_codes('right shift'), (6,)) - def test_key_to_scan_code_underscores(self): - self.assertEqual(keyboard.key_to_scan_codes('_'), (12,)) - self.assertEqual(keyboard.key_to_scan_codes('right_shift'), (6,)) - def test_key_to_scan_code_error_none(self): - with self.assertRaises(ValueError): - keyboard.key_to_scan_codes(None) - def test_key_to_scan_code_error_empty(self): - with self.assertRaises(ValueError): - keyboard.key_to_scan_codes('') - def test_key_to_scan_code_error_other(self): - with self.assertRaises(ValueError): - keyboard.key_to_scan_codes({}) - def test_key_to_scan_code_list(self): - self.assertEqual(keyboard.key_to_scan_codes([10, 5, 'a']), (10, 5, 1)) - def test_key_to_scan_code_empty(self): - with self.assertRaises(ValueError): - keyboard.key_to_scan_codes('none') - def test_key_to_scan_code_duplicated(self): - self.assertEqual(keyboard.key_to_scan_codes('duplicated'), (20,)) - - def test_parse_hotkey_simple(self): - self.assertEqual(keyboard.parse_hotkey('a'), (((1,),),)) - self.assertEqual(keyboard.parse_hotkey('A'), (((1,-1),),)) - def test_parse_hotkey_separators(self): - self.assertEqual(keyboard.parse_hotkey('+'), keyboard.parse_hotkey('plus')) - self.assertEqual(keyboard.parse_hotkey(','), keyboard.parse_hotkey('comma')) - def test_parse_hotkey_keys(self): - self.assertEqual(keyboard.parse_hotkey('left shift + a'), (((5,), (1,),),)) - self.assertEqual(keyboard.parse_hotkey('left shift+a'), (((5,), (1,),),)) - def test_parse_hotkey_simple_steps(self): - self.assertEqual(keyboard.parse_hotkey('a,b'), (((1,),),((2,),))) - self.assertEqual(keyboard.parse_hotkey('a, b'), (((1,),),((2,),))) - def test_parse_hotkey_steps(self): - self.assertEqual(keyboard.parse_hotkey('a+b, b+c'), (((1,),(2,)),((2,),(3,)))) - def test_parse_hotkey_example(self): - alt_codes = keyboard.key_to_scan_codes('alt') - shift_codes = keyboard.key_to_scan_codes('shift') - a_codes = keyboard.key_to_scan_codes('a') - b_codes = keyboard.key_to_scan_codes('b') - c_codes = keyboard.key_to_scan_codes('c') - self.assertEqual(keyboard.parse_hotkey("alt+shift+a, alt+b, c"), ((alt_codes, shift_codes, a_codes), (alt_codes, b_codes), (c_codes,))) - def test_parse_hotkey_list_scan_codes(self): - self.assertEqual(keyboard.parse_hotkey([1, 2, 3]), (((1,), (2,), (3,)),)) - def test_parse_hotkey_deep_list_scan_codes(self): - result = keyboard.parse_hotkey('a') - self.assertEqual(keyboard.parse_hotkey(result), (((1,),),)) - def test_parse_hotkey_list_names(self): - self.assertEqual(keyboard.parse_hotkey(['a', 'b', 'c']), (((1,), (2,), (3,)),)) - - def test_is_pressed_none(self): - self.assertFalse(keyboard.is_pressed('a')) - def test_is_pressed_true(self): - self.do(d_a) - self.assertTrue(keyboard.is_pressed('a')) - def test_is_pressed_true_scan_code_true(self): - self.do(d_a) - self.assertTrue(keyboard.is_pressed(1)) - def test_is_pressed_true_scan_code_false(self): - self.do(d_a) - self.assertFalse(keyboard.is_pressed(2)) - def test_is_pressed_true_scan_code_invalid(self): - self.do(d_a) - self.assertFalse(keyboard.is_pressed(-1)) - def test_is_pressed_false(self): - self.do(d_a+u_a+d_b) - self.assertFalse(keyboard.is_pressed('a')) - self.assertTrue(keyboard.is_pressed('b')) - def test_is_pressed_hotkey_true(self): - self.do(d_shift+d_a) - self.assertTrue(keyboard.is_pressed('shift+a')) - def test_is_pressed_hotkey_false(self): - self.do(d_shift+d_a+u_a) - self.assertFalse(keyboard.is_pressed('shift+a')) - def test_is_pressed_multi_step_fail(self): - self.do(u_a+d_a) - with self.assertRaises(ValueError): - keyboard.is_pressed('a, b') - - def test_send_single_press_release(self): - keyboard.send('a', do_press=True, do_release=True) - self.do([], d_a+u_a) - def test_send_single_press(self): - keyboard.send('a', do_press=True, do_release=False) - self.do([], d_a) - def test_send_single_release(self): - keyboard.send('a', do_press=False, do_release=True) - self.do([], u_a) - def test_send_single_none(self): - keyboard.send('a', do_press=False, do_release=False) - self.do([], []) - def test_press(self): - keyboard.press('a') - self.do([], d_a) - def test_release(self): - keyboard.release('a') - self.do([], u_a) - def test_press_and_release(self): - keyboard.press_and_release('a') - self.do([], d_a+u_a) - - def test_send_modifier_press_release(self): - keyboard.send('ctrl+a', do_press=True, do_release=True) - self.do([], d_ctrl+d_a+u_a+u_ctrl) - def test_send_modifiers_release(self): - keyboard.send('ctrl+shift+a', do_press=False, do_release=True) - self.do([], u_a+u_shift+u_ctrl) - - def test_call_later(self): - triggered = [] - def fn(arg1, arg2): - assert arg1 == 1 and arg2 == 2 - triggered.append(True) - keyboard.call_later(fn, (1, 2), 0.01) - self.assertFalse(triggered) - time.sleep(0.05) - self.assertTrue(triggered) - - def test_hook_nonblocking(self): - self.i = 0 - def count(e): - self.assertEqual(e.name, 'a') - self.i += 1 - hook = keyboard.hook(count, suppress=False) - self.do(d_a+u_a, d_a+u_a) - self.assertEqual(self.i, 2) - keyboard.unhook(hook) - self.do(d_a+u_a, d_a+u_a) - self.assertEqual(self.i, 2) - keyboard.hook(count, suppress=False) - self.do(d_a+u_a, d_a+u_a) - self.assertEqual(self.i, 4) - keyboard.unhook_all() - self.do(d_a+u_a, d_a+u_a) - self.assertEqual(self.i, 4) - def test_hook_blocking(self): - self.i = 0 - def count(e): - self.assertIn(e.name, ['a', 'b']) - self.i += 1 - return e.name == 'b' - hook = keyboard.hook(count, suppress=True) - self.do(d_a+d_b, d_b) - self.assertEqual(self.i, 2) - keyboard.unhook(hook) - self.do(d_a+d_b, d_a+d_b) - self.assertEqual(self.i, 2) - keyboard.hook(count, suppress=True) - self.do(d_a+d_b, d_b) - self.assertEqual(self.i, 4) - keyboard.unhook_all() - self.do(d_a+d_b, d_a+d_b) - self.assertEqual(self.i, 4) - def test_on_press_nonblocking(self): - keyboard.on_press(lambda e: self.assertEqual(e.name, 'a') and self.assertEqual(e.event_type, KEY_DOWN)) - self.do(d_a+u_a) - def test_on_press_blocking(self): - keyboard.on_press(lambda e: e.scan_code == 1, suppress=True) - self.do([make_event(KEY_DOWN, 'A', -1)] + d_a, d_a) - def test_on_release(self): - keyboard.on_release(lambda e: self.assertEqual(e.name, 'a') and self.assertEqual(e.event_type, KEY_UP)) - self.do(d_a+u_a) - - def test_hook_key_invalid(self): - with self.assertRaises(ValueError): - keyboard.hook_key('invalid', lambda e: None) - def test_hook_key_nonblocking(self): - self.i = 0 - def count(event): - self.i += 1 - hook = keyboard.hook_key('A', count) - self.do(d_a) - self.assertEqual(self.i, 1) - self.do(u_a+d_b) - self.assertEqual(self.i, 2) - self.do([make_event(KEY_DOWN, 'A', -1)]) - self.assertEqual(self.i, 3) - keyboard.unhook_key(hook) - self.do(d_a) - self.assertEqual(self.i, 3) - def test_hook_key_blocking(self): - self.i = 0 - def count(event): - self.i += 1 - return event.scan_code == 1 - hook = keyboard.hook_key('A', count, suppress=True) - self.do(d_a, d_a) - self.assertEqual(self.i, 1) - self.do(u_a+d_b, u_a+d_b) - self.assertEqual(self.i, 2) - self.do([make_event(KEY_DOWN, 'A', -1)], []) - self.assertEqual(self.i, 3) - keyboard.unhook_key(hook) - self.do([make_event(KEY_DOWN, 'A', -1)], [make_event(KEY_DOWN, 'A', -1)]) - self.assertEqual(self.i, 3) - def test_on_press_key_nonblocking(self): - keyboard.on_press_key('A', lambda e: self.assertEqual(e.name, 'a') and self.assertEqual(e.event_type, KEY_DOWN)) - self.do(d_a+u_a+d_b+u_b) - def test_on_press_key_blocking(self): - keyboard.on_press_key('A', lambda e: e.scan_code == 1, suppress=True) - self.do([make_event(KEY_DOWN, 'A', -1)] + d_a, d_a) - def test_on_release_key(self): - keyboard.on_release_key('a', lambda e: self.assertEqual(e.name, 'a') and self.assertEqual(e.event_type, KEY_UP)) - self.do(d_a+u_a) - - def test_block_key(self): - blocked = keyboard.block_key('a') - self.do(d_a+d_b, d_b) - self.do([make_event(KEY_DOWN, 'A', -1)], [make_event(KEY_DOWN, 'A', -1)]) - keyboard.unblock_key(blocked) - self.do(d_a+d_b, d_a+d_b) - def test_block_key_ambiguous(self): - keyboard.block_key('A') - self.do(d_a+d_b, d_b) - self.do([make_event(KEY_DOWN, 'A', -1)], []) - - def test_remap_key_simple(self): - mapped = keyboard.remap_key('a', 'b') - self.do(d_a+d_c+u_a, d_b+d_c+u_b) - keyboard.unremap_key(mapped) - self.do(d_a+d_c+u_a, d_a+d_c+u_a) - def test_remap_key_ambiguous(self): - keyboard.remap_key('A', 'b') - self.do(d_a+d_b, d_b+d_b) - self.do([make_event(KEY_DOWN, 'A', -1)], d_b) - def test_remap_key_multiple(self): - mapped = keyboard.remap_key('a', 'shift+b') - self.do(d_a+d_c+u_a, d_shift+d_b+d_c+u_b+u_shift) - keyboard.unremap_key(mapped) - self.do(d_a+d_c+u_a, d_a+d_c+u_a) - - def test_stash_state(self): - self.do(d_a+d_shift) - self.assertEqual(sorted(keyboard.stash_state()), [1, 5]) - self.do([], u_a+u_shift) - def test_restore_state(self): - self.do(d_b) - keyboard.restore_state([1, 5]) - self.do([], u_b+d_a+d_shift) - def test_restore_modifieres(self): - self.do(d_b) - keyboard.restore_modifiers([1, 5]) - self.do([], u_b+d_shift) - - def test_write_simple(self): - keyboard.write('a', exact=False) - self.do([], d_a+u_a) - def test_write_multiple(self): - keyboard.write('ab', exact=False) - self.do([], d_a+u_a+d_b+u_b) - def test_write_modifiers(self): - keyboard.write('Ab', exact=False) - self.do([], d_shift+d_a+u_a+u_shift+d_b+u_b) - # restore_state_after has been removed after the introduction of `restore_modifiers`. - #def test_write_stash_not_restore(self): - # self.do(d_shift) - # keyboard.write('a', restore_state_after=False, exact=False) - # self.do([], u_shift+d_a+u_a) - def test_write_stash_restore(self): - self.do(d_shift) - keyboard.write('a', exact=False) - self.do([], u_shift+d_a+u_a+d_shift) - def test_write_multiple(self): - last_time = time.time() - keyboard.write('ab', delay=0.01, exact=False) - self.do([], d_a+u_a+d_b+u_b) - self.assertGreater(time.time() - last_time, 0.015) - def test_write_unicode_explicit(self): - keyboard.write('ab', exact=True) - self.do([], [KeyboardEvent(event_type=KEY_DOWN, scan_code=999, name='a'), KeyboardEvent(event_type=KEY_DOWN, scan_code=999, name='b')]) - def test_write_unicode_fallback(self): - keyboard.write(u'áb', exact=False) - self.do([], [KeyboardEvent(event_type=KEY_DOWN, scan_code=999, name=u'á')]+d_b+u_b) - - def test_start_stop_recording(self): - keyboard.start_recording() - self.do(d_a+u_a) - self.assertEqual(keyboard.stop_recording(), d_a+u_a) - def test_stop_recording_error(self): - with self.assertRaises(ValueError): - keyboard.stop_recording() - - def test_record(self): - queue = keyboard._queue.Queue() - def process(): - queue.put(keyboard.record('space', suppress=True)) - from threading import Thread - t = Thread(target=process) - t.daemon = True - t.start() - # 0.01s sleep failed once already. Better solutions? - time.sleep(0.01) - self.do(du_a+du_b+du_space, du_a+du_b) - self.assertEqual(queue.get(timeout=0.5), du_a+du_b+du_space) - - def test_play_nodelay(self): - keyboard.play(d_a+u_a, 0) - self.do([], d_a+u_a) - def test_play_stash(self): - self.do(d_ctrl) - keyboard.play(d_a+u_a, 0) - self.do([], u_ctrl+d_a+u_a+d_ctrl) - def test_play_delay(self): - last_time = time.time() - events = [make_event(KEY_DOWN, 'a', 1, 100), make_event(KEY_UP, 'a', 1, 100.01)] - keyboard.play(events, 1) - self.do([], d_a+u_a) - self.assertGreater(time.time() - last_time, 0.005) - - def test_get_typed_strings_simple(self): - events = du_a+du_b+du_backspace+d_shift+du_a+u_shift+du_space+du_ctrl+du_a - self.assertEqual(list(keyboard.get_typed_strings(events)), ['aA ', 'a']) - def test_get_typed_strings_backspace(self): - events = du_a+du_b+du_backspace - self.assertEqual(list(keyboard.get_typed_strings(events)), ['a']) - events = du_backspace+du_a+du_b - self.assertEqual(list(keyboard.get_typed_strings(events)), ['ab']) - def test_get_typed_strings_shift(self): - events = d_shift+du_a+du_b+u_shift+du_space+du_ctrl+du_a - self.assertEqual(list(keyboard.get_typed_strings(events)), ['AB ', 'a']) - def test_get_typed_strings_all(self): - events = du_a+du_b+du_backspace+d_shift+du_a+du_capslock+du_b+u_shift+du_space+du_ctrl+du_a - self.assertEqual(list(keyboard.get_typed_strings(events)), ['aAb ', 'A']) - - def test_get_hotkey_name_simple(self): - self.assertEqual(keyboard.get_hotkey_name(['a']), 'a') - def test_get_hotkey_name_modifiers(self): - self.assertEqual(keyboard.get_hotkey_name(['a', 'shift', 'ctrl']), 'ctrl+shift+a') - def test_get_hotkey_name_normalize(self): - self.assertEqual(keyboard.get_hotkey_name(['SHIFT', 'left ctrl']), 'ctrl+shift') - def test_get_hotkey_name_plus(self): - self.assertEqual(keyboard.get_hotkey_name(['+']), 'plus') - def test_get_hotkey_name_duplicated(self): - self.assertEqual(keyboard.get_hotkey_name(['+', 'plus']), 'plus') - def test_get_hotkey_name_full(self): - self.assertEqual(keyboard.get_hotkey_name(['+', 'left ctrl', 'shift', 'WIN', 'right alt']), 'ctrl+alt+shift+windows+plus') - def test_get_hotkey_name_multiple(self): - self.assertEqual(keyboard.get_hotkey_name(['ctrl', 'b', '!', 'a']), 'ctrl+!+a+b') - def test_get_hotkey_name_from_pressed(self): - self.do(du_c+d_ctrl+d_a+d_b) - self.assertEqual(keyboard.get_hotkey_name(), 'ctrl+a+b') - - def test_read_hotkey(self): - queue = keyboard._queue.Queue() - def process(): - queue.put(keyboard.read_hotkey()) - from threading import Thread - t = Thread(target=process) - t.daemon = True - t.start() - time.sleep(0.01) - self.do(d_ctrl+d_a+d_b+u_ctrl) - self.assertEqual(queue.get(timeout=0.5), 'ctrl+a+b') - - def test_read_event(self): - queue = keyboard._queue.Queue() - def process(): - queue.put(keyboard.read_event(suppress=True)) - from threading import Thread - t = Thread(target=process) - t.daemon = True - t.start() - time.sleep(0.01) - self.do(d_a, []) - self.assertEqual(queue.get(timeout=0.5), d_a[0]) - - def test_read_key(self): - queue = keyboard._queue.Queue() - def process(): - queue.put(keyboard.read_key(suppress=True)) - from threading import Thread - t = Thread(target=process) - t.daemon = True - t.start() - time.sleep(0.01) - self.do(d_a, []) - self.assertEqual(queue.get(timeout=0.5), 'a') - - def test_wait_infinite(self): - self.triggered = False - def process(): - keyboard.wait() - self.triggered = True - from threading import Thread - t = Thread(target=process) - t.daemon = True # Yep, we are letting this thread loose. - t.start() - time.sleep(0.01) - self.assertFalse(self.triggered) - - def test_wait_until_success(self): - queue = keyboard._queue.Queue() - def process(): - queue.put(keyboard.wait(queue.get(timeout=0.5), suppress=True) or True) - from threading import Thread - t = Thread(target=process) - t.daemon = True - t.start() - queue.put('a') - time.sleep(0.01) - self.do(d_a, []) - self.assertTrue(queue.get(timeout=0.5)) - def test_wait_until_fail(self): - def process(): - keyboard.wait('a', suppress=True) - self.fail() - from threading import Thread - t = Thread(target=process) - t.daemon = True # Yep, we are letting this thread loose. - t.start() - time.sleep(0.01) - self.do(d_b) - - def test_add_hotkey_single_step_suppress_allow(self): - keyboard.add_hotkey('a', lambda: trigger() or True, suppress=True) - self.do(d_a, triggered_event+d_a) - def test_add_hotkey_single_step_suppress_args_allow(self): - arg = object() - keyboard.add_hotkey('a', lambda a: self.assertIs(a, arg) or trigger() or True, args=(arg,), suppress=True) - self.do(d_a, triggered_event+d_a) - def test_add_hotkey_single_step_suppress_single(self): - keyboard.add_hotkey('a', trigger, suppress=True) - self.do(d_a, triggered_event) - def test_add_hotkey_single_step_suppress_removed(self): - keyboard.remove_hotkey(keyboard.add_hotkey('a', trigger, suppress=True)) - self.do(d_a, d_a) - def test_add_hotkey_single_step_suppress_removed(self): - keyboard.remove_hotkey(keyboard.add_hotkey('ctrl+a', trigger, suppress=True)) - self.do(d_ctrl+d_a, d_ctrl+d_a) - self.assertEqual(keyboard._listener.filtered_modifiers[dummy_keys['left ctrl'][0][0]], 0) - def test_remove_hotkey_internal(self): - remove = keyboard.add_hotkey('shift+a', trigger, suppress=True) - self.assertTrue(all(keyboard._listener.blocking_hotkeys.values())) - self.assertTrue(all(keyboard._listener.filtered_modifiers.values())) - self.assertNotEqual(keyboard._hotkeys, {}) - remove() - self.assertTrue(not any(keyboard._listener.filtered_modifiers.values())) - self.assertTrue(not any(keyboard._listener.blocking_hotkeys.values())) - self.assertEqual(keyboard._hotkeys, {}) - def test_remove_hotkey_internal_multistep_start(self): - remove = keyboard.add_hotkey('shift+a, b', trigger, suppress=True) - self.assertTrue(all(keyboard._listener.blocking_hotkeys.values())) - self.assertTrue(all(keyboard._listener.filtered_modifiers.values())) - self.assertNotEqual(keyboard._hotkeys, {}) - remove() - self.assertTrue(not any(keyboard._listener.filtered_modifiers.values())) - self.assertTrue(not any(keyboard._listener.blocking_hotkeys.values())) - self.assertEqual(keyboard._hotkeys, {}) - def test_remove_hotkey_internal_multistep_end(self): - remove = keyboard.add_hotkey('shift+a, b', trigger, suppress=True) - self.do(d_shift+du_a+u_shift) - self.assertTrue(any(keyboard._listener.blocking_hotkeys.values())) - self.assertTrue(not any(keyboard._listener.filtered_modifiers.values())) - self.assertNotEqual(keyboard._hotkeys, {}) - remove() - self.assertTrue(not any(keyboard._listener.filtered_modifiers.values())) - self.assertTrue(not any(keyboard._listener.blocking_hotkeys.values())) - self.assertEqual(keyboard._hotkeys, {}) - def test_add_hotkey_single_step_suppress_with_modifiers(self): - keyboard.add_hotkey('ctrl+shift+a', trigger, suppress=True) - self.do(d_ctrl+d_shift+d_a, triggered_event) - def test_add_hotkey_single_step_suppress_with_modifiers_fail_unrelated_modifier(self): - keyboard.add_hotkey('ctrl+shift+a', trigger, suppress=True) - self.do(d_ctrl+d_shift+u_shift+d_a, d_shift+u_shift+d_ctrl+d_a) - def test_add_hotkey_single_step_suppress_with_modifiers_fail_unrelated_key(self): - keyboard.add_hotkey('ctrl+shift+a', trigger, suppress=True) - self.do(d_ctrl+d_shift+du_b, d_shift+d_ctrl+du_b) - def test_add_hotkey_single_step_suppress_with_modifiers_unrelated_key(self): - keyboard.add_hotkey('ctrl+shift+a', trigger, suppress=True) - self.do(d_ctrl+d_shift+du_b+d_a, d_shift+d_ctrl+du_b+triggered_event) - def test_add_hotkey_single_step_suppress_with_modifiers_release(self): - keyboard.add_hotkey('ctrl+shift+a', trigger, suppress=True) - self.do(d_ctrl+d_shift+du_b+d_a+u_ctrl+u_shift, d_shift+d_ctrl+du_b+triggered_event+u_ctrl+u_shift) - def test_add_hotkey_single_step_suppress_with_modifiers_out_of_order(self): - keyboard.add_hotkey('ctrl+shift+a', trigger, suppress=True) - self.do(d_shift+d_ctrl+d_a, triggered_event) - def test_add_hotkey_single_step_suppress_with_modifiers_repeated(self): - keyboard.add_hotkey('ctrl+a', trigger, suppress=True) - self.do(d_ctrl+du_a+du_b+du_a, triggered_event+d_ctrl+du_b+triggered_event) - def test_add_hotkey_single_step_suppress_with_modifiers_release(self): - keyboard.add_hotkey('ctrl+a', trigger, suppress=True, trigger_on_release=True) - self.do(d_ctrl+du_a+du_b+du_a, triggered_event+d_ctrl+du_b+triggered_event) - def test_add_hotkey_single_step_suppress_with_modifier_superset_release(self): - keyboard.add_hotkey('ctrl+a', trigger, suppress=True, trigger_on_release=True) - self.do(d_ctrl+d_shift+du_a+u_shift+u_ctrl, d_ctrl+d_shift+du_a+u_shift+u_ctrl) - def test_add_hotkey_single_step_suppress_with_modifier_superset(self): - keyboard.add_hotkey('ctrl+a', trigger, suppress=True) - self.do(d_ctrl+d_shift+du_a+u_shift+u_ctrl, d_ctrl+d_shift+du_a+u_shift+u_ctrl) - def test_add_hotkey_single_step_timeout(self): - keyboard.add_hotkey('a', trigger, timeout=1, suppress=True) - self.do(du_a, triggered_event) - def test_add_hotkey_multi_step_first_timeout(self): - keyboard.add_hotkey('a, b', trigger, timeout=0.01, suppress=True) - time.sleep(0.03) - self.do(du_a+du_b, triggered_event) - def test_add_hotkey_multi_step_last_timeout(self): - keyboard.add_hotkey('a, b', trigger, timeout=0.01, suppress=True) - self.do(du_a, []) - time.sleep(0.05) - self.do(du_b, du_a+du_b) - def test_add_hotkey_multi_step_success_timeout(self): - keyboard.add_hotkey('a, b', trigger, timeout=0.05, suppress=True) - self.do(du_a, []) - time.sleep(0.01) - self.do(du_b, triggered_event) - def test_add_hotkey_multi_step_suffix_timeout(self): - keyboard.add_hotkey('a, b, a', trigger, timeout=0.01, suppress=True) - self.do(du_a+du_b, []) - time.sleep(0.05) - self.do(du_a, du_a+du_b) - self.do(du_b+du_a, triggered_event) - def test_add_hotkey_multi_step_allow(self): - keyboard.add_hotkey('a, b', lambda: trigger() or True, suppress=True) - self.do(du_a+du_b, triggered_event+du_a+du_b) - - def test_add_hotkey_single_step_nonsuppress(self): - queue = keyboard._queue.Queue() - keyboard.add_hotkey('ctrl+shift+a+b', lambda: queue.put(True), suppress=False) - self.do(d_shift+d_ctrl+d_a+d_b) - self.assertTrue(queue.get(timeout=0.5)) - def test_add_hotkey_single_step_nonsuppress_repeated(self): - queue = keyboard._queue.Queue() - keyboard.add_hotkey('ctrl+shift+a+b', lambda: queue.put(True), suppress=False) - self.do(d_shift+d_ctrl+d_a+d_b) - self.do(d_shift+d_ctrl+d_a+d_b) - self.assertTrue(queue.get(timeout=0.5)) - self.assertTrue(queue.get(timeout=0.5)) - def test_add_hotkey_single_step_nosuppress_with_modifiers_out_of_order(self): - queue = keyboard._queue.Queue() - keyboard.add_hotkey('ctrl+shift+a', lambda: queue.put(True), suppress=False) - self.do(d_shift+d_ctrl+d_a) - self.assertTrue(queue.get(timeout=0.5)) - def test_add_hotkey_single_step_suppress_regression_1(self): - keyboard.add_hotkey('a', trigger, suppress=True) - self.do(d_c+d_a+u_c+u_a, d_c+d_a+u_c+u_a) - - def test_remap_hotkey_single(self): - keyboard.remap_hotkey('a', 'b') - self.do(d_a+u_a, d_b+u_b) - def test_remap_hotkey_complex_dst(self): - keyboard.remap_hotkey('a', 'ctrl+b, c') - self.do(d_a+u_a, d_ctrl+du_b+u_ctrl+du_c) - def test_remap_hotkey_modifiers(self): - keyboard.remap_hotkey('ctrl+shift+a', 'b') - self.do(d_ctrl+d_shift+d_a+u_a, du_b) - def test_remap_hotkey_modifiers_repeat(self): - keyboard.remap_hotkey('ctrl+shift+a', 'b') - self.do(d_ctrl+d_shift+du_a+du_a, du_b+du_b) - def test_remap_hotkey_modifiers_state(self): - keyboard.remap_hotkey('ctrl+shift+a', 'b') - self.do(d_ctrl+d_shift+du_c+du_a+du_a, d_shift+d_ctrl+du_c+u_shift+u_ctrl+du_b+d_ctrl+d_shift+u_shift+u_ctrl+du_b+d_ctrl+d_shift) - def test_remap_hotkey_release_incomplete(self): - keyboard.remap_hotkey('a', 'b', trigger_on_release=True) - self.do(d_a, []) - def test_remap_hotkey_release_complete(self): - keyboard.remap_hotkey('a', 'b', trigger_on_release=True) - self.do(du_a, du_b) - - def test_parse_hotkey_combinations_scan_code(self): - self.assertEqual(keyboard.parse_hotkey_combinations(30), (((30,),),)) - def test_parse_hotkey_combinations_single(self): - self.assertEqual(keyboard.parse_hotkey_combinations('a'), (((1,),),)) - def test_parse_hotkey_combinations_single_modifier(self): - self.assertEqual(keyboard.parse_hotkey_combinations('shift+a'), (((1, 5), (1, 6)),)) - def test_parse_hotkey_combinations_single_modifiers(self): - self.assertEqual(keyboard.parse_hotkey_combinations('shift+ctrl+a'), (((1, 5, 7), (1, 6, 7)),)) - def test_parse_hotkey_combinations_multi(self): - self.assertEqual(keyboard.parse_hotkey_combinations('a, b'), (((1,),), ((2,),))) - def test_parse_hotkey_combinations_multi_modifier(self): - self.assertEqual(keyboard.parse_hotkey_combinations('shift+a, b'), (((1, 5), (1, 6)), ((2,),))) - def test_parse_hotkey_combinations_list_list(self): - self.assertEqual(keyboard.parse_hotkey_combinations(keyboard.parse_hotkey_combinations('a, b')), keyboard.parse_hotkey_combinations('a, b')) - def test_parse_hotkey_combinations_fail_empty(self): - with self.assertRaises(ValueError): - keyboard.parse_hotkey_combinations('') - - - def test_add_hotkey_multistep_suppress_incomplete(self): - keyboard.add_hotkey('a, b', trigger, suppress=True) - self.do(du_a, []) - self.assertEqual(keyboard._listener.blocking_hotkeys[(1,)], []) - self.assertEqual(len(keyboard._listener.blocking_hotkeys[(2,)]), 1) - def test_add_hotkey_multistep_suppress_incomplete(self): - keyboard.add_hotkey('a, b', trigger, suppress=True) - self.do(du_a+du_b, triggered_event) - def test_add_hotkey_multistep_suppress_modifier(self): - keyboard.add_hotkey('shift+a, b', trigger, suppress=True) - self.do(d_shift+du_a+u_shift+du_b, triggered_event) - def test_add_hotkey_multistep_suppress_fail(self): - keyboard.add_hotkey('a, b', trigger, suppress=True) - self.do(du_a+du_c, du_a+du_c) - def test_add_hotkey_multistep_suppress_three_steps(self): - keyboard.add_hotkey('a, b, c', trigger, suppress=True) - self.do(du_a+du_b+du_c, triggered_event) - def test_add_hotkey_multistep_suppress_repeated_prefix(self): - keyboard.add_hotkey('a, a, c', trigger, suppress=True, trigger_on_release=True) - self.do(du_a+du_a+du_c, triggered_event) - def test_add_hotkey_multistep_suppress_repeated_key(self): - keyboard.add_hotkey('a, b', trigger, suppress=True) - self.do(du_a+du_a+du_b, du_a+triggered_event) - self.assertEqual(keyboard._listener.blocking_hotkeys[(2,)], []) - self.assertEqual(len(keyboard._listener.blocking_hotkeys[(1,)]), 1) - def test_add_hotkey_multi_step_suppress_regression_1(self): - keyboard.add_hotkey('a, b', trigger, suppress=True) - self.do(d_c+d_a+u_c+u_a+du_c, d_c+d_a+u_c+u_a+du_c) - def test_add_hotkey_multi_step_suppress_replays(self): - keyboard.add_hotkey('a, b, c', trigger, suppress=True) - self.do(du_a+du_b+du_a+du_b+du_space, du_a+du_b+du_a+du_b+du_space) - - def test_add_word_listener_success(self): - queue = keyboard._queue.Queue() - def free(): - queue.put(1) - keyboard.add_word_listener('abc', free) - self.do(du_a+du_b+du_c+du_space) - self.assertTrue(queue.get(timeout=0.5)) - def test_add_word_listener_no_trigger_fail(self): - queue = keyboard._queue.Queue() - def free(): - queue.put(1) - keyboard.add_word_listener('abc', free) - self.do(du_a+du_b+du_c) - with self.assertRaises(keyboard._queue.Empty): - queue.get(timeout=0.01) - def test_add_word_listener_timeout_fail(self): - queue = keyboard._queue.Queue() - def free(): - queue.put(1) - keyboard.add_word_listener('abc', free, timeout=1) - self.do(du_a+du_b+du_c+[make_event(KEY_DOWN, name='space', time=2)]) - with self.assertRaises(keyboard._queue.Empty): - queue.get(timeout=0.01) - def test_duplicated_word_listener(self): - keyboard.add_word_listener('abc', trigger) - keyboard.add_word_listener('abc', trigger) - def test_add_word_listener_remove(self): - queue = keyboard._queue.Queue() - def free(): - queue.put(1) - keyboard.add_word_listener('abc', free) - keyboard.remove_word_listener('abc') - self.do(du_a+du_b+du_c+du_space) - with self.assertRaises(keyboard._queue.Empty): - queue.get(timeout=0.01) - def test_add_word_listener_suffix_success(self): - queue = keyboard._queue.Queue() - def free(): - queue.put(1) - keyboard.add_word_listener('abc', free, match_suffix=True) - self.do(du_a+du_a+du_b+du_c+du_space) - self.assertTrue(queue.get(timeout=0.5)) - def test_add_word_listener_suffix_fail(self): - queue = keyboard._queue.Queue() - def free(): - queue.put(1) - keyboard.add_word_listener('abc', free) - self.do(du_a+du_a+du_b+du_c) - with self.assertRaises(keyboard._queue.Empty): - queue.get(timeout=0.01) - - #def test_add_abbreviation(self): - # keyboard.add_abbreviation('abc', 'aaa') - # self.do(du_a+du_b+du_c+du_space, []) - - -if __name__ == '__main__': - unittest.main()
\ No newline at end of file diff --git a/Python/venv1/Lib/site-packages/keyboard/_mouse_event.py b/Python/venv1/Lib/site-packages/keyboard/_mouse_event.py deleted file mode 100644 index 38b8961..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_mouse_event.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from collections import namedtuple - -LEFT = 'left' -RIGHT = 'right' -MIDDLE = 'middle' -WHEEL = 'wheel' -X = 'x' -X2 = 'x2' - -UP = 'up' -DOWN = 'down' -DOUBLE = 'double' -VERTICAL = 'vertical' -HORIZONTAL = 'horizontal' - - -ButtonEvent = namedtuple('ButtonEvent', ['event_type', 'button', 'time']) -WheelEvent = namedtuple('WheelEvent', ['delta', 'time']) -MoveEvent = namedtuple('MoveEvent', ['x', 'y', 'time']) diff --git a/Python/venv1/Lib/site-packages/keyboard/_mouse_tests.py b/Python/venv1/Lib/site-packages/keyboard/_mouse_tests.py deleted file mode 100644 index 6a2b2e4..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_mouse_tests.py +++ /dev/null @@ -1,271 +0,0 @@ -# -*- coding: utf-8 -*- -import unittest -import time - -from ._mouse_event import MoveEvent, ButtonEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE -from keyboard import mouse - -class FakeOsMouse(object): - def __init__(self): - self.append = None - self.position = (0, 0) - self.queue = None - self.init = lambda: None - - def listen(self, queue): - self.listening = True - self.queue = queue - - def press(self, button): - self.append((DOWN, button)) - - def release(self, button): - self.append((UP, button)) - - def get_position(self): - return self.position - - def move_to(self, x, y): - self.append(('move', (x, y))) - self.position = (x, y) - - def wheel(self, delta): - self.append(('wheel', delta)) - - def move_relative(self, x, y): - self.position = (self.position[0] + x, self.position[1] + y) - -class TestMouse(unittest.TestCase): - @staticmethod - def setUpClass(): - mouse._os_mouse= FakeOsMouse() - mouse._listener.start_if_necessary() - assert mouse._os_mouse.listening - - def setUp(self): - self.events = [] - mouse._pressed_events.clear() - mouse._os_mouse.append = self.events.append - - def tearDown(self): - mouse.unhook_all() - # Make sure there's no spill over between tests. - self.wait_for_events_queue() - - def wait_for_events_queue(self): - mouse._listener.queue.join() - - def flush_events(self): - self.wait_for_events_queue() - events = list(self.events) - # Ugly, but requried to work in Python2. Python3 has list.clear - del self.events[:] - return events - - def press(self, button=LEFT): - mouse._os_mouse.queue.put(ButtonEvent(DOWN, button, time.time())) - self.wait_for_events_queue() - - def release(self, button=LEFT): - mouse._os_mouse.queue.put(ButtonEvent(UP, button, time.time())) - self.wait_for_events_queue() - - def double_click(self, button=LEFT): - mouse._os_mouse.queue.put(ButtonEvent(DOUBLE, button, time.time())) - self.wait_for_events_queue() - - def click(self, button=LEFT): - self.press(button) - self.release(button) - - def wheel(self, delta=1): - mouse._os_mouse.queue.put(WheelEvent(delta, time.time())) - self.wait_for_events_queue() - - def move(self, x=0, y=0): - mouse._os_mouse.queue.put(MoveEvent(x, y, time.time())) - self.wait_for_events_queue() - - def test_hook(self): - events = [] - self.press() - mouse.hook(events.append) - self.press() - mouse.unhook(events.append) - self.press() - self.assertEqual(len(events), 1) - - def test_is_pressed(self): - self.assertFalse(mouse.is_pressed()) - self.press() - self.assertTrue(mouse.is_pressed()) - self.release() - self.press(X2) - self.assertFalse(mouse.is_pressed()) - - self.assertTrue(mouse.is_pressed(X2)) - self.press(X2) - self.assertTrue(mouse.is_pressed(X2)) - self.release(X2) - self.release(X2) - self.assertFalse(mouse.is_pressed(X2)) - - def test_buttons(self): - mouse.press() - self.assertEqual(self.flush_events(), [(DOWN, LEFT)]) - mouse.release() - self.assertEqual(self.flush_events(), [(UP, LEFT)]) - mouse.click() - self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT)]) - mouse.double_click() - self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT), (DOWN, LEFT), (UP, LEFT)]) - mouse.right_click() - self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)]) - mouse.click(RIGHT) - self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)]) - mouse.press(X2) - self.assertEqual(self.flush_events(), [(DOWN, X2)]) - - def test_position(self): - self.assertEqual(mouse.get_position(), mouse._os_mouse.get_position()) - - def test_move(self): - mouse.move(0, 0) - self.assertEqual(mouse._os_mouse.get_position(), (0, 0)) - mouse.move(100, 500) - self.assertEqual(mouse._os_mouse.get_position(), (100, 500)) - mouse.move(1, 2, False) - self.assertEqual(mouse._os_mouse.get_position(), (101, 502)) - - mouse.move(0, 0) - mouse.move(100, 499, True, duration=0.01) - self.assertEqual(mouse._os_mouse.get_position(), (100, 499)) - mouse.move(100, 1, False, duration=0.01) - self.assertEqual(mouse._os_mouse.get_position(), (200, 500)) - mouse.move(0, 0, False, duration=0.01) - self.assertEqual(mouse._os_mouse.get_position(), (200, 500)) - - def triggers(self, fn, events, **kwargs): - self.triggered = False - def callback(): - self.triggered = True - handler = fn(callback, **kwargs) - - for event_type, arg in events: - if event_type == DOWN: - self.press(arg) - elif event_type == UP: - self.release(arg) - elif event_type == DOUBLE: - self.double_click(arg) - elif event_type == 'WHEEL': - self.wheel() - - mouse._listener.remove_handler(handler) - return self.triggered - - def test_on_button(self): - self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)])) - self.assertTrue(self.triggers(mouse.on_button, [(DOWN, RIGHT)])) - self.assertTrue(self.triggers(mouse.on_button, [(DOWN, X)])) - - self.assertFalse(self.triggers(mouse.on_button, [('WHEEL', '')])) - - self.assertFalse(self.triggers(mouse.on_button, [(DOWN, X)], buttons=MIDDLE)) - self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE)) - self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE)) - self.assertFalse(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE, types=UP)) - self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=MIDDLE, types=UP)) - - self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) - self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) - self.assertFalse(self.triggers(mouse.on_button, [(UP, X)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) - - def test_ons(self): - self.assertTrue(self.triggers(mouse.on_click, [(UP, LEFT)])) - self.assertFalse(self.triggers(mouse.on_click, [(UP, RIGHT)])) - self.assertFalse(self.triggers(mouse.on_click, [(DOWN, LEFT)])) - self.assertFalse(self.triggers(mouse.on_click, [(DOWN, RIGHT)])) - - self.assertTrue(self.triggers(mouse.on_double_click, [(DOUBLE, LEFT)])) - self.assertFalse(self.triggers(mouse.on_double_click, [(DOUBLE, RIGHT)])) - self.assertFalse(self.triggers(mouse.on_double_click, [(DOWN, RIGHT)])) - - self.assertTrue(self.triggers(mouse.on_right_click, [(UP, RIGHT)])) - self.assertTrue(self.triggers(mouse.on_middle_click, [(UP, MIDDLE)])) - - def test_wait(self): - # If this fails it blocks. Unfortunately, but I see no other way of testing. - from threading import Thread, Lock - lock = Lock() - lock.acquire() - def t(): - mouse.wait() - lock.release() - Thread(target=t).start() - self.press() - lock.acquire() - - def test_record_play(self): - from threading import Thread, Lock - lock = Lock() - lock.acquire() - def t(): - self.recorded = mouse.record(RIGHT) - lock.release() - Thread(target=t).start() - self.click() - self.wheel(5) - self.move(100, 50) - self.press(RIGHT) - lock.acquire() - - self.assertEqual(len(self.recorded), 5) - self.assertEqual(self.recorded[0]._replace(time=None), ButtonEvent(DOWN, LEFT, None)) - self.assertEqual(self.recorded[1]._replace(time=None), ButtonEvent(UP, LEFT, None)) - self.assertEqual(self.recorded[2]._replace(time=None), WheelEvent(5, None)) - self.assertEqual(self.recorded[3]._replace(time=None), MoveEvent(100, 50, None)) - self.assertEqual(self.recorded[4]._replace(time=None), ButtonEvent(DOWN, RIGHT, None)) - - mouse.play(self.recorded, speed_factor=0) - events = self.flush_events() - self.assertEqual(len(events), 5) - self.assertEqual(events[0], (DOWN, LEFT)) - self.assertEqual(events[1], (UP, LEFT)) - self.assertEqual(events[2], ('wheel', 5)) - self.assertEqual(events[3], ('move', (100, 50))) - self.assertEqual(events[4], (DOWN, RIGHT)) - - mouse.play(self.recorded) - events = self.flush_events() - self.assertEqual(len(events), 5) - self.assertEqual(events[0], (DOWN, LEFT)) - self.assertEqual(events[1], (UP, LEFT)) - self.assertEqual(events[2], ('wheel', 5)) - self.assertEqual(events[3], ('move', (100, 50))) - self.assertEqual(events[4], (DOWN, RIGHT)) - - mouse.play(self.recorded, include_clicks=False) - events = self.flush_events() - self.assertEqual(len(events), 2) - self.assertEqual(events[0], ('wheel', 5)) - self.assertEqual(events[1], ('move', (100, 50))) - - mouse.play(self.recorded, include_moves=False) - events = self.flush_events() - self.assertEqual(len(events), 4) - self.assertEqual(events[0], (DOWN, LEFT)) - self.assertEqual(events[1], (UP, LEFT)) - self.assertEqual(events[2], ('wheel', 5)) - self.assertEqual(events[3], (DOWN, RIGHT)) - - mouse.play(self.recorded, include_wheel=False) - events = self.flush_events() - self.assertEqual(len(events), 4) - self.assertEqual(events[0], (DOWN, LEFT)) - self.assertEqual(events[1], (UP, LEFT)) - self.assertEqual(events[2], ('move', (100, 50))) - self.assertEqual(events[3], (DOWN, RIGHT)) - -if __name__ == '__main__': - unittest.main() diff --git a/Python/venv1/Lib/site-packages/keyboard/_nixcommon.py b/Python/venv1/Lib/site-packages/keyboard/_nixcommon.py deleted file mode 100644 index a4d0d06..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_nixcommon.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -import struct -import os -import atexit -from time import time as now -from threading import Thread -from glob import glob -try: - from queue import Queue -except ImportError: - from Queue import Queue - -event_bin_format = 'llHHI' - -# Taken from include/linux/input.h -# https://www.kernel.org/doc/Documentation/input/event-codes.txt -EV_SYN = 0x00 -EV_KEY = 0x01 -EV_REL = 0x02 -EV_ABS = 0x03 -EV_MSC = 0x04 - -def make_uinput(): - if not os.path.exists('/dev/uinput'): - raise IOError('No uinput module found.') - - import fcntl, struct - - # Requires uinput driver, but it's usually available. - uinput = open("/dev/uinput", 'wb') - UI_SET_EVBIT = 0x40045564 - fcntl.ioctl(uinput, UI_SET_EVBIT, EV_KEY) - - UI_SET_KEYBIT = 0x40045565 - for i in range(256): - fcntl.ioctl(uinput, UI_SET_KEYBIT, i) - - BUS_USB = 0x03 - uinput_user_dev = "80sHHHHi64i64i64i64i" - axis = [0] * 64 * 4 - uinput.write(struct.pack(uinput_user_dev, b"Virtual Keyboard", BUS_USB, 1, 1, 1, 0, *axis)) - uinput.flush() # Without this you may get Errno 22: Invalid argument. - - UI_DEV_CREATE = 0x5501 - fcntl.ioctl(uinput, UI_DEV_CREATE) - UI_DEV_DESTROY = 0x5502 - #fcntl.ioctl(uinput, UI_DEV_DESTROY) - - return uinput - -class EventDevice(object): - def __init__(self, path): - self.path = path - self._input_file = None - self._output_file = None - - @property - def input_file(self): - if self._input_file is None: - try: - self._input_file = open(self.path, 'rb') - except IOError as e: - if e.strerror == 'Permission denied': - print('Permission denied ({}). You must be sudo to access global events.'.format(self.path)) - exit() - - def try_close(): - try: - self._input_file.close - except: - pass - atexit.register(try_close) - return self._input_file - - @property - def output_file(self): - if self._output_file is None: - self._output_file = open(self.path, 'wb') - atexit.register(self._output_file.close) - return self._output_file - - def read_event(self): - data = self.input_file.read(struct.calcsize(event_bin_format)) - seconds, microseconds, type, code, value = struct.unpack(event_bin_format, data) - return seconds + microseconds / 1e6, type, code, value, self.path - - def write_event(self, type, code, value): - integer, fraction = divmod(now(), 1) - seconds = int(integer) - microseconds = int(fraction * 1e6) - data_event = struct.pack(event_bin_format, seconds, microseconds, type, code, value) - - # Send a sync event to ensure other programs update. - sync_event = struct.pack(event_bin_format, seconds, microseconds, EV_SYN, 0, 0) - - self.output_file.write(data_event + sync_event) - self.output_file.flush() - -class AggregatedEventDevice(object): - def __init__(self, devices, output=None): - self.event_queue = Queue() - self.devices = devices - self.output = output or self.devices[0] - def start_reading(device): - while True: - self.event_queue.put(device.read_event()) - for device in self.devices: - thread = Thread(target=start_reading, args=[device]) - thread.setDaemon(True) - thread.start() - - def read_event(self): - return self.event_queue.get(block=True) - - def write_event(self, type, code, value): - self.output.write_event(type, code, value) - -import re -from collections import namedtuple -DeviceDescription = namedtuple('DeviceDescription', 'event_file is_mouse is_keyboard') -device_pattern = r"""N: Name="([^"]+?)".+?H: Handlers=([^\n]+)""" -def list_devices_from_proc(type_name): - try: - with open('/proc/bus/input/devices') as f: - description = f.read() - except FileNotFoundError: - return - - devices = {} - for name, handlers in re.findall(device_pattern, description, re.DOTALL): - path = '/dev/input/event' + re.search(r'event(\d+)', handlers).group(1) - if type_name in handlers: - yield EventDevice(path) - -def list_devices_from_by_id(name_suffix, by_id=True): - for path in glob('/dev/input/{}/*-event-{}'.format('by-id' if by_id else 'by-path', name_suffix)): - yield EventDevice(path) - -def aggregate_devices(type_name): - # Some systems have multiple keyboards with different range of allowed keys - # on each one, like a notebook with a "keyboard" device exclusive for the - # power button. Instead of figuring out which keyboard allows which key to - # send events, we create a fake device and send all events through there. - try: - uinput = make_uinput() - fake_device = EventDevice('uinput Fake Device') - fake_device._input_file = uinput - fake_device._output_file = uinput - except IOError as e: - import warnings - warnings.warn('Failed to create a device file using `uinput` module. Sending of events may be limited or unavailable depending on plugged-in devices.', stacklevel=2) - fake_device = None - - # We don't aggregate devices from different sources to avoid - # duplicates. - - devices_from_proc = list(list_devices_from_proc(type_name)) - if devices_from_proc: - return AggregatedEventDevice(devices_from_proc, output=fake_device) - - # breaks on mouse for virtualbox - # was getting /dev/input/by-id/usb-VirtualBox_USB_Tablet-event-mouse - devices_from_by_id = list(list_devices_from_by_id(type_name)) or list(list_devices_from_by_id(type_name, by_id=False)) - if devices_from_by_id: - return AggregatedEventDevice(devices_from_by_id, output=fake_device) - - # If no keyboards were found we can only use the fake device to send keys. - assert fake_device - return fake_device - - -def ensure_root(): - if os.geteuid() != 0: - raise ImportError('You must be root to use this library on linux.') diff --git a/Python/venv1/Lib/site-packages/keyboard/_nixkeyboard.py b/Python/venv1/Lib/site-packages/keyboard/_nixkeyboard.py deleted file mode 100644 index d3950a1..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_nixkeyboard.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -import struct -import traceback -from time import time as now -from collections import namedtuple -from ._keyboard_event import KeyboardEvent, KEY_DOWN, KEY_UP -from ._canonical_names import all_modifiers, normalize_name -from ._nixcommon import EV_KEY, aggregate_devices, ensure_root - -# TODO: start by reading current keyboard state, as to not missing any already pressed keys. -# See: http://stackoverflow.com/questions/3649874/how-to-get-keyboard-state-in-linux - -def cleanup_key(name): - """ Formats a dumpkeys format to our standard. """ - name = name.lstrip('+') - is_keypad = name.startswith('KP_') - for mod in ('Meta_', 'Control_', 'dead_', 'KP_'): - if name.startswith(mod): - name = name[len(mod):] - - # Dumpkeys is weird like that. - if name == 'Remove': - name = 'Delete' - elif name == 'Delete': - name = 'Backspace' - - if name.endswith('_r'): - name = 'right ' + name[:-2] - if name.endswith('_l'): - name = 'left ' + name[:-2] - - - return normalize_name(name), is_keypad - -def cleanup_modifier(modifier): - modifier = normalize_name(modifier) - if modifier in all_modifiers: - return modifier - if modifier[:-1] in all_modifiers: - return modifier[:-1] - raise ValueError('Unknown modifier {}'.format(modifier)) - -""" -Use `dumpkeys --keys-only` to list all scan codes and their names. We -then parse the output and built a table. For each scan code and modifiers we -have a list of names and vice-versa. -""" -from subprocess import check_output -from collections import defaultdict -import re - -to_name = defaultdict(list) -from_name = defaultdict(list) -keypad_scan_codes = set() - -def register_key(key_and_modifiers, name): - if name not in to_name[key_and_modifiers]: - to_name[key_and_modifiers].append(name) - if key_and_modifiers not in from_name[name]: - from_name[name].append(key_and_modifiers) - -def build_tables(): - if to_name and from_name: return - ensure_root() - - modifiers_bits = { - 'shift': 1, - 'alt gr': 2, - 'ctrl': 4, - 'alt': 8, - } - keycode_template = r'^keycode\s+(\d+)\s+=(.*?)$' - dump = check_output(['dumpkeys', '--keys-only'], universal_newlines=True) - for str_scan_code, str_names in re.findall(keycode_template, dump, re.MULTILINE): - scan_code = int(str_scan_code) - for i, str_name in enumerate(str_names.strip().split()): - modifiers = tuple(sorted(modifier for modifier, bit in modifiers_bits.items() if i & bit)) - name, is_keypad = cleanup_key(str_name) - register_key((scan_code, modifiers), name) - if is_keypad: - keypad_scan_codes.add(scan_code) - register_key((scan_code, modifiers), 'keypad ' + name) - - # dumpkeys consistently misreports the Windows key, sometimes - # skipping it completely or reporting as 'alt. 125 = left win, - # 126 = right win. - if (125, ()) not in to_name or to_name[(125, ())] == 'alt': - register_key((125, ()), 'windows') - if (126, ()) not in to_name or to_name[(126, ())] == 'alt': - register_key((126, ()), 'windows') - - # The menu key is usually skipped altogether, so we also add it manually. - if (127, ()) not in to_name: - register_key((127, ()), 'menu') - - synonyms_template = r'^(\S+)\s+for (.+)$' - dump = check_output(['dumpkeys', '--long-info'], universal_newlines=True) - for synonym_str, original_str in re.findall(synonyms_template, dump, re.MULTILINE): - synonym, _ = cleanup_key(synonym_str) - original, _ = cleanup_key(original_str) - if synonym != original: - from_name[original].extend(from_name[synonym]) - from_name[synonym].extend(from_name[original]) - -device = None -def build_device(): - global device - if device: return - ensure_root() - device = aggregate_devices('kbd') - -def init(): - build_device() - build_tables() - -pressed_modifiers = set() - -def listen(callback): - build_device() - build_tables() - - while True: - time, type, code, value, device_id = device.read_event() - if type != EV_KEY: - continue - - scan_code = code - event_type = KEY_DOWN if value else KEY_UP # 0 = UP, 1 = DOWN, 2 = HOLD - - pressed_modifiers_tuple = tuple(sorted(pressed_modifiers)) - names = to_name[(scan_code, pressed_modifiers_tuple)] or to_name[(scan_code, ())] or ['unknown'] - name = names[0] - - if name in all_modifiers: - if event_type == KEY_DOWN: - pressed_modifiers.add(name) - else: - pressed_modifiers.discard(name) - - is_keypad = scan_code in keypad_scan_codes - callback(KeyboardEvent(event_type=event_type, scan_code=scan_code, name=name, time=time, device=device_id, is_keypad=is_keypad, modifiers=pressed_modifiers_tuple)) - -def write_event(scan_code, is_down): - build_device() - device.write_event(EV_KEY, scan_code, int(is_down)) - -def map_name(name): - build_tables() - for entry in from_name[name]: - yield entry - - parts = name.split(' ', 1) - if len(parts) > 1 and parts[0] in ('left', 'right'): - for entry in from_name[parts[1]]: - yield entry - -def press(scan_code): - write_event(scan_code, True) - -def release(scan_code): - write_event(scan_code, False) - -def type_unicode(character): - codepoint = ord(character) - hexadecimal = hex(codepoint)[len('0x'):] - - for key in ['ctrl', 'shift', 'u']: - scan_code, _ = next(map_name(key)) - press(scan_code) - - for key in hexadecimal: - scan_code, _ = next(map_name(key)) - press(scan_code) - release(scan_code) - - for key in ['ctrl', 'shift', 'u']: - scan_code, _ = next(map_name(key)) - release(scan_code) - -if __name__ == '__main__': - def p(e): - print(e) - listen(p) diff --git a/Python/venv1/Lib/site-packages/keyboard/_nixmouse.py b/Python/venv1/Lib/site-packages/keyboard/_nixmouse.py deleted file mode 100644 index 6b02c57..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_nixmouse.py +++ /dev/null @@ -1,130 +0,0 @@ -# -*- coding: utf-8 -*- -import struct -from subprocess import check_output -import re -from ._nixcommon import EV_KEY, EV_REL, EV_MSC, EV_SYN, EV_ABS, aggregate_devices, ensure_root -from ._mouse_event import ButtonEvent, WheelEvent, MoveEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN - -import ctypes -import ctypes.util -from ctypes import c_uint32, c_uint, c_int, byref - -display = None -window = None -x11 = None -def build_display(): - global display, window, x11 - if display and window and x11: return - x11 = ctypes.cdll.LoadLibrary(ctypes.util.find_library('X11')) - # Required because we will have multiple threads calling x11, - # such as the listener thread and then main using "move_to". - x11.XInitThreads() - display = x11.XOpenDisplay(None) - # Known to cause segfault in Fedora 23 64bits, no known workarounds. - # http://stackoverflow.com/questions/35137007/get-mouse-position-on-linux-pure-python - window = x11.XDefaultRootWindow(display) - -def get_position(): - build_display() - root_id, child_id = c_uint32(), c_uint32() - root_x, root_y, win_x, win_y = c_int(), c_int(), c_int(), c_int() - mask = c_uint() - ret = x11.XQueryPointer(display, c_uint32(window), byref(root_id), byref(child_id), - byref(root_x), byref(root_y), - byref(win_x), byref(win_y), byref(mask)) - return root_x.value, root_y.value - -def move_to(x, y): - build_display() - x11.XWarpPointer(display, None, window, 0, 0, 0, 0, x, y) - x11.XFlush(display) - -REL_X = 0x00 -REL_Y = 0x01 -REL_Z = 0x02 -REL_HWHEEL = 0x06 -REL_WHEEL = 0x08 - -ABS_X = 0x00 -ABS_Y = 0x01 - -BTN_MOUSE = 0x110 -BTN_LEFT = 0x110 -BTN_RIGHT = 0x111 -BTN_MIDDLE = 0x112 -BTN_SIDE = 0x113 -BTN_EXTRA = 0x114 - -button_by_code = { - BTN_LEFT: LEFT, - BTN_RIGHT: RIGHT, - BTN_MIDDLE: MIDDLE, - BTN_SIDE: X, - BTN_EXTRA: X2, -} -code_by_button = {button: code for code, button in button_by_code.items()} - -device = None -def build_device(): - global device - if device: return - ensure_root() - device = aggregate_devices('mouse') -init = build_device - -def listen(queue): - build_device() - - while True: - time, type, code, value, device_id = device.read_event() - if type == EV_SYN or type == EV_MSC: - continue - - event = None - arg = None - - if type == EV_KEY: - event = ButtonEvent(DOWN if value else UP, button_by_code.get(code, '?'), time) - elif type == EV_REL: - value, = struct.unpack('i', struct.pack('I', value)) - - if code == REL_WHEEL: - event = WheelEvent(value, time) - elif code in (REL_X, REL_Y): - x, y = get_position() - event = MoveEvent(x, y, time) - - if event is None: - # Unknown event type. - continue - - queue.put(event) - -def press(button=LEFT): - build_device() - device.write_event(EV_KEY, code_by_button[button], 0x01) - -def release(button=LEFT): - build_device() - device.write_event(EV_KEY, code_by_button[button], 0x00) - -def move_relative(x, y): - build_device() - # Note relative events are not in terms of pixels, but millimeters. - if x < 0: - x += 2**32 - if y < 0: - y += 2**32 - device.write_event(EV_REL, REL_X, x) - device.write_event(EV_REL, REL_Y, y) - -def wheel(delta=1): - build_device() - if delta < 0: - delta += 2**32 - device.write_event(EV_REL, REL_WHEEL, delta) - - -if __name__ == '__main__': - #listen(print) - move_to(100, 200) diff --git a/Python/venv1/Lib/site-packages/keyboard/_winkeyboard.py b/Python/venv1/Lib/site-packages/keyboard/_winkeyboard.py deleted file mode 100644 index 528e95f..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_winkeyboard.py +++ /dev/null @@ -1,620 +0,0 @@ -# -*- coding: utf-8 -*- -""" -This is the Windows backend for keyboard events, and is implemented by -invoking the Win32 API through the ctypes module. This is error prone -and can introduce very unpythonic failure modes, such as segfaults and -low level memory leaks. But it is also dependency-free, very performant -well documented on Microsoft's webstie and scattered examples. - -# TODO: -- Keypad numbers still print as numbers even when numlock is off. -- No way to specify if user wants a keypad key or not in `map_char`. -""" -from __future__ import unicode_literals -import re -import atexit -import traceback -from threading import Lock -from collections import defaultdict - -from ._keyboard_event import KeyboardEvent, KEY_DOWN, KEY_UP -from ._canonical_names import normalize_name -try: - # Force Python2 to convert to unicode and not to str. - chr = unichr -except NameError: - pass - -# This part is just declaring Win32 API structures using ctypes. In C -# this would be simply #include "windows.h". - -import ctypes -from ctypes import c_short, c_char, c_uint8, c_int32, c_int, c_uint, c_uint32, c_long, Structure, CFUNCTYPE, POINTER -from ctypes.wintypes import WORD, DWORD, BOOL, HHOOK, MSG, LPWSTR, WCHAR, WPARAM, LPARAM, LONG, HMODULE, LPCWSTR, HINSTANCE, HWND -LPMSG = POINTER(MSG) -ULONG_PTR = POINTER(DWORD) - -kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) -GetModuleHandleW = kernel32.GetModuleHandleW -GetModuleHandleW.restype = HMODULE -GetModuleHandleW.argtypes = [LPCWSTR] - -#https://github.com/boppreh/mouse/issues/1 -#user32 = ctypes.windll.user32 -user32 = ctypes.WinDLL('user32', use_last_error = True) - -VK_PACKET = 0xE7 - -INPUT_MOUSE = 0 -INPUT_KEYBOARD = 1 -INPUT_HARDWARE = 2 - -KEYEVENTF_KEYUP = 0x02 -KEYEVENTF_UNICODE = 0x04 - -class KBDLLHOOKSTRUCT(Structure): - _fields_ = [("vk_code", DWORD), - ("scan_code", DWORD), - ("flags", DWORD), - ("time", c_int), - ("dwExtraInfo", ULONG_PTR)] - -# Included for completeness. -class MOUSEINPUT(ctypes.Structure): - _fields_ = (('dx', LONG), - ('dy', LONG), - ('mouseData', DWORD), - ('dwFlags', DWORD), - ('time', DWORD), - ('dwExtraInfo', ULONG_PTR)) - -class KEYBDINPUT(ctypes.Structure): - _fields_ = (('wVk', WORD), - ('wScan', WORD), - ('dwFlags', DWORD), - ('time', DWORD), - ('dwExtraInfo', ULONG_PTR)) - -class HARDWAREINPUT(ctypes.Structure): - _fields_ = (('uMsg', DWORD), - ('wParamL', WORD), - ('wParamH', WORD)) - -class _INPUTunion(ctypes.Union): - _fields_ = (('mi', MOUSEINPUT), - ('ki', KEYBDINPUT), - ('hi', HARDWAREINPUT)) - -class INPUT(ctypes.Structure): - _fields_ = (('type', DWORD), - ('union', _INPUTunion)) - -LowLevelKeyboardProc = CFUNCTYPE(c_int, WPARAM, LPARAM, POINTER(KBDLLHOOKSTRUCT)) - -SetWindowsHookEx = user32.SetWindowsHookExW -SetWindowsHookEx.argtypes = [c_int, LowLevelKeyboardProc, HINSTANCE , DWORD] -SetWindowsHookEx.restype = HHOOK - -CallNextHookEx = user32.CallNextHookEx -#CallNextHookEx.argtypes = [c_int , c_int, c_int, POINTER(KBDLLHOOKSTRUCT)] -CallNextHookEx.restype = c_int - -UnhookWindowsHookEx = user32.UnhookWindowsHookEx -UnhookWindowsHookEx.argtypes = [HHOOK] -UnhookWindowsHookEx.restype = BOOL - -GetMessage = user32.GetMessageW -GetMessage.argtypes = [LPMSG, HWND, c_uint, c_uint] -GetMessage.restype = BOOL - -TranslateMessage = user32.TranslateMessage -TranslateMessage.argtypes = [LPMSG] -TranslateMessage.restype = BOOL - -DispatchMessage = user32.DispatchMessageA -DispatchMessage.argtypes = [LPMSG] - - -keyboard_state_type = c_uint8 * 256 - -GetKeyboardState = user32.GetKeyboardState -GetKeyboardState.argtypes = [keyboard_state_type] -GetKeyboardState.restype = BOOL - -GetKeyNameText = user32.GetKeyNameTextW -GetKeyNameText.argtypes = [c_long, LPWSTR, c_int] -GetKeyNameText.restype = c_int - -MapVirtualKey = user32.MapVirtualKeyW -MapVirtualKey.argtypes = [c_uint, c_uint] -MapVirtualKey.restype = c_uint - -ToUnicode = user32.ToUnicode -ToUnicode.argtypes = [c_uint, c_uint, keyboard_state_type, LPWSTR, c_int, c_uint] -ToUnicode.restype = c_int - -SendInput = user32.SendInput -SendInput.argtypes = [c_uint, POINTER(INPUT), c_int] -SendInput.restype = c_uint - -# https://msdn.microsoft.com/en-us/library/windows/desktop/ms646307(v=vs.85).aspx -MAPVK_VK_TO_CHAR = 2 -MAPVK_VK_TO_VSC = 0 -MAPVK_VSC_TO_VK = 1 -MAPVK_VK_TO_VSC_EX = 4 -MAPVK_VSC_TO_VK_EX = 3 - -VkKeyScan = user32.VkKeyScanW -VkKeyScan.argtypes = [WCHAR] -VkKeyScan.restype = c_short - -LLKHF_INJECTED = 0x00000010 - -WM_KEYDOWN = 0x0100 -WM_KEYUP = 0x0101 -WM_SYSKEYDOWN = 0x104 # Used for ALT key -WM_SYSKEYUP = 0x105 - - -# This marks the end of Win32 API declarations. The rest is ours. - -keyboard_event_types = { - WM_KEYDOWN: KEY_DOWN, - WM_KEYUP: KEY_UP, - WM_SYSKEYDOWN: KEY_DOWN, - WM_SYSKEYUP: KEY_UP, -} - -# List taken from the official documentation, but stripped of the OEM-specific keys. -# Keys are virtual key codes, values are pairs (name, is_keypad). -official_virtual_keys = { - 0x03: ('control-break processing', False), - 0x08: ('backspace', False), - 0x09: ('tab', False), - 0x0c: ('clear', False), - 0x0d: ('enter', False), - 0x10: ('shift', False), - 0x11: ('ctrl', False), - 0x12: ('alt', False), - 0x13: ('pause', False), - 0x14: ('caps lock', False), - 0x15: ('ime kana mode', False), - 0x15: ('ime hanguel mode', False), - 0x15: ('ime hangul mode', False), - 0x17: ('ime junja mode', False), - 0x18: ('ime final mode', False), - 0x19: ('ime hanja mode', False), - 0x19: ('ime kanji mode', False), - 0x1b: ('esc', False), - 0x1c: ('ime convert', False), - 0x1d: ('ime nonconvert', False), - 0x1e: ('ime accept', False), - 0x1f: ('ime mode change request', False), - 0x20: ('spacebar', False), - 0x21: ('page up', False), - 0x22: ('page down', False), - 0x23: ('end', False), - 0x24: ('home', False), - 0x25: ('left', False), - 0x26: ('up', False), - 0x27: ('right', False), - 0x28: ('down', False), - 0x29: ('select', False), - 0x2a: ('print', False), - 0x2b: ('execute', False), - 0x2c: ('print screen', False), - 0x2d: ('insert', False), - 0x2e: ('delete', False), - 0x2f: ('help', False), - 0x30: ('0', False), - 0x31: ('1', False), - 0x32: ('2', False), - 0x33: ('3', False), - 0x34: ('4', False), - 0x35: ('5', False), - 0x36: ('6', False), - 0x37: ('7', False), - 0x38: ('8', False), - 0x39: ('9', False), - 0x41: ('a', False), - 0x42: ('b', False), - 0x43: ('c', False), - 0x44: ('d', False), - 0x45: ('e', False), - 0x46: ('f', False), - 0x47: ('g', False), - 0x48: ('h', False), - 0x49: ('i', False), - 0x4a: ('j', False), - 0x4b: ('k', False), - 0x4c: ('l', False), - 0x4d: ('m', False), - 0x4e: ('n', False), - 0x4f: ('o', False), - 0x50: ('p', False), - 0x51: ('q', False), - 0x52: ('r', False), - 0x53: ('s', False), - 0x54: ('t', False), - 0x55: ('u', False), - 0x56: ('v', False), - 0x57: ('w', False), - 0x58: ('x', False), - 0x59: ('y', False), - 0x5a: ('z', False), - 0x5b: ('left windows', False), - 0x5c: ('right windows', False), - 0x5d: ('applications', False), - 0x5f: ('sleep', False), - 0x60: ('0', True), - 0x61: ('1', True), - 0x62: ('2', True), - 0x63: ('3', True), - 0x64: ('4', True), - 0x65: ('5', True), - 0x66: ('6', True), - 0x67: ('7', True), - 0x68: ('8', True), - 0x69: ('9', True), - 0x6a: ('*', True), - 0x6b: ('+', True), - 0x6c: ('separator', True), - 0x6d: ('-', True), - 0x6e: ('decimal', True), - 0x6f: ('/', True), - 0x70: ('f1', False), - 0x71: ('f2', False), - 0x72: ('f3', False), - 0x73: ('f4', False), - 0x74: ('f5', False), - 0x75: ('f6', False), - 0x76: ('f7', False), - 0x77: ('f8', False), - 0x78: ('f9', False), - 0x79: ('f10', False), - 0x7a: ('f11', False), - 0x7b: ('f12', False), - 0x7c: ('f13', False), - 0x7d: ('f14', False), - 0x7e: ('f15', False), - 0x7f: ('f16', False), - 0x80: ('f17', False), - 0x81: ('f18', False), - 0x82: ('f19', False), - 0x83: ('f20', False), - 0x84: ('f21', False), - 0x85: ('f22', False), - 0x86: ('f23', False), - 0x87: ('f24', False), - 0x90: ('num lock', False), - 0x91: ('scroll lock', False), - 0xa0: ('left shift', False), - 0xa1: ('right shift', False), - 0xa2: ('left ctrl', False), - 0xa3: ('right ctrl', False), - 0xa4: ('left menu', False), - 0xa5: ('right menu', False), - 0xa6: ('browser back', False), - 0xa7: ('browser forward', False), - 0xa8: ('browser refresh', False), - 0xa9: ('browser stop', False), - 0xaa: ('browser search key', False), - 0xab: ('browser favorites', False), - 0xac: ('browser start and home', False), - 0xad: ('volume mute', False), - 0xae: ('volume down', False), - 0xaf: ('volume up', False), - 0xb0: ('next track', False), - 0xb1: ('previous track', False), - 0xb2: ('stop media', False), - 0xb3: ('play/pause media', False), - 0xb4: ('start mail', False), - 0xb5: ('select media', False), - 0xb6: ('start application 1', False), - 0xb7: ('start application 2', False), - 0xbb: ('+', False), - 0xbc: (',', False), - 0xbd: ('-', False), - 0xbe: ('.', False), - #0xbe:('/', False), # Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '/?. - 0xe5: ('ime process', False), - 0xf6: ('attn', False), - 0xf7: ('crsel', False), - 0xf8: ('exsel', False), - 0xf9: ('erase eof', False), - 0xfa: ('play', False), - 0xfb: ('zoom', False), - 0xfc: ('reserved ', False), - 0xfd: ('pa1', False), - 0xfe: ('clear', False), -} - -tables_lock = Lock() -to_name = defaultdict(list) -from_name = defaultdict(list) -scan_code_to_vk = {} - -distinct_modifiers = [ - (), - ('shift',), - ('alt gr',), - ('num lock',), - ('shift', 'num lock'), - ('caps lock',), - ('shift', 'caps lock'), - ('alt gr', 'num lock'), -] - -name_buffer = ctypes.create_unicode_buffer(32) -unicode_buffer = ctypes.create_unicode_buffer(32) -keyboard_state = keyboard_state_type() -def get_event_names(scan_code, vk, is_extended, modifiers): - is_keypad = (scan_code, vk, is_extended) in keypad_keys - is_official = vk in official_virtual_keys - if is_keypad and is_official: - yield official_virtual_keys[vk][0] - - keyboard_state[0x10] = 0x80 * ('shift' in modifiers) - keyboard_state[0x11] = 0x80 * ('alt gr' in modifiers) - keyboard_state[0x12] = 0x80 * ('alt gr' in modifiers) - keyboard_state[0x14] = 0x01 * ('caps lock' in modifiers) - keyboard_state[0x90] = 0x01 * ('num lock' in modifiers) - keyboard_state[0x91] = 0x01 * ('scroll lock' in modifiers) - unicode_ret = ToUnicode(vk, scan_code, keyboard_state, unicode_buffer, len(unicode_buffer), 0) - if unicode_ret and unicode_buffer.value: - yield unicode_buffer.value - # unicode_ret == -1 -> is dead key - # ToUnicode has the side effect of setting global flags for dead keys. - # Therefore we need to call it twice to clear those flags. - # If your 6 and 7 keys are named "^6" and "^7", this is the reason. - ToUnicode(vk, scan_code, keyboard_state, unicode_buffer, len(unicode_buffer), 0) - - name_ret = GetKeyNameText(scan_code << 16 | is_extended << 24, name_buffer, 1024) - if name_ret and name_buffer.value: - yield name_buffer.value - - char = user32.MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) & 0xFF - if char != 0: - yield chr(char) - - if not is_keypad and is_official: - yield official_virtual_keys[vk][0] - -def _setup_name_tables(): - """ - Ensures the scan code/virtual key code/name translation tables are - filled. - """ - with tables_lock: - if to_name: return - - # Go through every possible scan code, and map them to virtual key codes. - # Then vice-versa. - all_scan_codes = [(sc, user32.MapVirtualKeyExW(sc, MAPVK_VSC_TO_VK_EX, 0)) for sc in range(0x100)] - all_vks = [(user32.MapVirtualKeyExW(vk, MAPVK_VK_TO_VSC_EX, 0), vk) for vk in range(0x100)] - for scan_code, vk in all_scan_codes + all_vks: - # `to_name` and `from_name` entries will be a tuple (scan_code, vk, extended, shift_state). - if (scan_code, vk, 0, 0, 0) in to_name: - continue - - if scan_code not in scan_code_to_vk: - scan_code_to_vk[scan_code] = vk - - # Brute force all combinations to find all possible names. - for extended in [0, 1]: - for modifiers in distinct_modifiers: - entry = (scan_code, vk, extended, modifiers) - # Get key names from ToUnicode, GetKeyNameText, MapVirtualKeyW and official virtual keys. - names = list(get_event_names(*entry)) - if names: - # Also map lowercased key names, but only after the properly cased ones. - lowercase_names = [name.lower() for name in names] - to_name[entry] = names + lowercase_names - # Remember the "id" of the name, as the first techniques - # have better results and therefore priority. - for i, name in enumerate(map(normalize_name, names + lowercase_names)): - from_name[name].append((i, entry)) - - # TODO: single quotes on US INTL is returning the dead key (?), and therefore - # not typing properly. - - # Alt gr is way outside the usual range of keys (0..127) and on my - # computer is named as 'ctrl'. Therefore we add it manually and hope - # Windows is consistent in its inconsistency. - for extended in [0, 1]: - for modifiers in distinct_modifiers: - to_name[(541, 162, extended, modifiers)] = ['alt gr'] - from_name['alt gr'].append((1, (541, 162, extended, modifiers))) - - modifiers_preference = defaultdict(lambda: 10) - modifiers_preference.update({(): 0, ('shift',): 1, ('alt gr',): 2, ('ctrl',): 3, ('alt',): 4}) - def order_key(line): - i, entry = line - scan_code, vk, extended, modifiers = entry - return modifiers_preference[modifiers], i, extended, vk, scan_code - for name, entries in list(from_name.items()): - from_name[name] = sorted(set(entries), key=order_key) - -# Called by keyboard/__init__.py -init = _setup_name_tables - -# List created manually. -keypad_keys = [ - # (scan_code, virtual_key_code, is_extended) - (126, 194, 0), - (126, 194, 0), - (28, 13, 1), - (28, 13, 1), - (53, 111, 1), - (53, 111, 1), - (55, 106, 0), - (55, 106, 0), - (69, 144, 1), - (69, 144, 1), - (71, 103, 0), - (71, 36, 0), - (72, 104, 0), - (72, 38, 0), - (73, 105, 0), - (73, 33, 0), - (74, 109, 0), - (74, 109, 0), - (75, 100, 0), - (75, 37, 0), - (76, 101, 0), - (76, 12, 0), - (77, 102, 0), - (77, 39, 0), - (78, 107, 0), - (78, 107, 0), - (79, 35, 0), - (79, 97, 0), - (80, 40, 0), - (80, 98, 0), - (81, 34, 0), - (81, 99, 0), - (82, 45, 0), - (82, 96, 0), - (83, 110, 0), - (83, 46, 0), -] - -shift_is_pressed = False -altgr_is_pressed = False -ignore_next_right_alt = False -shift_vks = set([0x10, 0xa0, 0xa1]) -def prepare_intercept(callback): - """ - Registers a Windows low level keyboard hook. The provided callback will - be invoked for each high-level keyboard event, and is expected to return - True if the key event should be passed to the next program, or False if - the event is to be blocked. - - No event is processed until the Windows messages are pumped (see - start_intercept). - """ - _setup_name_tables() - - def process_key(event_type, vk, scan_code, is_extended): - global shift_is_pressed, altgr_is_pressed, ignore_next_right_alt - #print(event_type, vk, scan_code, is_extended) - - # Pressing alt-gr also generates an extra "right alt" event - if vk == 0xA5 and ignore_next_right_alt: - ignore_next_right_alt = False - return True - - modifiers = ( - ('shift',) * shift_is_pressed + - ('alt gr',) * altgr_is_pressed + - ('num lock',) * (user32.GetKeyState(0x90) & 1) + - ('caps lock',) * (user32.GetKeyState(0x14) & 1) + - ('scroll lock',) * (user32.GetKeyState(0x91) & 1) - ) - entry = (scan_code, vk, is_extended, modifiers) - if entry not in to_name: - to_name[entry] = list(get_event_names(*entry)) - - names = to_name[entry] - name = names[0] if names else None - - # TODO: inaccurate when holding multiple different shifts. - if vk in shift_vks: - shift_is_pressed = event_type == KEY_DOWN - if scan_code == 541 and vk == 162: - ignore_next_right_alt = True - altgr_is_pressed = event_type == KEY_DOWN - - is_keypad = (scan_code, vk, is_extended) in keypad_keys - return callback(KeyboardEvent(event_type=event_type, scan_code=scan_code or -vk, name=name, is_keypad=is_keypad)) - - def low_level_keyboard_handler(nCode, wParam, lParam): - try: - vk = lParam.contents.vk_code - # Ignore the second `alt` DOWN observed in some cases. - fake_alt = (LLKHF_INJECTED | 0x20) - # Ignore events generated by SendInput with Unicode. - if vk != VK_PACKET and lParam.contents.flags & fake_alt != fake_alt: - event_type = keyboard_event_types[wParam] - is_extended = lParam.contents.flags & 1 - scan_code = lParam.contents.scan_code - should_continue = process_key(event_type, vk, scan_code, is_extended) - if not should_continue: - return -1 - except Exception as e: - print('Error in keyboard hook:') - traceback.print_exc() - - return CallNextHookEx(None, nCode, wParam, lParam) - - WH_KEYBOARD_LL = c_int(13) - keyboard_callback = LowLevelKeyboardProc(low_level_keyboard_handler) - handle = GetModuleHandleW(None) - thread_id = DWORD(0) - keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_callback, handle, thread_id) - - # Register to remove the hook when the interpreter exits. Unfortunately a - # try/finally block doesn't seem to work here. - atexit.register(UnhookWindowsHookEx, keyboard_callback) - -def listen(callback): - prepare_intercept(callback) - msg = LPMSG() - while not GetMessage(msg, 0, 0, 0): - TranslateMessage(msg) - DispatchMessage(msg) - -def map_name(name): - _setup_name_tables() - - entries = from_name.get(name) - if not entries: - raise ValueError('Key name {} is not mapped to any known key.'.format(repr(name))) - for i, entry in entries: - scan_code, vk, is_extended, modifiers = entry - yield scan_code or -vk, modifiers - -def _send_event(code, event_type): - if code == 541: - # Alt-gr is made of ctrl+alt. Just sending even 541 doesn't do anything. - user32.keybd_event(0x11, code, event_type, 0) - user32.keybd_event(0x12, code, event_type, 0) - elif code > 0: - vk = scan_code_to_vk.get(code, 0) - user32.keybd_event(vk, code, event_type, 0) - else: - # Negative scan code is a way to indicate we don't have a scan code, - # and the value actually contains the Virtual key code. - user32.keybd_event(-code, 0, event_type, 0) - -def press(code): - _send_event(code, 0) - -def release(code): - _send_event(code, 2) - -def type_unicode(character): - # This code and related structures are based on - # http://stackoverflow.com/a/11910555/252218 - surrogates = bytearray(character.encode('utf-16le')) - presses = [] - releases = [] - for i in range(0, len(surrogates), 2): - higher, lower = surrogates[i:i+2] - structure = KEYBDINPUT(0, (lower << 8) + higher, KEYEVENTF_UNICODE, 0, None) - presses.append(INPUT(INPUT_KEYBOARD, _INPUTunion(ki=structure))) - structure = KEYBDINPUT(0, (lower << 8) + higher, KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, 0, None) - releases.append(INPUT(INPUT_KEYBOARD, _INPUTunion(ki=structure))) - inputs = presses + releases - nInputs = len(inputs) - LPINPUT = INPUT * nInputs - pInputs = LPINPUT(*inputs) - cbSize = c_int(ctypes.sizeof(INPUT)) - SendInput(nInputs, pInputs, cbSize) - -if __name__ == '__main__': - _setup_name_tables() - import pprint - pprint.pprint(to_name) - pprint.pprint(from_name) - #listen(lambda e: print(e.to_json()) or True) diff --git a/Python/venv1/Lib/site-packages/keyboard/_winmouse.py b/Python/venv1/Lib/site-packages/keyboard/_winmouse.py deleted file mode 100644 index ef16dd4..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_winmouse.py +++ /dev/null @@ -1,201 +0,0 @@ -# -*- coding: utf-8 -*- -import ctypes -import time -from ctypes import c_short, c_char, c_uint8, c_int32, c_int, c_uint, c_uint32, c_long, byref, Structure, CFUNCTYPE, POINTER -from ctypes.wintypes import DWORD, BOOL, HHOOK, MSG, LPWSTR, WCHAR, WPARAM, LPARAM -LPMSG = POINTER(MSG) - -import atexit - -from ._mouse_event import ButtonEvent, WheelEvent, MoveEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE, WHEEL, HORIZONTAL, VERTICAL - -#https://github.com/boppreh/mouse/issues/1 -#user32 = ctypes.windll.user32 -user32 = ctypes.WinDLL('user32', use_last_error = True) - -class MSLLHOOKSTRUCT(Structure): - _fields_ = [("x", c_long), - ("y", c_long), - ('data', c_int32), - ('reserved', c_int32), - ("flags", DWORD), - ("time", c_int), - ] - -LowLevelMouseProc = CFUNCTYPE(c_int, WPARAM, LPARAM, POINTER(MSLLHOOKSTRUCT)) - -SetWindowsHookEx = user32.SetWindowsHookExA -#SetWindowsHookEx.argtypes = [c_int, LowLevelMouseProc, c_int, c_int] -SetWindowsHookEx.restype = HHOOK - -CallNextHookEx = user32.CallNextHookEx -#CallNextHookEx.argtypes = [c_int , c_int, c_int, POINTER(MSLLHOOKSTRUCT)] -CallNextHookEx.restype = c_int - -UnhookWindowsHookEx = user32.UnhookWindowsHookEx -UnhookWindowsHookEx.argtypes = [HHOOK] -UnhookWindowsHookEx.restype = BOOL - -GetMessage = user32.GetMessageW -GetMessage.argtypes = [LPMSG, c_int, c_int, c_int] -GetMessage.restype = BOOL - -TranslateMessage = user32.TranslateMessage -TranslateMessage.argtypes = [LPMSG] -TranslateMessage.restype = BOOL - -DispatchMessage = user32.DispatchMessageA -DispatchMessage.argtypes = [LPMSG] - -# Beware, as of 2016-01-30 the official docs have a very incomplete list. -# This one was compiled from experience and may be incomplete. -WM_MOUSEMOVE = 0x200 -WM_LBUTTONDOWN = 0x201 -WM_LBUTTONUP = 0x202 -WM_LBUTTONDBLCLK = 0x203 -WM_RBUTTONDOWN = 0x204 -WM_RBUTTONUP = 0x205 -WM_RBUTTONDBLCLK = 0x206 -WM_MBUTTONDOWN = 0x207 -WM_MBUTTONUP = 0x208 -WM_MBUTTONDBLCLK = 0x209 -WM_MOUSEWHEEL = 0x20A -WM_XBUTTONDOWN = 0x20B -WM_XBUTTONUP = 0x20C -WM_XBUTTONDBLCLK = 0x20D -WM_NCXBUTTONDOWN = 0x00AB -WM_NCXBUTTONUP = 0x00AC -WM_NCXBUTTONDBLCLK = 0x00AD -WM_MOUSEHWHEEL = 0x20E -WM_LBUTTONDOWN = 0x0201 -WM_LBUTTONUP = 0x0202 -WM_MOUSEMOVE = 0x0200 -WM_MOUSEWHEEL = 0x020A -WM_MOUSEHWHEEL = 0x020E -WM_RBUTTONDOWN = 0x0204 -WM_RBUTTONUP = 0x0205 - -buttons_by_wm_code = { - WM_LBUTTONDOWN: (DOWN, LEFT), - WM_LBUTTONUP: (UP, LEFT), - WM_LBUTTONDBLCLK: (DOUBLE, LEFT), - - WM_RBUTTONDOWN: (DOWN, RIGHT), - WM_RBUTTONUP: (UP, RIGHT), - WM_RBUTTONDBLCLK: (DOUBLE, RIGHT), - - WM_MBUTTONDOWN: (DOWN, MIDDLE), - WM_MBUTTONUP: (UP, MIDDLE), - WM_MBUTTONDBLCLK: (DOUBLE, MIDDLE), - - WM_XBUTTONDOWN: (DOWN, X), - WM_XBUTTONUP: (UP, X), - WM_XBUTTONDBLCLK: (DOUBLE, X), -} - -MOUSEEVENTF_ABSOLUTE = 0x8000 -MOUSEEVENTF_MOVE = 0x1 -MOUSEEVENTF_WHEEL = 0x800 -MOUSEEVENTF_HWHEEL = 0x1000 -MOUSEEVENTF_LEFTDOWN = 0x2 -MOUSEEVENTF_LEFTUP = 0x4 -MOUSEEVENTF_RIGHTDOWN = 0x8 -MOUSEEVENTF_RIGHTUP = 0x10 -MOUSEEVENTF_MIDDLEDOWN = 0x20 -MOUSEEVENTF_MIDDLEUP = 0x40 -MOUSEEVENTF_XDOWN = 0x0080 -MOUSEEVENTF_XUP = 0x0100 - -simulated_mouse_codes = { - (WHEEL, HORIZONTAL): MOUSEEVENTF_HWHEEL, - (WHEEL, VERTICAL): MOUSEEVENTF_WHEEL, - - (DOWN, LEFT): MOUSEEVENTF_LEFTDOWN, - (UP, LEFT): MOUSEEVENTF_LEFTUP, - - (DOWN, RIGHT): MOUSEEVENTF_RIGHTDOWN, - (UP, RIGHT): MOUSEEVENTF_RIGHTUP, - - (DOWN, MIDDLE): MOUSEEVENTF_MIDDLEDOWN, - (UP, MIDDLE): MOUSEEVENTF_MIDDLEUP, - - (DOWN, X): MOUSEEVENTF_XDOWN, - (UP, X): MOUSEEVENTF_XUP, -} - -NULL = c_int(0) - -WHEEL_DELTA = 120 - -init = lambda: None - -def listen(queue): - def low_level_mouse_handler(nCode, wParam, lParam): - struct = lParam.contents - # Can't use struct.time because it's usually zero. - t = time.time() - - if wParam == WM_MOUSEMOVE: - event = MoveEvent(struct.x, struct.y, t) - elif wParam == WM_MOUSEWHEEL: - event = WheelEvent(struct.data / (WHEEL_DELTA * (2<<15)), t) - elif wParam in buttons_by_wm_code: - type, button = buttons_by_wm_code.get(wParam, ('?', '?')) - if wParam >= WM_XBUTTONDOWN: - button = {0x10000: X, 0x20000: X2}[struct.data] - event = ButtonEvent(type, button, t) - - queue.put(event) - return CallNextHookEx(NULL, nCode, wParam, lParam) - - WH_MOUSE_LL = c_int(14) - mouse_callback = LowLevelMouseProc(low_level_mouse_handler) - mouse_hook = SetWindowsHookEx(WH_MOUSE_LL, mouse_callback, NULL, NULL) - - # Register to remove the hook when the interpreter exits. Unfortunately a - # try/finally block doesn't seem to work here. - atexit.register(UnhookWindowsHookEx, mouse_hook) - - msg = LPMSG() - while not GetMessage(msg, NULL, NULL, NULL): - TranslateMessage(msg) - DispatchMessage(msg) - -def _translate_button(button): - if button == X or button == X2: - return X, {X: 0x10000, X2: 0x20000}[button] - else: - return button, 0 - -def press(button=LEFT): - button, data = _translate_button(button) - code = simulated_mouse_codes[(DOWN, button)] - user32.mouse_event(code, 0, 0, data, 0) - -def release(button=LEFT): - button, data = _translate_button(button) - code = simulated_mouse_codes[(UP, button)] - user32.mouse_event(code, 0, 0, data, 0) - -def wheel(delta=1): - code = simulated_mouse_codes[(WHEEL, VERTICAL)] - user32.mouse_event(code, 0, 0, int(delta * WHEEL_DELTA), 0) - -def move_to(x, y): - user32.SetCursorPos(int(x), int(y)) - -def move_relative(x, y): - user32.mouse_event(MOUSEEVENTF_MOVE, int(x), int(y), 0, 0) - -class POINT(Structure): - _fields_ = [("x", c_long), ("y", c_long)] - -def get_position(): - point = POINT() - user32.GetCursorPos(byref(point)) - return (point.x, point.y) - -if __name__ == '__main__': - def p(e): - print(e) - listen(p) diff --git a/Python/venv1/Lib/site-packages/keyboard/_xlibkeyboard.py b/Python/venv1/Lib/site-packages/keyboard/_xlibkeyboard.py deleted file mode 100644 index 3db9187..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/_xlibkeyboard.py +++ /dev/null @@ -1,119 +0,0 @@ -from collections import defaultdict - -from Xlib import X, XK, display -from Xlib.ext import record -from Xlib.protocol import rq - -from ._keyboard_event import KeyboardEvent, KEY_DOWN, KEY_UP, normalize_name - - -# from ._nixkeyboard import init - -def cleanup_key(name): - if name.startswith('XK_'): - name = name[3:] - - if name.startswith('KP_'): - is_keypad = True - name = name[3:] - else: - is_keypad = False - - if name.endswith('_R'): - name = 'right ' + name[:-2] - if name.endswith('_L'): - name = 'left ' + name[:-2] - - return normalize_name(name), is_keypad - - -keysym_to_keys = defaultdict(list) -name_to_keysyms = defaultdict(list) -for raw_name in dir(XK): - if not raw_name.startswith('XK_'): continue - keysym = getattr(XK, raw_name) - name, is_keypad = cleanup_key(raw_name) - keysym_to_keys[keysym].append((name, is_keypad)) - name_to_keysyms[name].append(keysym) - -local_dpy = None -record_dpy = None -ctx = None - - -def init(): - # Adapted from https://github.com/python-xlib/python-xlib/blob/master/examples/record_demo.py - global local_dpy - global record_dpy - local_dpy = display.Display() - record_dpy = display.Display() - - if not record_dpy.has_extension("RECORD"): - raise ImportError("RECORD extension not found") - - 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 - global ctx - 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.KeyPress, X.KeyPress), - 'errors': (0, 0), - 'client_started': False, - 'client_died': False, - } - ] - ) - - -def listen(callback): - def handler(reply): - if reply.category != record.FromServer: - return - if reply.client_swapped: - print("* received swapped protocol data, cowardly ignored") - return - if not len(reply.data) or reply.data[0] < 2: - # not an event - return - - data = reply.data - while len(data): - raw_event, data = rq.EventField(None).parse_binary_value(data, record_dpy.display, None, None) - - event_type = {X.KeyPress: KEY_DOWN, X.KeyRelease: KEY_UP}.get(raw_event.type) - if event_type: - keysym = local_dpy.keycode_to_keysym(raw_event.detail, 0) - # TODO: scan code is not correct. - if not keysym: - event = KeyboardEvent(event_type=event_type, scan_code=raw_event.detail) - else: - try: - name, is_keypad = keysym_to_keys[keysym][0] - except IndexError: - name, is_keypad = None, None - event = KeyboardEvent(event_type=event_type, scan_code=keysym, name=name, is_keypad=is_keypad) - - callback(event) - - try: - # 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, handler) - finally: - # Finally free the context - record_dpy.record_free_context(ctx) - - -def map_name(name): - for keysym in name_to_keysyms[name]: - yield keysym, () diff --git a/Python/venv1/Lib/site-packages/keyboard/mouse.py b/Python/venv1/Lib/site-packages/keyboard/mouse.py deleted file mode 100644 index 315199e..0000000 --- a/Python/venv1/Lib/site-packages/keyboard/mouse.py +++ /dev/null @@ -1,232 +0,0 @@ -# -*- coding: utf-8 -*- -import warnings -warnings.simplefilter('always', DeprecationWarning) -warnings.warn('The mouse sub-library is deprecated and will be removed in future versions. Please use the standalone package `mouse`.', DeprecationWarning, stacklevel=2) - -import time as _time - -import platform as _platform -if _platform.system() == 'Windows': - from. import _winmouse as _os_mouse -elif _platform.system() == 'Linux': - from. import _nixmouse as _os_mouse -elif _platform.system() == 'Darwin': - from. import _darwinmouse as _os_mouse -else: - raise OSError("Unsupported platform '{}'".format(_platform.system())) - -from ._mouse_event import ButtonEvent, MoveEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE -from ._generic import GenericListener as _GenericListener - -_pressed_events = set() -class _MouseListener(_GenericListener): - def init(self): - _os_mouse.init() - def pre_process_event(self, event): - if isinstance(event, ButtonEvent): - if event.event_type in (UP, DOUBLE): - _pressed_events.discard(event.button) - else: - _pressed_events.add(event.button) - return True - - def listen(self): - _os_mouse.listen(self.queue) - -_listener = _MouseListener() - -def is_pressed(button=LEFT): - """ Returns True if the given button is currently pressed. """ - _listener.start_if_necessary() - return button in _pressed_events - -def press(button=LEFT): - """ Presses the given button (but doesn't release). """ - _os_mouse.press(button) - -def release(button=LEFT): - """ Releases the given button. """ - _os_mouse.release(button) - -def click(button=LEFT): - """ Sends a click with the given button. """ - _os_mouse.press(button) - _os_mouse.release(button) - -def double_click(button=LEFT): - """ Sends a double click with the given button. """ - click(button) - click(button) - -def right_click(): - """ Sends a right click with the given button. """ - click(RIGHT) - -def wheel(delta=1): - """ Scrolls the wheel `delta` clicks. Sign indicates direction. """ - _os_mouse.wheel(delta) - -def move(x, y, absolute=True, duration=0): - """ - Moves the mouse. If `absolute`, to position (x, y), otherwise move relative - to the current position. If `duration` is non-zero, animates the movement. - """ - x = int(x) - y = int(y) - - # Requires an extra system call on Linux, but `move_relative` is measured - # in millimiters so we would lose precision. - position_x, position_y = get_position() - - if not absolute: - x = position_x + x - y = position_y + y - - if duration: - start_x = position_x - start_y = position_y - dx = x - start_x - dy = y - start_y - - if dx == 0 and dy == 0: - _time.sleep(duration) - else: - # 120 movements per second. - # Round and keep float to ensure float division in Python 2 - steps = max(1.0, float(int(duration * 120.0))) - for i in range(int(steps)+1): - move(start_x + dx*i/steps, start_y + dy*i/steps) - _time.sleep(duration/steps) - else: - _os_mouse.move_to(x, y) - -def drag(start_x, start_y, end_x, end_y, absolute=True, duration=0): - """ - Holds the left mouse button, moving from start to end position, then - releases. `absolute` and `duration` are parameters regarding the mouse - movement. - """ - if is_pressed(): - release() - move(start_x, start_y, absolute, 0) - press() - move(end_x, end_y, absolute, duration) - release() - -def on_button(callback, args=(), buttons=(LEFT, MIDDLE, RIGHT, X, X2), types=(UP, DOWN, DOUBLE)): - """ Invokes `callback` with `args` when the specified event happens. """ - if not isinstance(buttons, (tuple, list)): - buttons = (buttons,) - if not isinstance(types, (tuple, list)): - types = (types,) - - def handler(event): - if isinstance(event, ButtonEvent): - if event.event_type in types and event.button in buttons: - callback(*args) - _listener.add_handler(handler) - return handler - -def on_click(callback, args=()): - """ Invokes `callback` with `args` when the left button is clicked. """ - return on_button(callback, args, [LEFT], [UP]) - -def on_double_click(callback, args=()): - """ - Invokes `callback` with `args` when the left button is double clicked. - """ - return on_button(callback, args, [LEFT], [DOUBLE]) - -def on_right_click(callback, args=()): - """ Invokes `callback` with `args` when the right button is clicked. """ - return on_button(callback, args, [RIGHT], [UP]) - -def on_middle_click(callback, args=()): - """ Invokes `callback` with `args` when the middle button is clicked. """ - return on_button(callback, args, [MIDDLE], [UP]) - -def wait(button=LEFT, target_types=(UP, DOWN, DOUBLE)): - """ - Blocks program execution until the given button performs an event. - """ - from threading import Lock - lock = Lock() - lock.acquire() - handler = on_button(lock.release, (), [button], target_types) - lock.acquire() - _listener.remove_handler(handler) - -def get_position(): - """ Returns the (x, y) mouse position. """ - return _os_mouse.get_position() - -def hook(callback): - """ - Installs a global listener on all available mouses, invoking `callback` - each time it is moved, a key status changes or the wheel is spun. A mouse - event is passed as argument, with type either `mouse.ButtonEvent`, - `mouse.WheelEvent` or `mouse.MoveEvent`. - - Returns the given callback for easier development. - """ - _listener.add_handler(callback) - return callback - -def unhook(callback): - """ - Removes a previously installed hook. - """ - _listener.remove_handler(callback) - -def unhook_all(): - """ - Removes all hooks registered by this application. Note this may include - hooks installed by high level functions, such as `record`. - """ - del _listener.handlers[:] - -def record(button=RIGHT, target_types=(DOWN,)): - """ - Records all mouse events until the user presses the given button. - Then returns the list of events recorded. Pairs well with `play(events)`. - - Note: this is a blocking function. - Note: for more details on the mouse hook and events see `hook`. - """ - recorded = [] - hook(recorded.append) - wait(button=button, target_types=target_types) - unhook(recorded.append) - return recorded - -def play(events, speed_factor=1.0, include_clicks=True, include_moves=True, include_wheel=True): - """ - Plays a sequence of recorded events, maintaining the relative time - intervals. If speed_factor is <= 0 then the actions are replayed as fast - as the OS allows. Pairs well with `record()`. - - The parameters `include_*` define if events of that type should be inluded - in the replay or ignored. - """ - last_time = None - for event in events: - if speed_factor > 0 and last_time is not None: - _time.sleep((event.time - last_time) / speed_factor) - last_time = event.time - - if isinstance(event, ButtonEvent) and include_clicks: - if event.event_type == UP: - _os_mouse.release(event.button) - else: - _os_mouse.press(event.button) - elif isinstance(event, MoveEvent) and include_moves: - _os_mouse.move_to(event.x, event.y) - elif isinstance(event, WheelEvent) and include_wheel: - _os_mouse.wheel(event.delta) - -replay = play -hold = press - -if __name__ == '__main__': - print('Recording... Double click to stop and replay.') - play(record()) |
