evdev 1.7.1__tar.gz → 1.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {evdev-1.7.1 → evdev-1.8.0}/LICENSE +1 -1
- {evdev-1.7.1 → evdev-1.8.0}/MANIFEST.in +1 -0
- {evdev-1.7.1/evdev.egg-info → evdev-1.8.0}/PKG-INFO +5 -4
- {evdev-1.7.1 → evdev-1.8.0}/README.md +1 -0
- evdev-1.8.0/evdev/__init__.py +9 -0
- {evdev-1.7.1 → evdev-1.8.0}/evdev/device.py +10 -11
- evdev-1.8.0/evdev/ecodes.py +5 -0
- evdev-1.7.1/evdev/ecodes.py → evdev-1.8.0/evdev/ecodes_runtime.py +15 -5
- {evdev-1.7.1 → evdev-1.8.0}/evdev/eventio.py +15 -4
- {evdev-1.7.1 → evdev-1.8.0}/evdev/eventio_async.py +2 -2
- {evdev-1.7.1 → evdev-1.8.0}/evdev/events.py +14 -13
- {evdev-1.7.1 → evdev-1.8.0}/evdev/evtest.py +4 -10
- {evdev-1.7.1 → evdev-1.8.0}/evdev/ff.py +1 -1
- evdev-1.8.0/evdev/genecodes_c.py +138 -0
- evdev-1.8.0/evdev/genecodes_py.py +53 -0
- {evdev-1.7.1 → evdev-1.8.0}/evdev/uinput.py +6 -19
- {evdev-1.7.1 → evdev-1.8.0}/evdev/util.py +5 -5
- {evdev-1.7.1 → evdev-1.8.0/evdev.egg-info}/PKG-INFO +5 -4
- {evdev-1.7.1 → evdev-1.8.0}/evdev.egg-info/SOURCES.txt +3 -1
- {evdev-1.7.1 → evdev-1.8.0}/pyproject.toml +12 -3
- {evdev-1.7.1 → evdev-1.8.0}/setup.py +25 -8
- {evdev-1.7.1 → evdev-1.8.0}/tests/test_uinput.py +27 -6
- evdev-1.7.1/evdev/__init__.py +0 -10
- evdev-1.7.1/evdev/genecodes.py +0 -96
- {evdev-1.7.1 → evdev-1.8.0}/evdev/input.c +0 -0
- {evdev-1.7.1 → evdev-1.8.0}/evdev/uinput.c +0 -0
- {evdev-1.7.1 → evdev-1.8.0}/evdev.egg-info/dependency_links.txt +0 -0
- {evdev-1.7.1 → evdev-1.8.0}/evdev.egg-info/top_level.txt +0 -0
- {evdev-1.7.1 → evdev-1.8.0}/setup.cfg +0 -0
- {evdev-1.7.1 → evdev-1.8.0}/tests/test_ecodes.py +0 -0
- {evdev-1.7.1 → evdev-1.8.0}/tests/test_events.py +0 -0
- {evdev-1.7.1 → evdev-1.8.0}/tests/test_util.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: evdev
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: Bindings to the Linux input handling subsystem
|
|
5
5
|
Author-email: Georgi Valkov <georgi.t.valkov@gmail.com>
|
|
6
6
|
Maintainer-email: Tobi <proxima@sezanzeb.de>
|
|
7
|
-
License: Copyright (c) 2012-
|
|
7
|
+
License: Copyright (c) 2012-2025 Georgi Valkov. All rights reserved.
|
|
8
8
|
|
|
9
9
|
Redistribution and use in source and binary forms, with or without
|
|
10
10
|
modification, are permitted provided that the following conditions are
|
|
@@ -43,7 +43,7 @@ Classifier: Intended Audience :: Developers
|
|
|
43
43
|
Classifier: Topic :: Software Development :: Libraries
|
|
44
44
|
Classifier: License :: OSI Approved :: BSD License
|
|
45
45
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
46
|
-
Requires-Python: >=3.
|
|
46
|
+
Requires-Python: >=3.8
|
|
47
47
|
Description-Content-Type: text/markdown
|
|
48
48
|
License-File: LICENSE
|
|
49
49
|
|
|
@@ -52,6 +52,7 @@ License-File: LICENSE
|
|
|
52
52
|
<p>
|
|
53
53
|
<a href="https://pypi.python.org/pypi/evdev"><img alt="pypi version" src="https://img.shields.io/pypi/v/evdev.svg"></a>
|
|
54
54
|
<a href="https://github.com/gvalkov/python-evdev/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/pypi/l/evdev"></a>
|
|
55
|
+
<a href="https://repology.org/project/python:evdev/versions"><img alt="Packaging status" src="https://repology.org/badge/tiny-repos/python:evdev.svg"></a>
|
|
55
56
|
</p>
|
|
56
57
|
|
|
57
58
|
This package provides bindings to the generic input event interface in Linux.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<p>
|
|
4
4
|
<a href="https://pypi.python.org/pypi/evdev"><img alt="pypi version" src="https://img.shields.io/pypi/v/evdev.svg"></a>
|
|
5
5
|
<a href="https://github.com/gvalkov/python-evdev/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/pypi/l/evdev"></a>
|
|
6
|
+
<a href="https://repology.org/project/python:evdev/versions"><img alt="Packaging status" src="https://repology.org/badge/tiny-repos/python:evdev.svg"></a>
|
|
6
7
|
</p>
|
|
7
8
|
|
|
8
9
|
This package provides bindings to the generic input event interface in Linux.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# --------------------------------------------------------------------------
|
|
2
|
+
# Gather everything into a single, convenient namespace.
|
|
3
|
+
# --------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
from . import ecodes, ff
|
|
6
|
+
from .device import AbsInfo, DeviceInfo, EvdevError, InputDevice
|
|
7
|
+
from .events import AbsEvent, InputEvent, KeyEvent, RelEvent, SynEvent, event_factory
|
|
8
|
+
from .uinput import UInput, UInputError
|
|
9
|
+
from .util import categorize, list_devices, resolve_ecodes, resolve_ecodes_dict
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
|
+
import collections
|
|
4
|
+
import contextlib
|
|
3
5
|
import os
|
|
4
6
|
import warnings
|
|
5
|
-
import contextlib
|
|
6
|
-
import collections
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from evdev.events import InputEvent
|
|
8
|
+
from . import _input, ecodes, util
|
|
10
9
|
|
|
11
10
|
try:
|
|
12
|
-
from
|
|
11
|
+
from .eventio_async import EvdevError, EventIO
|
|
13
12
|
except ImportError:
|
|
14
|
-
from
|
|
13
|
+
from .eventio import EvdevError, EventIO
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
# --------------------------------------------------------------------------
|
|
18
17
|
_AbsInfo = collections.namedtuple("AbsInfo", ["value", "min", "max", "fuzz", "flat", "resolution"])
|
|
19
18
|
|
|
20
|
-
_KbdInfo = collections.namedtuple("KbdInfo", ["
|
|
19
|
+
_KbdInfo = collections.namedtuple("KbdInfo", ["delay", "repeat"])
|
|
21
20
|
|
|
22
21
|
_DeviceInfo = collections.namedtuple("DeviceInfo", ["bustype", "vendor", "product", "version"])
|
|
23
22
|
|
|
@@ -70,16 +69,16 @@ class KbdInfo(_KbdInfo):
|
|
|
70
69
|
|
|
71
70
|
Attributes
|
|
72
71
|
----------
|
|
73
|
-
repeat
|
|
74
|
-
Keyboard repeat rate in characters per second.
|
|
75
|
-
|
|
76
72
|
delay
|
|
77
73
|
Amount of time that a key must be depressed before it will start
|
|
78
74
|
to repeat (in milliseconds).
|
|
75
|
+
|
|
76
|
+
repeat
|
|
77
|
+
Keyboard repeat rate in characters per second.
|
|
79
78
|
"""
|
|
80
79
|
|
|
81
80
|
def __str__(self):
|
|
82
|
-
return "
|
|
81
|
+
return "delay {}, repeat {}".format(*self)
|
|
83
82
|
|
|
84
83
|
|
|
85
84
|
class DeviceInfo(_DeviceInfo):
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# pylint: disable=undefined-variable
|
|
1
2
|
"""
|
|
2
3
|
This modules exposes the integer constants defined in ``linux/input.h`` and
|
|
3
4
|
``linux/input-event-codes.h``.
|
|
@@ -32,26 +33,26 @@ Keep in mind that values in reverse mappings may point to one or more event
|
|
|
32
33
|
codes. For example::
|
|
33
34
|
|
|
34
35
|
>>> evdev.ecodes.FF[80]
|
|
35
|
-
|
|
36
|
+
('FF_EFFECT_MIN', 'FF_RUMBLE')
|
|
36
37
|
|
|
37
38
|
>>> evdev.ecodes.FF[81]
|
|
38
39
|
'FF_PERIODIC'
|
|
39
40
|
"""
|
|
40
41
|
|
|
41
42
|
from inspect import getmembers
|
|
42
|
-
from evdev import _ecodes
|
|
43
43
|
|
|
44
|
+
from . import _ecodes
|
|
44
45
|
|
|
45
46
|
#: Mapping of names to values.
|
|
46
47
|
ecodes = {}
|
|
47
48
|
|
|
48
|
-
prefixes = "KEY ABS REL SW MSC LED BTN REP SND ID EV BUS SYN FF_STATUS FF INPUT_PROP"
|
|
49
|
+
prefixes = "KEY ABS REL SW MSC LED BTN REP SND ID EV BUS SYN FF_STATUS FF INPUT_PROP".split()
|
|
49
50
|
prev_prefix = ""
|
|
50
51
|
g = globals()
|
|
51
52
|
|
|
52
53
|
# eg. code: 'REL_Z', val: 2
|
|
53
54
|
for code, val in getmembers(_ecodes):
|
|
54
|
-
for prefix in prefixes
|
|
55
|
+
for prefix in prefixes: # eg. 'REL'
|
|
55
56
|
if code.startswith(prefix):
|
|
56
57
|
ecodes[code] = val
|
|
57
58
|
# FF_STATUS codes should not appear in the FF reverse mapping
|
|
@@ -70,6 +71,15 @@ for code, val in getmembers(_ecodes):
|
|
|
70
71
|
|
|
71
72
|
prev_prefix = prefix
|
|
72
73
|
|
|
74
|
+
|
|
75
|
+
# Convert lists to tuples.
|
|
76
|
+
k, v = None, None
|
|
77
|
+
for prefix in prefixes:
|
|
78
|
+
for k, v in g[prefix].items():
|
|
79
|
+
if isinstance(v, list):
|
|
80
|
+
g[prefix][k] = tuple(v)
|
|
81
|
+
|
|
82
|
+
|
|
73
83
|
#: Keys are a combination of all BTN and KEY codes.
|
|
74
84
|
keys = {}
|
|
75
85
|
keys.update(BTN)
|
|
@@ -98,4 +108,4 @@ bytype = {
|
|
|
98
108
|
from evdev._ecodes import *
|
|
99
109
|
|
|
100
110
|
# cheaper than whitelisting in an __all__
|
|
101
|
-
del code, val, prefix, getmembers, g, d, prefixes, prev_prefix
|
|
111
|
+
del code, val, prefix, getmembers, g, d, k, v, prefixes, prev_prefix
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import fcntl
|
|
3
|
-
import select
|
|
4
2
|
import functools
|
|
3
|
+
import os
|
|
4
|
+
import select
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
6
|
+
from . import _input, _uinput, ecodes
|
|
7
|
+
from .events import InputEvent
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
# --------------------------------------------------------------------------
|
|
@@ -72,6 +72,7 @@ class EventIO:
|
|
|
72
72
|
for event in events:
|
|
73
73
|
yield InputEvent(*event)
|
|
74
74
|
|
|
75
|
+
# pylint: disable=no-self-argument
|
|
75
76
|
def need_write(func):
|
|
76
77
|
"""
|
|
77
78
|
Decorator that raises :class:`EvdevError` if there is no write access to the
|
|
@@ -82,6 +83,7 @@ class EventIO:
|
|
|
82
83
|
def wrapper(*args):
|
|
83
84
|
fd = args[0].fd
|
|
84
85
|
if fcntl.fcntl(fd, fcntl.F_GETFL) & os.O_RDWR:
|
|
86
|
+
# pylint: disable=not-callable
|
|
85
87
|
return func(*args)
|
|
86
88
|
msg = 'no write access to device "%s"' % args[0].path
|
|
87
89
|
raise EvdevError(msg)
|
|
@@ -136,5 +138,14 @@ class EventIO:
|
|
|
136
138
|
|
|
137
139
|
_uinput.write(self.fd, etype, code, value)
|
|
138
140
|
|
|
141
|
+
def syn(self):
|
|
142
|
+
"""
|
|
143
|
+
Inject a ``SYN_REPORT`` event into the input subsystem. Events
|
|
144
|
+
queued by :func:`write()` will be fired. If possible, events
|
|
145
|
+
will be merged into an 'atomic' event.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
self.write(ecodes.EV_SYN, ecodes.SYN_REPORT, 0)
|
|
149
|
+
|
|
139
150
|
def close(self):
|
|
140
151
|
pass
|
|
@@ -37,7 +37,8 @@ methods::
|
|
|
37
37
|
# event type descriptions have been taken mot-a-mot from:
|
|
38
38
|
# http://www.kernel.org/doc/Documentation/input/event-codes.txt
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
# pylint: disable=no-name-in-module
|
|
41
|
+
from .ecodes import ABS, EV_ABS, EV_KEY, EV_REL, EV_SYN, KEY, REL, SYN, keys
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
class InputEvent:
|
|
@@ -65,13 +66,13 @@ class InputEvent:
|
|
|
65
66
|
"""Return event timestamp as a float."""
|
|
66
67
|
return self.sec + (self.usec / 1000000.0)
|
|
67
68
|
|
|
68
|
-
def __str__(
|
|
69
|
+
def __str__(self):
|
|
69
70
|
msg = "event at {:f}, code {:02d}, type {:02d}, val {:02d}"
|
|
70
|
-
return msg.format(
|
|
71
|
+
return msg.format(self.timestamp(), self.code, self.type, self.value)
|
|
71
72
|
|
|
72
|
-
def __repr__(
|
|
73
|
+
def __repr__(self):
|
|
73
74
|
msg = "{}({!r}, {!r}, {!r}, {!r}, {!r})"
|
|
74
|
-
return msg.format(
|
|
75
|
+
return msg.format(self.__class__.__name__, self.sec, self.usec, self.type, self.code, self.value)
|
|
75
76
|
|
|
76
77
|
|
|
77
78
|
class KeyEvent:
|
|
@@ -119,8 +120,8 @@ class KeyEvent:
|
|
|
119
120
|
msg = "key event at {:f}, {} ({}), {}"
|
|
120
121
|
return msg.format(self.event.timestamp(), self.scancode, self.keycode, ks)
|
|
121
122
|
|
|
122
|
-
def __repr__(
|
|
123
|
-
return "{}({!r})".format(
|
|
123
|
+
def __repr__(self):
|
|
124
|
+
return "{}({!r})".format(self.__class__.__name__, self.event)
|
|
124
125
|
|
|
125
126
|
|
|
126
127
|
class RelEvent:
|
|
@@ -136,8 +137,8 @@ class RelEvent:
|
|
|
136
137
|
msg = "relative axis event at {:f}, {}"
|
|
137
138
|
return msg.format(self.event.timestamp(), REL[self.event.code])
|
|
138
139
|
|
|
139
|
-
def __repr__(
|
|
140
|
-
return "{}({!r})".format(
|
|
140
|
+
def __repr__(self):
|
|
141
|
+
return "{}({!r})".format(self.__class__.__name__, self.event)
|
|
141
142
|
|
|
142
143
|
|
|
143
144
|
class AbsEvent:
|
|
@@ -153,8 +154,8 @@ class AbsEvent:
|
|
|
153
154
|
msg = "absolute axis event at {:f}, {}"
|
|
154
155
|
return msg.format(self.event.timestamp(), ABS[self.event.code])
|
|
155
156
|
|
|
156
|
-
def __repr__(
|
|
157
|
-
return "{}({!r})".format(
|
|
157
|
+
def __repr__(self):
|
|
158
|
+
return "{}({!r})".format(self.__class__.__name__, self.event)
|
|
158
159
|
|
|
159
160
|
|
|
160
161
|
class SynEvent:
|
|
@@ -173,8 +174,8 @@ class SynEvent:
|
|
|
173
174
|
msg = "synchronization event at {:f}, {}"
|
|
174
175
|
return msg.format(self.event.timestamp(), SYN[self.event.code])
|
|
175
176
|
|
|
176
|
-
def __repr__(
|
|
177
|
-
return "{}({!r})".format(
|
|
177
|
+
def __repr__(self):
|
|
178
|
+
return "{}({!r})".format(self.__class__.__name__, self.event)
|
|
178
179
|
|
|
179
180
|
|
|
180
181
|
#: A mapping of event types to :class:`InputEvent` sub-classes. Used
|
|
@@ -16,21 +16,15 @@ Examples:
|
|
|
16
16
|
evtest /dev/input/event0 /dev/input/event1
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
from __future__ import print_function
|
|
20
19
|
|
|
20
|
+
import atexit
|
|
21
|
+
import optparse
|
|
21
22
|
import re
|
|
22
|
-
import sys
|
|
23
23
|
import select
|
|
24
|
-
import
|
|
24
|
+
import sys
|
|
25
25
|
import termios
|
|
26
|
-
import optparse
|
|
27
|
-
|
|
28
|
-
try:
|
|
29
|
-
input = raw_input
|
|
30
|
-
except NameError:
|
|
31
|
-
pass
|
|
32
26
|
|
|
33
|
-
from
|
|
27
|
+
from . import AbsInfo, InputDevice, ecodes, list_devices
|
|
34
28
|
|
|
35
29
|
|
|
36
30
|
def parseopt():
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generate a Python extension module with the constants defined in linux/input.h.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import getopt
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
# -----------------------------------------------------------------------------
|
|
11
|
+
# The default header file locations to try.
|
|
12
|
+
headers = [
|
|
13
|
+
"/usr/include/linux/input.h",
|
|
14
|
+
"/usr/include/linux/input-event-codes.h",
|
|
15
|
+
"/usr/include/linux/uinput.h",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
opts, args = getopt.getopt(sys.argv[1:], "", ["ecodes", "stubs"])
|
|
19
|
+
if not opts:
|
|
20
|
+
print("usage: genecodes.py [--ecodes|--stubs] <headers>")
|
|
21
|
+
exit(2)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# -----------------------------------------------------------------------------
|
|
25
|
+
macro_regex = r"#define +((?:KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF|UI_FF|INPUT_PROP)_\w+)"
|
|
26
|
+
macro_regex = re.compile(macro_regex)
|
|
27
|
+
|
|
28
|
+
# Uname without hostname.
|
|
29
|
+
uname = list(os.uname())
|
|
30
|
+
uname = " ".join((uname[0], *uname[2:]))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# -----------------------------------------------------------------------------
|
|
34
|
+
template_ecodes = r"""
|
|
35
|
+
#include <Python.h>
|
|
36
|
+
#ifdef __FreeBSD__
|
|
37
|
+
#include <dev/evdev/input.h>
|
|
38
|
+
#else
|
|
39
|
+
#include <linux/input.h>
|
|
40
|
+
#include <linux/uinput.h>
|
|
41
|
+
#endif
|
|
42
|
+
|
|
43
|
+
/* Automatically generated by evdev.genecodes */
|
|
44
|
+
/* Generated on %s */
|
|
45
|
+
/* Generated from %s */
|
|
46
|
+
|
|
47
|
+
#define MODULE_NAME "_ecodes"
|
|
48
|
+
#define MODULE_HELP "linux/input.h macros"
|
|
49
|
+
|
|
50
|
+
static PyMethodDef MethodTable[] = {
|
|
51
|
+
{ NULL, NULL, 0, NULL}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
static struct PyModuleDef moduledef = {
|
|
55
|
+
PyModuleDef_HEAD_INIT,
|
|
56
|
+
MODULE_NAME,
|
|
57
|
+
MODULE_HELP,
|
|
58
|
+
-1, /* m_size */
|
|
59
|
+
MethodTable, /* m_methods */
|
|
60
|
+
NULL, /* m_reload */
|
|
61
|
+
NULL, /* m_traverse */
|
|
62
|
+
NULL, /* m_clear */
|
|
63
|
+
NULL, /* m_free */
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
PyMODINIT_FUNC
|
|
67
|
+
PyInit__ecodes(void)
|
|
68
|
+
{
|
|
69
|
+
PyObject* m = PyModule_Create(&moduledef);
|
|
70
|
+
if (m == NULL) return NULL;
|
|
71
|
+
|
|
72
|
+
%s
|
|
73
|
+
|
|
74
|
+
return m;
|
|
75
|
+
}
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
template_stubs = r"""
|
|
80
|
+
# Automatically generated by evdev.genecodes
|
|
81
|
+
# Generated on %s
|
|
82
|
+
# Generated from %s
|
|
83
|
+
|
|
84
|
+
# pylint: skip-file
|
|
85
|
+
|
|
86
|
+
ecodes: dict[str, int]
|
|
87
|
+
keys: dict[int, str|list[str]]
|
|
88
|
+
bytype: dict[int, dict[int, str|list[str]]]
|
|
89
|
+
|
|
90
|
+
KEY: dict[int, str|list[str]]
|
|
91
|
+
ABS: dict[int, str|list[str]]
|
|
92
|
+
REL: dict[int, str|list[str]]
|
|
93
|
+
SW: dict[int, str|list[str]]
|
|
94
|
+
MSC: dict[int, str|list[str]]
|
|
95
|
+
LED: dict[int, str|list[str]]
|
|
96
|
+
BTN: dict[int, str|list[str]]
|
|
97
|
+
REP: dict[int, str|list[str]]
|
|
98
|
+
SND: dict[int, str|list[str]]
|
|
99
|
+
ID: dict[int, str|list[str]]
|
|
100
|
+
EV: dict[int, str|list[str]]
|
|
101
|
+
BUS: dict[int, str|list[str]]
|
|
102
|
+
SYN: dict[int, str|list[str]]
|
|
103
|
+
FF_STATUS: dict[int, str|list[str]]
|
|
104
|
+
FF_INPUT_PROP: dict[int, str|list[str]]
|
|
105
|
+
|
|
106
|
+
%s
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def parse_headers(headers=headers):
|
|
111
|
+
for header in headers:
|
|
112
|
+
try:
|
|
113
|
+
fh = open(header)
|
|
114
|
+
except (IOError, OSError):
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
for line in fh:
|
|
118
|
+
macro = macro_regex.search(line)
|
|
119
|
+
if macro:
|
|
120
|
+
yield macro.group(1)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
all_macros = list(parse_headers())
|
|
124
|
+
if not all_macros:
|
|
125
|
+
print("no input macros found in: %s" % " ".join(headers), file=sys.stderr)
|
|
126
|
+
sys.exit(1)
|
|
127
|
+
|
|
128
|
+
# pylint: disable=possibly-used-before-assignment, used-before-assignment
|
|
129
|
+
if ("--ecodes", "") in opts:
|
|
130
|
+
body = (" PyModule_AddIntMacro(m, %s);" % macro for macro in all_macros)
|
|
131
|
+
template = template_ecodes
|
|
132
|
+
elif ("--stubs", "") in opts:
|
|
133
|
+
body = ("%s: int" % macro for macro in all_macros)
|
|
134
|
+
template = template_stubs
|
|
135
|
+
|
|
136
|
+
body = os.linesep.join(body)
|
|
137
|
+
text = template % (uname, headers, body)
|
|
138
|
+
print(text.strip())
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from unittest import mock
|
|
3
|
+
from pprint import PrettyPrinter
|
|
4
|
+
|
|
5
|
+
sys.modules["evdev.ecodes"] = mock.Mock()
|
|
6
|
+
from evdev import ecodes_runtime as ecodes
|
|
7
|
+
|
|
8
|
+
pprint = PrettyPrinter(indent=2, sort_dicts=True, width=120).pprint
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
print("# Automatically generated by evdev.genecodes_py")
|
|
12
|
+
print()
|
|
13
|
+
print('"""')
|
|
14
|
+
print(ecodes.__doc__.strip())
|
|
15
|
+
print('"""')
|
|
16
|
+
|
|
17
|
+
print()
|
|
18
|
+
print("from typing import Final, Dict, Tuple, Union")
|
|
19
|
+
print()
|
|
20
|
+
|
|
21
|
+
for name, value in ecodes.ecodes.items():
|
|
22
|
+
print(f"{name}: Final[int] = {value}")
|
|
23
|
+
print()
|
|
24
|
+
|
|
25
|
+
entries = [
|
|
26
|
+
("ecodes", "Dict[str, int]", "#: Mapping of names to values."),
|
|
27
|
+
("bytype", "Dict[int, Dict[int, Union[str, Tuple[str]]]]", "#: Mapping of event types to other value/name mappings."),
|
|
28
|
+
("keys", "Dict[int, Union[str, Tuple[str]]]", "#: Keys are a combination of all BTN and KEY codes."),
|
|
29
|
+
("KEY", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
30
|
+
("ABS", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
31
|
+
("REL", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
32
|
+
("SW", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
33
|
+
("MSC", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
34
|
+
("LED", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
35
|
+
("BTN", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
36
|
+
("REP", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
37
|
+
("SND", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
38
|
+
("ID", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
39
|
+
("EV", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
40
|
+
("BUS", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
41
|
+
("SYN", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
42
|
+
("FF", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
43
|
+
("FF_STATUS", "Dict[int, Union[str, Tuple[str]]]", None),
|
|
44
|
+
("INPUT_PROP", "Dict[int, Union[str, Tuple[str]]]", None)
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
for key, annotation, doc in entries:
|
|
48
|
+
if doc:
|
|
49
|
+
print(doc)
|
|
50
|
+
|
|
51
|
+
print(f"{key}: {annotation} = ", end="")
|
|
52
|
+
pprint(getattr(ecodes, key))
|
|
53
|
+
print()
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ctypes
|
|
1
2
|
import os
|
|
2
3
|
import platform
|
|
3
4
|
import re
|
|
@@ -5,11 +6,8 @@ import stat
|
|
|
5
6
|
import time
|
|
6
7
|
from collections import defaultdict
|
|
7
8
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from evdev.events import InputEvent
|
|
11
|
-
import evdev.ff as ff
|
|
12
|
-
import ctypes
|
|
9
|
+
from . import _uinput, device, ecodes, ff, util
|
|
10
|
+
from .events import InputEvent
|
|
13
11
|
|
|
14
12
|
try:
|
|
15
13
|
from evdev.eventio_async import EventIO
|
|
@@ -227,15 +225,6 @@ class UInput(EventIO):
|
|
|
227
225
|
_uinput.close(self.fd)
|
|
228
226
|
self.fd = -1
|
|
229
227
|
|
|
230
|
-
def syn(self):
|
|
231
|
-
"""
|
|
232
|
-
Inject a ``SYN_REPORT`` event into the input subsystem. Events
|
|
233
|
-
queued by :func:`write()` will be fired. If possible, events
|
|
234
|
-
will be merged into an 'atomic' event.
|
|
235
|
-
"""
|
|
236
|
-
|
|
237
|
-
_uinput.write(self.fd, ecodes.EV_SYN, ecodes.SYN_REPORT, 0)
|
|
238
|
-
|
|
239
228
|
def capabilities(self, verbose=False, absinfo=True):
|
|
240
229
|
"""See :func:`capabilities <evdev.device.InputDevice.capabilities>`."""
|
|
241
230
|
if self.device is None:
|
|
@@ -277,13 +266,11 @@ class UInput(EventIO):
|
|
|
277
266
|
Verify that an uinput device exists and is readable and writable
|
|
278
267
|
by the current process.
|
|
279
268
|
"""
|
|
280
|
-
|
|
281
269
|
try:
|
|
282
270
|
m = os.stat(self.devnode)[stat.ST_MODE]
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
msg = '"{}" does not exist or is not a character device file ' "- verify that the uinput module is loaded"
|
|
271
|
+
assert stat.S_ISCHR(m)
|
|
272
|
+
except (IndexError, OSError, AssertionError):
|
|
273
|
+
msg = '"{}" does not exist or is not a character device file - verify that the uinput module is loaded'
|
|
287
274
|
raise UInputError(msg.format(self.devnode))
|
|
288
275
|
|
|
289
276
|
if not os.access(self.devnode, os.W_OK):
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import collections
|
|
2
|
+
import glob
|
|
2
3
|
import os
|
|
4
|
+
import re
|
|
3
5
|
import stat
|
|
4
|
-
import glob
|
|
5
|
-
import collections
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
from
|
|
7
|
+
from . import ecodes
|
|
8
|
+
from .events import event_factory
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def list_devices(input_device_dir="/dev/input"):
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: evdev
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: Bindings to the Linux input handling subsystem
|
|
5
5
|
Author-email: Georgi Valkov <georgi.t.valkov@gmail.com>
|
|
6
6
|
Maintainer-email: Tobi <proxima@sezanzeb.de>
|
|
7
|
-
License: Copyright (c) 2012-
|
|
7
|
+
License: Copyright (c) 2012-2025 Georgi Valkov. All rights reserved.
|
|
8
8
|
|
|
9
9
|
Redistribution and use in source and binary forms, with or without
|
|
10
10
|
modification, are permitted provided that the following conditions are
|
|
@@ -43,7 +43,7 @@ Classifier: Intended Audience :: Developers
|
|
|
43
43
|
Classifier: Topic :: Software Development :: Libraries
|
|
44
44
|
Classifier: License :: OSI Approved :: BSD License
|
|
45
45
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
46
|
-
Requires-Python: >=3.
|
|
46
|
+
Requires-Python: >=3.8
|
|
47
47
|
Description-Content-Type: text/markdown
|
|
48
48
|
License-File: LICENSE
|
|
49
49
|
|
|
@@ -52,6 +52,7 @@ License-File: LICENSE
|
|
|
52
52
|
<p>
|
|
53
53
|
<a href="https://pypi.python.org/pypi/evdev"><img alt="pypi version" src="https://img.shields.io/pypi/v/evdev.svg"></a>
|
|
54
54
|
<a href="https://github.com/gvalkov/python-evdev/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/pypi/l/evdev"></a>
|
|
55
|
+
<a href="https://repology.org/project/python:evdev/versions"><img alt="Packaging status" src="https://repology.org/badge/tiny-repos/python:evdev.svg"></a>
|
|
55
56
|
</p>
|
|
56
57
|
|
|
57
58
|
This package provides bindings to the generic input event interface in Linux.
|
|
@@ -6,12 +6,14 @@ setup.py
|
|
|
6
6
|
evdev/__init__.py
|
|
7
7
|
evdev/device.py
|
|
8
8
|
evdev/ecodes.py
|
|
9
|
+
evdev/ecodes_runtime.py
|
|
9
10
|
evdev/eventio.py
|
|
10
11
|
evdev/eventio_async.py
|
|
11
12
|
evdev/events.py
|
|
12
13
|
evdev/evtest.py
|
|
13
14
|
evdev/ff.py
|
|
14
|
-
evdev/
|
|
15
|
+
evdev/genecodes_c.py
|
|
16
|
+
evdev/genecodes_py.py
|
|
15
17
|
evdev/input.c
|
|
16
18
|
evdev/uinput.c
|
|
17
19
|
evdev/uinput.py
|
|
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "evdev"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.8.0"
|
|
8
8
|
description = "Bindings to the Linux input handling subsystem"
|
|
9
9
|
keywords = ["evdev", "input", "uinput"]
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
license = {file = "LICENSE"}
|
|
12
|
-
requires-python = ">=3.
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
13
|
authors = [
|
|
14
14
|
{ name="Georgi Valkov", email="georgi.t.valkov@gmail.com" },
|
|
15
15
|
]
|
|
@@ -39,7 +39,7 @@ line-length = 120
|
|
|
39
39
|
ignore = ["E265", "E241", "F403", "F401", "E401", "E731"]
|
|
40
40
|
|
|
41
41
|
[tool.bumpversion]
|
|
42
|
-
current_version = "1.
|
|
42
|
+
current_version = "1.8.0"
|
|
43
43
|
commit = true
|
|
44
44
|
tag = true
|
|
45
45
|
allow_dirty = true
|
|
@@ -49,3 +49,12 @@ filename = "pyproject.toml"
|
|
|
49
49
|
|
|
50
50
|
[[tool.bumpversion.files]]
|
|
51
51
|
filename = "docs/conf.py"
|
|
52
|
+
|
|
53
|
+
[tool.pylint.'MESSAGES CONTROL']
|
|
54
|
+
disable = """
|
|
55
|
+
no-member,
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
[tool.pylint.typecheck]
|
|
59
|
+
generated-members = ["evdev.ecodes.*"]
|
|
60
|
+
ignored-modules= ["evdev._*"]
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
|
+
import shutil
|
|
3
4
|
import textwrap
|
|
4
5
|
from pathlib import Path
|
|
6
|
+
from subprocess import run
|
|
5
7
|
|
|
6
8
|
from setuptools import setup, Extension, Command
|
|
7
9
|
from setuptools.command import build_ext as _build_ext
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
curdir = Path(__file__).resolve().parent
|
|
11
|
-
|
|
13
|
+
ecodes_c_path = curdir / "evdev/ecodes.c"
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
def create_ecodes(headers=None):
|
|
@@ -47,16 +49,18 @@ def create_ecodes(headers=None):
|
|
|
47
49
|
build_ecodes --evdev-headers path/input.h:path/input-event-codes.h \\
|
|
48
50
|
build_ext --include-dirs path/ \\
|
|
49
51
|
install
|
|
52
|
+
|
|
53
|
+
If you want to avoid building this package from source, then please consider
|
|
54
|
+
installing the `evdev-binary` package instead. Keep in mind that it may not be
|
|
55
|
+
fully compatible with, or support all the features of your current kernel.
|
|
50
56
|
"""
|
|
51
57
|
|
|
52
58
|
sys.stderr.write(textwrap.dedent(msg))
|
|
53
59
|
sys.exit(1)
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
with ecodes_path.open("w") as fh:
|
|
59
|
-
cmd = [sys.executable, "evdev/genecodes.py", *headers]
|
|
61
|
+
print("writing %s (using %s)" % (ecodes_c_path, " ".join(headers)))
|
|
62
|
+
with ecodes_c_path.open("w") as fh:
|
|
63
|
+
cmd = [sys.executable, "evdev/genecodes_c.py", "--ecodes", *headers]
|
|
60
64
|
run(cmd, check=True, stdout=fh)
|
|
61
65
|
|
|
62
66
|
|
|
@@ -80,14 +84,27 @@ class build_ecodes(Command):
|
|
|
80
84
|
|
|
81
85
|
class build_ext(_build_ext.build_ext):
|
|
82
86
|
def has_ecodes(self):
|
|
83
|
-
if
|
|
87
|
+
if ecodes_c_path.exists():
|
|
84
88
|
print("ecodes.c already exists ... skipping build_ecodes")
|
|
85
|
-
|
|
89
|
+
return False
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
def generate_ecodes_py(self):
|
|
93
|
+
ecodes_py = Path(self.build_lib) / "evdev/ecodes.py"
|
|
94
|
+
print(f"writing {ecodes_py}")
|
|
95
|
+
with ecodes_py.open("w") as fh:
|
|
96
|
+
cmd = [sys.executable, "-B", "evdev/genecodes_py.py"]
|
|
97
|
+
res = run(cmd, env={"PYTHONPATH": self.build_lib}, stdout=fh)
|
|
98
|
+
|
|
99
|
+
if res.returncode != 0:
|
|
100
|
+
print(f"failed to generate static {ecodes_py} - will use ecodes_runtime.py")
|
|
101
|
+
shutil.copy("evdev/ecodes_runtime.py", ecodes_py)
|
|
86
102
|
|
|
87
103
|
def run(self):
|
|
88
104
|
for cmd_name in self.get_sub_commands():
|
|
89
105
|
self.run_command(cmd_name)
|
|
90
106
|
_build_ext.build_ext.run(self)
|
|
107
|
+
self.generate_ecodes_py()
|
|
91
108
|
|
|
92
109
|
sub_commands = [("build_ecodes", has_ecodes)] + _build_ext.build_ext.sub_commands
|
|
93
110
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
-
|
|
2
|
+
import os
|
|
3
|
+
import stat
|
|
3
4
|
from select import select
|
|
4
|
-
from
|
|
5
|
+
from unittest.mock import patch
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
import pytest
|
|
8
|
+
from pytest import raises, fixture
|
|
7
9
|
|
|
10
|
+
from evdev import uinput, ecodes, device, UInputError
|
|
8
11
|
|
|
9
12
|
# -----------------------------------------------------------------------------
|
|
10
13
|
uinput_options = {
|
|
@@ -66,12 +69,12 @@ def test_enable_events(c):
|
|
|
66
69
|
|
|
67
70
|
def test_abs_values(c):
|
|
68
71
|
e = ecodes
|
|
69
|
-
c
|
|
72
|
+
c = {
|
|
70
73
|
e.EV_KEY: [e.KEY_A, e.KEY_B],
|
|
71
|
-
e.EV_ABS: [(e.ABS_X, (0, 255, 0, 0)), (e.ABS_Y, device.AbsInfo(0, 255, 5, 10, 0
|
|
74
|
+
e.EV_ABS: [(e.ABS_X, (0, 0, 255, 0, 0)), (e.ABS_Y, device.AbsInfo(0, 0, 255, 5, 10, 0))],
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
with uinput.UInput(
|
|
77
|
+
with uinput.UInput(events=c) as ui:
|
|
75
78
|
c = ui.capabilities()
|
|
76
79
|
abs = device.AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)
|
|
77
80
|
assert c[e.EV_ABS][0] == (0, abs)
|
|
@@ -114,3 +117,21 @@ def test_write(c):
|
|
|
114
117
|
assert evs[3].code == ecodes.KEY_A and evs[3].value == 2
|
|
115
118
|
assert evs[4].code == ecodes.KEY_A and evs[4].value == 0
|
|
116
119
|
break
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@patch.object(stat, 'S_ISCHR', return_value=False)
|
|
123
|
+
def test_not_a_character_device(ischr_mock, c):
|
|
124
|
+
with pytest.raises(UInputError, match='not a character device file'):
|
|
125
|
+
uinput.UInput(**c)
|
|
126
|
+
|
|
127
|
+
@patch.object(stat, 'S_ISCHR', return_value=True)
|
|
128
|
+
@patch.object(os, 'stat', side_effect=OSError())
|
|
129
|
+
def test_not_a_character_device_2(stat_mock, ischr_mock, c):
|
|
130
|
+
with pytest.raises(UInputError, match='not a character device file'):
|
|
131
|
+
uinput.UInput(**c)
|
|
132
|
+
|
|
133
|
+
@patch.object(stat, 'S_ISCHR', return_value=True)
|
|
134
|
+
@patch.object(os, 'stat', return_value=[])
|
|
135
|
+
def test_not_a_character_device_3(stat_mock, ischr_mock, c):
|
|
136
|
+
with pytest.raises(UInputError, match='not a character device file'):
|
|
137
|
+
uinput.UInput(**c)
|
evdev-1.7.1/evdev/__init__.py
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# --------------------------------------------------------------------------
|
|
2
|
-
# Gather everything into a single, convenient namespace.
|
|
3
|
-
# --------------------------------------------------------------------------
|
|
4
|
-
|
|
5
|
-
from evdev.device import DeviceInfo, InputDevice, AbsInfo, EvdevError
|
|
6
|
-
from evdev.events import InputEvent, KeyEvent, RelEvent, SynEvent, AbsEvent, event_factory
|
|
7
|
-
from evdev.uinput import UInput, UInputError
|
|
8
|
-
from evdev.util import list_devices, categorize, resolve_ecodes, resolve_ecodes_dict
|
|
9
|
-
from evdev import ecodes
|
|
10
|
-
from evdev import ff
|
evdev-1.7.1/evdev/genecodes.py
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Generate a Python extension module with the constants defined in linux/input.h.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from __future__ import print_function
|
|
6
|
-
import os, sys, re
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# -----------------------------------------------------------------------------
|
|
10
|
-
# The default header file locations to try.
|
|
11
|
-
headers = [
|
|
12
|
-
"/usr/include/linux/input.h",
|
|
13
|
-
"/usr/include/linux/input-event-codes.h",
|
|
14
|
-
"/usr/include/linux/uinput.h",
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
if sys.argv[1:]:
|
|
18
|
-
headers = sys.argv[1:]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# -----------------------------------------------------------------------------
|
|
22
|
-
macro_regex = r"#define +((?:KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF|UI_FF|INPUT_PROP)_\w+)"
|
|
23
|
-
macro_regex = re.compile(macro_regex)
|
|
24
|
-
|
|
25
|
-
uname = list(os.uname())
|
|
26
|
-
del uname[1]
|
|
27
|
-
uname = " ".join(uname)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# -----------------------------------------------------------------------------
|
|
31
|
-
template = r"""
|
|
32
|
-
#include <Python.h>
|
|
33
|
-
#ifdef __FreeBSD__
|
|
34
|
-
#include <dev/evdev/input.h>
|
|
35
|
-
#else
|
|
36
|
-
#include <linux/input.h>
|
|
37
|
-
#include <linux/uinput.h>
|
|
38
|
-
#endif
|
|
39
|
-
|
|
40
|
-
/* Automatically generated by evdev.genecodes */
|
|
41
|
-
/* Generated on %s */
|
|
42
|
-
|
|
43
|
-
#define MODULE_NAME "_ecodes"
|
|
44
|
-
#define MODULE_HELP "linux/input.h macros"
|
|
45
|
-
|
|
46
|
-
static PyMethodDef MethodTable[] = {
|
|
47
|
-
{ NULL, NULL, 0, NULL}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
static struct PyModuleDef moduledef = {
|
|
51
|
-
PyModuleDef_HEAD_INIT,
|
|
52
|
-
MODULE_NAME,
|
|
53
|
-
MODULE_HELP,
|
|
54
|
-
-1, /* m_size */
|
|
55
|
-
MethodTable, /* m_methods */
|
|
56
|
-
NULL, /* m_reload */
|
|
57
|
-
NULL, /* m_traverse */
|
|
58
|
-
NULL, /* m_clear */
|
|
59
|
-
NULL, /* m_free */
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
PyMODINIT_FUNC
|
|
63
|
-
PyInit__ecodes(void)
|
|
64
|
-
{
|
|
65
|
-
PyObject* m = PyModule_Create(&moduledef);
|
|
66
|
-
if (m == NULL) return NULL;
|
|
67
|
-
|
|
68
|
-
%s
|
|
69
|
-
|
|
70
|
-
return m;
|
|
71
|
-
}
|
|
72
|
-
"""
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def parse_header(header):
|
|
76
|
-
for line in open(header):
|
|
77
|
-
macro = macro_regex.search(line)
|
|
78
|
-
if macro:
|
|
79
|
-
yield " PyModule_AddIntMacro(m, %s);" % macro.group(1)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
all_macros = []
|
|
83
|
-
for header in headers:
|
|
84
|
-
try:
|
|
85
|
-
fh = open(header)
|
|
86
|
-
except (IOError, OSError):
|
|
87
|
-
continue
|
|
88
|
-
all_macros += parse_header(header)
|
|
89
|
-
|
|
90
|
-
if not all_macros:
|
|
91
|
-
print("no input macros found in: %s" % " ".join(headers), file=sys.stderr)
|
|
92
|
-
sys.exit(1)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
macros = os.linesep.join(all_macros)
|
|
96
|
-
print(template % (uname, macros))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|