Import Upstream version 0.33
This commit is contained in:
parent
466392cd2e
commit
ee09aa30a6
|
@ -59,6 +59,9 @@ docs/_build/
|
|||
target/
|
||||
|
||||
# IntelliJ
|
||||
|
||||
.idea/
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
|
||||
/.mypy_cache/
|
||||
|
|
|
@ -2,10 +2,12 @@ language: python
|
|||
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
|
||||
# command to install dependencies
|
||||
install:
|
||||
|
|
135
CHANGELOG.md
135
CHANGELOG.md
|
@ -1,5 +1,140 @@
|
|||
NEWS for Python X Library
|
||||
|
||||
Version 0.33
|
||||
============
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Removed unused imports (thanks @Avasam).
|
||||
- Avoid to use fcntl module on some environments (thanks @i2y).
|
||||
- Change a test behavior for `unix_connect.get_socket` (thanks @i2y).
|
||||
- Fix accidental data change (thanks @Avasam).
|
||||
- Prefer `bool` over `Literal[0, 1, None]` (thanks @Avasam).
|
||||
- Change parentheses to brackets in LICENSE (thanks @mtelka).
|
||||
|
||||
---
|
||||
Version 0.32
|
||||
============
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Use archived link for X documentation resource (thanks @yaxollum).
|
||||
- Fix for auth entry having no display number (thanks @Majiir).
|
||||
- Fix return type inconsistency with the `pack_value` for class `Object` (thanks @allfro).
|
||||
- Rename `add_extension_error` method to `extension_add_error` (thanks @mattalexx).
|
||||
|
||||
Extensions
|
||||
--------------------
|
||||
|
||||
- screensaver: fix screensaver protocol mismatch (thanks @yut23).
|
||||
- XRandr: add version 1.5 support for RRSetMonitor RRGetMonitors and RRDeleteMonitors (thanks @allfro and @jklong).
|
||||
|
||||
---
|
||||
Version 0.31
|
||||
============
|
||||
|
||||
Extensions
|
||||
--------------------
|
||||
|
||||
- XInput: add event methods (thanks @dd4e).
|
||||
|
||||
---
|
||||
Version 0.30
|
||||
============
|
||||
|
||||
Extensions
|
||||
--------------------
|
||||
|
||||
- XResource: first implementation (thanks @alebastr).
|
||||
- XRandr: add missing parameters to delete_output_mode function (thanks @jimmy-loyola).
|
||||
|
||||
---
|
||||
Version 0.29
|
||||
============
|
||||
|
||||
Extensions
|
||||
--------------------
|
||||
|
||||
- Drawable & XInput: Avoid using array.array.tostring() which wiil be removed in Python 3.9 (thanks @t-wissmann).
|
||||
|
||||
---
|
||||
Version 0.28
|
||||
============
|
||||
|
||||
Extensions
|
||||
--------------------
|
||||
|
||||
- DPMS: Display Power Management Signaling (by @thiagokokada)
|
||||
|
||||
---
|
||||
Version 0.27
|
||||
============
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- fix TypeError in socket.error exception handling for Python 3.x (by @t-wissmann)
|
||||
|
||||
Extensions
|
||||
--------------------
|
||||
|
||||
- NV-CONTROL: set offset for all perf levels (by @Sporif)
|
||||
|
||||
---
|
||||
Version 0.26
|
||||
============
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- support legacy X servers like RealVNC's one (by @Gerardwx)
|
||||
|
||||
Extensions
|
||||
--------------------
|
||||
|
||||
- enrich XFixes extension with XFixesSelectionNotify events (by @acrisci)
|
||||
- add example xfixes-selection-notify.py (by @acrisci)
|
||||
- fix two issues in NV-CONTROL extension (by @leinardi)
|
||||
- add method get_clock_info into NV-CONTROL extension (by @leinardi)
|
||||
- add default client version into Composite extension (by @jakogut)
|
||||
- add Damage extension with the example (by @mgarg1 and @jakogut)
|
||||
|
||||
---
|
||||
Version 0.25
|
||||
============
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- fix increasing memory usage on display instantiation
|
||||
|
||||
NV-CONTROL extension
|
||||
--------------------
|
||||
|
||||
- add first implementation by Roberto Leinardi (@leinardi)
|
||||
|
||||
---
|
||||
Version 0.24
|
||||
============
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- fix protocol handling: correctly support explicit Unix
|
||||
connections and fix support fox macOS
|
||||
- improve Python 3 support: fix events sub-code handling
|
||||
and possible crashes when unpacking text data
|
||||
- add support for error handlers to the Composite extension
|
||||
|
||||
Misc
|
||||
----
|
||||
|
||||
- fix `xfixes` example
|
||||
- fix a bunch of typos in the code / documentation
|
||||
|
||||
---
|
||||
Version 0.23
|
||||
============
|
||||
|
||||
|
|
4
LICENSE
4
LICENSE
|
@ -6,9 +6,9 @@
|
|||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
(This is the first released version of the Lesser GPL. It also counts
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.)
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
|
|
150
PKG-INFO
150
PKG-INFO
|
@ -1,150 +0,0 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: python-xlib
|
||||
Version: 0.23
|
||||
Summary: Python X Library
|
||||
Home-page: https://github.com/python-xlib/python-xlib
|
||||
Author: Peter Liljenberg
|
||||
Author-email: petli@ctrl-c.liu.se
|
||||
License: LGPLv2+
|
||||
Download-URL: https://github.com/python-xlib/python-xlib/releases
|
||||
Description-Content-Type: UNKNOWN
|
||||
Description: The Python X Library
|
||||
====================
|
||||
|
||||
|Build Status| |codecov.io| |Code Health|
|
||||
|
||||
`Homepage`_ | `Releases`_ | `Changelog`_
|
||||
|
||||
Copyright
|
||||
~~~~~~~~~
|
||||
|
||||
The main part of the code is
|
||||
|
||||
::
|
||||
|
||||
Copyright (C) 2000-2002 Peter Liljenberg
|
||||
|
||||
Some contributed code is copyrighted by `the contributors <Contributors_>`_,
|
||||
in these cases that is indicated in the source files in question.
|
||||
|
||||
The Python X Library is released under LGPL v2.1 or later (since 2016),
|
||||
see the file LICENSE for details. 0.15rc1 and before were released under
|
||||
GPL v2.
|
||||
|
||||
Requirements
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The Python X Library requires Python 2.7 or newer. It has been tested to
|
||||
various extents with Python 2.7 and 3.3 through 3.6.
|
||||
|
||||
Installation
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The Python Xlib uses the standard setuptools package, to install run
|
||||
this command:
|
||||
|
||||
::
|
||||
|
||||
python setup.py install
|
||||
|
||||
See the command help for details: ``python setup.py install -h``.
|
||||
|
||||
Alternatively, you can run programs from the distribution directory, or
|
||||
change the module path in programs.
|
||||
|
||||
There's a simple example program, implemented twice using both the
|
||||
high-level interface and the low-level protocol.
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The Python X Library is intended to be a fully functional X client
|
||||
library for Python programs. It is written entirely in Python, in
|
||||
contrast to earlier X libraries for Python (the ancient X extension and
|
||||
the newer plxlib) which were interfaces to the C Xlib.
|
||||
|
||||
This is possible to do since X client programs communicate with the X
|
||||
server via the X protocol. The communication takes place over TCP/IP,
|
||||
Unix sockets, DECnet or any other streaming network protocol. The C Xlib
|
||||
is merely an interface to this protocol, providing functions suitable
|
||||
for a C environment.
|
||||
|
||||
There are three advantages of implementing a pure Python library:
|
||||
|
||||
- Integration: The library can make use of the wonderful object system
|
||||
in Python, providing an easy-to-use class hierarchy.
|
||||
|
||||
- Portability: The library will be usable on (almost) any computer
|
||||
which have Python installed. A C interface could be problematic to
|
||||
port to non-Unix systems, such as MS Windows or OpenVMS.
|
||||
|
||||
- Maintainability: It is much easier to develop and debug native Python
|
||||
modules than modules written in C.
|
||||
|
||||
Documentation
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The reference manual is not finished by far, but is probably still useful. It
|
||||
can be `browsed online <http://python-xlib.sourceforge.net/doc/html/index.html>`__.
|
||||
|
||||
There are also some `example programs <Examples_>`_ and, of course,
|
||||
`the standard X11 documentation <http://tronche.com/gui/x/xlib/>`__ applies.
|
||||
|
||||
|
||||
Project status
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The low-level protocol is complete, implementing client-side X11R6. The
|
||||
high-level object oriented interface is also fully functional. It is
|
||||
possible to write client applications with the library. Currently, the
|
||||
only real application using Python Xlib is the window manager PLWM,
|
||||
starting with version 2.0.
|
||||
|
||||
There is a resource database implementation, ICCCM support and a
|
||||
framework for adding X extension code. Several extensions have been
|
||||
implemented; (RECORD, SHAPE, Xinerama, Composite, RANDR, and XTEST)
|
||||
patches for additions are very welcome.
|
||||
|
||||
There are most likely still bugs, but the library is at least stable
|
||||
enough to run PLWM. A continuously bigger part of the library is covered
|
||||
by regression tests, improving stability.
|
||||
|
||||
The documentation is still quite rudimentary, but should be of some help
|
||||
for people programming with the Xlib. X beginners should first find some
|
||||
general texts on X. A very good starting point is
|
||||
http://www.rahul.net/kenton/xsites.html
|
||||
|
||||
See the file TODO for a detailed list of what is missing, approximately
|
||||
ordered by importance.
|
||||
|
||||
.. _Homepage: https://github.com/python-xlib/python-xlib
|
||||
.. _Releases: https://github.com/python-xlib/python-xlib/releases
|
||||
.. _Changelog: https://github.com/python-xlib/python-xlib/tree/master/CHANGELOG.md
|
||||
.. _Contributors: https://github.com/python-xlib/python-xlib/graphs/contributors
|
||||
.. _Examples: https://github.com/python-xlib/python-xlib/tree/master/examples
|
||||
|
||||
.. |Build Status| image:: https://travis-ci.org/python-xlib/python-xlib.svg?branch=master
|
||||
:target: https://travis-ci.org/python-xlib/python-xlib
|
||||
.. |codecov.io| image:: https://codecov.io/github/python-xlib/python-xlib/coverage.svg?branch=master
|
||||
:target: https://codecov.io/github/python-xlib/python-xlib?branch=master
|
||||
.. |Code Health| image:: https://landscape.io/github/python-xlib/python-xlib/master/landscape.svg?style=flat
|
||||
:target: https://landscape.io/github/python-xlib/python-xlib/master
|
||||
|
||||
Keywords: windows,x,x11,xlib
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: X11 Applications
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
Classifier: Topic :: Software Development :: User Interfaces
|
12
README.rst
12
README.rst
|
@ -27,6 +27,9 @@ Requirements
|
|||
The Python X Library requires Python 2.7 or newer. It has been tested to
|
||||
various extents with Python 2.7 and 3.3 through 3.6.
|
||||
|
||||
The Python X Library will only work on systems that have an X server installed,
|
||||
such as most Linux distros, but will not work on Windows or MacOS.
|
||||
|
||||
Installation
|
||||
~~~~~~~~~~~~
|
||||
|
||||
|
@ -70,15 +73,15 @@ There are three advantages of implementing a pure Python library:
|
|||
|
||||
- Maintainability: It is much easier to develop and debug native Python
|
||||
modules than modules written in C.
|
||||
|
||||
|
||||
Documentation
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The reference manual is not finished by far, but is probably still useful. It
|
||||
can be `browsed online <http://python-xlib.sourceforge.net/doc/html/index.html>`__.
|
||||
can be `browsed online <https://python-xlib.github.io/>`__.
|
||||
|
||||
There are also some `example programs <Examples_>`_ and, of course,
|
||||
`the standard X11 documentation <http://tronche.com/gui/x/xlib/>`__ applies.
|
||||
`the standard X11 documentation <https://tronche.com/gui/x/xlib/>`__ applies.
|
||||
|
||||
|
||||
Project status
|
||||
|
@ -92,7 +95,8 @@ starting with version 2.0.
|
|||
|
||||
There is a resource database implementation, ICCCM support and a
|
||||
framework for adding X extension code. Several extensions have been
|
||||
implemented; (RECORD, SHAPE, Xinerama, Composite, RANDR, and XTEST)
|
||||
implemented (RECORD, SHAPE, Xinerama, Composite, RANDR, DAMAGE,
|
||||
Generic Event, SECURITY, XFIXES, XInput, XTEST, NV-CONTROL, DPMS and XRes);
|
||||
patches for additions are very welcome.
|
||||
|
||||
There are most likely still bugs, but the library is at least stable
|
||||
|
|
|
@ -197,6 +197,8 @@ PlaceOnBottom = 1
|
|||
FamilyInternet = 0
|
||||
FamilyDECnet = 1
|
||||
FamilyChaos = 2
|
||||
FamilyServerInterpreted = 5
|
||||
FamilyInternetV6 = 6
|
||||
PropertyNewValue = 0
|
||||
PropertyDelete = 1
|
||||
ColormapUninstalled = 0
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
__version__ = (0, 23)
|
||||
__version__ = (0, 33)
|
||||
|
||||
__version_extra__ = ''
|
||||
|
||||
|
|
|
@ -62,16 +62,16 @@ _resource_hierarchy = {
|
|||
}
|
||||
|
||||
class _BaseDisplay(protocol_display.Display):
|
||||
resource_classes = _resource_baseclasses.copy()
|
||||
|
||||
# Implement a cache of atom names, used by Window objects when
|
||||
# dealing with some ICCCM properties not defined in Xlib.Xatom
|
||||
|
||||
def __init__(self, *args, **keys):
|
||||
self.resource_classes = _resource_baseclasses.copy()
|
||||
protocol_display.Display.__init__(self, *args, **keys)
|
||||
self._atom_cache = {}
|
||||
|
||||
def get_atom(self, atomname, only_if_exists=0):
|
||||
def get_atom(self, atomname, only_if_exists=False):
|
||||
if atomname in self._atom_cache:
|
||||
return self._atom_cache[atomname]
|
||||
|
||||
|
@ -340,8 +340,8 @@ class Display(object):
|
|||
# extension dict maintained in the display object
|
||||
setattr(self.extension_event, name, (code,subcode))
|
||||
|
||||
def add_extension_error(self, code, err):
|
||||
"""add_extension_error(code, err)
|
||||
def extension_add_error(self, code, err):
|
||||
"""extension_add_error(code, err)
|
||||
|
||||
Add an extension error. CODE is the numeric code, and ERR is
|
||||
the error class.
|
||||
|
@ -473,7 +473,7 @@ class Display(object):
|
|||
### X requests
|
||||
###
|
||||
|
||||
def intern_atom(self, name, only_if_exists = 0):
|
||||
def intern_atom(self, name, only_if_exists = False):
|
||||
"""Intern the string name, returning its atom number. If
|
||||
only_if_exists is true and the atom does not already exist, it
|
||||
will not be created and X.NONE is returned."""
|
||||
|
@ -482,7 +482,7 @@ class Display(object):
|
|||
only_if_exists = only_if_exists)
|
||||
return r.atom
|
||||
|
||||
def get_atom(self, atom, only_if_exists = 0):
|
||||
def get_atom(self, atom, only_if_exists = False):
|
||||
"""Alias for intern_atom, using internal cache"""
|
||||
return self.display.get_atom(atom, only_if_exists)
|
||||
|
||||
|
@ -501,7 +501,7 @@ class Display(object):
|
|||
selection = selection)
|
||||
return r.owner
|
||||
|
||||
def send_event(self, destination, event, event_mask = 0, propagate = 0,
|
||||
def send_event(self, destination, event, event_mask = 0, propagate = False,
|
||||
onerror = None):
|
||||
"""Send a synthetic event to the window destination which can be
|
||||
a window object, or X.PointerWindow or X.InputFocus. event is the
|
||||
|
@ -517,7 +517,7 @@ class Display(object):
|
|||
event = event)
|
||||
|
||||
def ungrab_pointer(self, time, onerror = None):
|
||||
"""elease a grabbed pointer and any queued events. See
|
||||
"""Release a grabbed pointer and any queued events. See
|
||||
XUngrabPointer(3X11)."""
|
||||
request.UngrabPointer(display = self.display,
|
||||
onerror = onerror,
|
||||
|
@ -661,7 +661,7 @@ class Display(object):
|
|||
font_ascent
|
||||
font_descent
|
||||
replies_hint
|
||||
See the descripton of XFontStruct in XGetFontProperty(3X11)
|
||||
See the description of XFontStruct in XGetFontProperty(3X11)
|
||||
for details on these values.
|
||||
properties
|
||||
A list of properties. Each entry has two attributes:
|
||||
|
@ -849,7 +849,8 @@ class Display(object):
|
|||
|
||||
def change_hosts(self, mode, host_family, host, onerror = None):
|
||||
"""mode is either X.HostInsert or X.HostDelete. host_family is
|
||||
one of X.FamilyInternet, X.FamilyDECnet or X.FamilyChaos.
|
||||
one of X.FamilyInternet, X.FamilyDECnet, X.FamilyChaos,
|
||||
X.FamilyServerInterpreted or X.FamilyInternetV6.
|
||||
|
||||
host is a list of bytes. For the Internet family, it should be the
|
||||
four bytes of an IPv4 address."""
|
||||
|
@ -868,7 +869,7 @@ hosts
|
|||
The hosts on the access list. Each entry has the following attributes:
|
||||
|
||||
family
|
||||
X.FamilyInternet, X.FamilyDECnet, or X.FamilyChaos.
|
||||
X.FamilyInternet, X.FamilyDECnet, X.FamilyChaos, X.FamilyServerInterpreted or X.FamilyInternetV6.
|
||||
name
|
||||
A list of byte values, the coding depends on family. For the Internet family, it is the 4 bytes of an IPv4 address.
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class XError(rq.GetAttrData, Exception):
|
|||
)
|
||||
|
||||
def __init__(self, display, data):
|
||||
self._data, data = self._fields.parse_binary(data, display, rawdict = 1)
|
||||
self._data, _ = self._fields.parse_binary(data, display, rawdict = True)
|
||||
|
||||
def __str__(self):
|
||||
s = []
|
||||
|
|
|
@ -36,6 +36,11 @@ __extensions__ = [
|
|||
('XFIXES', 'xfixes'),
|
||||
('SECURITY', 'security'),
|
||||
('XInputExtension', 'xinput'),
|
||||
('NV-CONTROL', 'nvcontrol'),
|
||||
('DAMAGE', 'damage'),
|
||||
('DPMS', 'dpms'),
|
||||
('X-Resource', 'res'),
|
||||
('MIT-SCREEN-SAVER', 'screensaver'),
|
||||
]
|
||||
|
||||
__all__ = map(lambda x: x[1], __extensions__)
|
||||
|
|
|
@ -33,7 +33,6 @@ also need RENDER or glX or some similar method of creating fancy
|
|||
graphics.
|
||||
"""
|
||||
|
||||
from Xlib import X
|
||||
from Xlib.protocol import rq
|
||||
from Xlib.xobject import drawable
|
||||
|
||||
|
@ -65,6 +64,8 @@ def query_version(self):
|
|||
return QueryVersion(
|
||||
display = self.display,
|
||||
opcode = self.display.get_extension_major(extname),
|
||||
major_version=0,
|
||||
minor_version=4
|
||||
)
|
||||
|
||||
|
||||
|
@ -78,11 +79,12 @@ class RedirectWindow(rq.Request):
|
|||
rq.Pad(3),
|
||||
)
|
||||
|
||||
def redirect_window(self, update):
|
||||
def redirect_window(self, update, onerror = None):
|
||||
"""Redirect the hierarchy starting at this window to off-screen
|
||||
storage.
|
||||
"""
|
||||
RedirectWindow(display = self.display,
|
||||
onerror = onerror,
|
||||
opcode = self.display.get_extension_major(extname),
|
||||
window = self,
|
||||
update = update,
|
||||
|
@ -99,11 +101,12 @@ class RedirectSubwindows(rq.Request):
|
|||
rq.Pad(3),
|
||||
)
|
||||
|
||||
def redirect_subwindows(self, update):
|
||||
def redirect_subwindows(self, update, onerror = None):
|
||||
"""Redirect the hierarchies starting at all current and future
|
||||
children to this window to off-screen storage.
|
||||
"""
|
||||
RedirectSubwindows(display = self.display,
|
||||
onerror = onerror,
|
||||
opcode = self.display.get_extension_major(extname),
|
||||
window = self,
|
||||
update = update,
|
||||
|
@ -120,10 +123,11 @@ class UnredirectWindow(rq.Request):
|
|||
rq.Pad(3),
|
||||
)
|
||||
|
||||
def unredirect_window(self, update):
|
||||
def unredirect_window(self, update, onerror = None):
|
||||
"""Stop redirecting this window hierarchy.
|
||||
"""
|
||||
UnredirectWindow(display = self.display,
|
||||
onerror = onerror,
|
||||
opcode = self.display.get_extension_major(extname),
|
||||
window = self,
|
||||
update = update,
|
||||
|
@ -140,10 +144,11 @@ class UnredirectSubindows(rq.Request):
|
|||
rq.Pad(3),
|
||||
)
|
||||
|
||||
def unredirect_subwindows(self, update):
|
||||
def unredirect_subwindows(self, update, onerror = None):
|
||||
"""Stop redirecting the hierarchies of children to this window.
|
||||
"""
|
||||
RedirectWindow(display = self.display,
|
||||
onerror = onerror,
|
||||
opcode = self.display.get_extension_major(extname),
|
||||
window = self,
|
||||
update = update,
|
||||
|
@ -159,7 +164,7 @@ class CreateRegionFromBorderClip(rq.Request):
|
|||
rq.Window('window'),
|
||||
)
|
||||
|
||||
def create_region_from_border_clip(self):
|
||||
def create_region_from_border_clip(self, onerror = None):
|
||||
"""Create a region of the border clip of the window, i.e. the area
|
||||
that is not clipped by the parent and any sibling windows.
|
||||
"""
|
||||
|
@ -167,6 +172,7 @@ def create_region_from_border_clip(self):
|
|||
rid = self.display.allocate_resource_id()
|
||||
CreateRegionFromBorderClip(
|
||||
display = self.display,
|
||||
onerror = onerror,
|
||||
opcode = self.display.get_extension_major(extname),
|
||||
region = rid,
|
||||
window = self,
|
||||
|
@ -185,7 +191,7 @@ class NameWindowPixmap(rq.Request):
|
|||
rq.Pixmap('pixmap'),
|
||||
)
|
||||
|
||||
def name_window_pixmap(self):
|
||||
def name_window_pixmap(self, onerror = None):
|
||||
"""Create a new pixmap that refers to the off-screen storage of
|
||||
the window, including its border.
|
||||
|
||||
|
@ -198,6 +204,7 @@ def name_window_pixmap(self):
|
|||
|
||||
pid = self.display.allocate_resource_id()
|
||||
NameWindowPixmap(display = self.display,
|
||||
onerror = onerror,
|
||||
opcode = self.display.get_extension_major(extname),
|
||||
window = self,
|
||||
pixmap = pid,
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
# Xlib.ext.damage -- DAMAGE extension module
|
||||
#
|
||||
# Copyright (C) 2018 Joseph Kogut <joseph.kogut@gmail.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 59 Temple Place,
|
||||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
from Xlib import X
|
||||
from Xlib.protocol import rq, structs
|
||||
from Xlib.error import XError
|
||||
|
||||
extname = 'DAMAGE'
|
||||
|
||||
# Event codes #
|
||||
DamageNotifyCode = 0
|
||||
|
||||
# Error codes #
|
||||
BadDamageCode = 0
|
||||
|
||||
class BadDamageError(XError):
|
||||
pass
|
||||
|
||||
# DamageReportLevel options
|
||||
DamageReportRawRectangles = 0
|
||||
DamageReportDeltaRectangles = 1
|
||||
DamageReportBoundingBox = 2
|
||||
DamageReportNonEmpty = 3
|
||||
|
||||
DamageReportLevel = (
|
||||
DamageReportRawRectangles,
|
||||
DamageReportDeltaRectangles,
|
||||
DamageReportBoundingBox,
|
||||
DamageReportNonEmpty,
|
||||
)
|
||||
|
||||
DAMAGE = rq.Card32
|
||||
|
||||
# Methods
|
||||
|
||||
class QueryVersion(rq.ReplyRequest):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(0),
|
||||
rq.RequestLength(),
|
||||
rq.Card32('major_version'),
|
||||
rq.Card32('minor_version'),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Card32('major_version'),
|
||||
rq.Card32('minor_version'),
|
||||
rq.Pad(16),
|
||||
)
|
||||
|
||||
def query_version(self):
|
||||
return QueryVersion(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1)
|
||||
|
||||
class DamageCreate(rq.Request):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(1),
|
||||
rq.RequestLength(),
|
||||
DAMAGE('damage'),
|
||||
rq.Drawable('drawable'),
|
||||
rq.Set('level', 1, DamageReportLevel),
|
||||
rq.Pad(3),
|
||||
)
|
||||
|
||||
def damage_create(self, level):
|
||||
did = self.display.allocate_resource_id()
|
||||
DamageCreate(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
damage=did,
|
||||
drawable=self.id,
|
||||
level=level,
|
||||
)
|
||||
return did
|
||||
|
||||
class DamageDestroy(rq.Request):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(2),
|
||||
rq.RequestLength(),
|
||||
DAMAGE('damage')
|
||||
)
|
||||
|
||||
def damage_destroy(self, damage):
|
||||
DamageDestroy(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
damage=damage,
|
||||
)
|
||||
|
||||
self.display.free_resource_id(damage)
|
||||
|
||||
class DamageSubtract(rq.Request):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(3),
|
||||
rq.RequestLength(),
|
||||
DAMAGE('damage'),
|
||||
rq.Card32('repair'),
|
||||
rq.Card32('parts')
|
||||
)
|
||||
|
||||
def damage_subtract(self, damage, repair=X.NONE, parts=X.NONE):
|
||||
DamageSubtract(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
damage=damage,
|
||||
repair=repair,
|
||||
parts=parts)
|
||||
|
||||
class DamageAdd(rq.Request):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(4),
|
||||
rq.RequestLength(),
|
||||
rq.Card32('repair'),
|
||||
rq.Card32('parts'),
|
||||
)
|
||||
|
||||
def damage_add(self, repair, parts):
|
||||
DamageAdd(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
repair=repair,
|
||||
parts=parts)
|
||||
|
||||
# Events #
|
||||
|
||||
class DamageNotify(rq.Event):
|
||||
_code = None
|
||||
_fields = rq.Struct(
|
||||
rq.Card8('type'),
|
||||
rq.Card8('level'),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.Drawable('drawable'),
|
||||
DAMAGE('damage'),
|
||||
rq.Card32('timestamp'),
|
||||
rq.Object('area', structs.Rectangle),
|
||||
rq.Object('drawable_geometry', structs.Rectangle)
|
||||
)
|
||||
|
||||
def init(disp, info):
|
||||
disp.extension_add_method('display',
|
||||
'damage_query_version',
|
||||
query_version)
|
||||
|
||||
disp.extension_add_method('drawable',
|
||||
'damage_create',
|
||||
damage_create)
|
||||
|
||||
disp.extension_add_method('display',
|
||||
'damage_destroy',
|
||||
damage_destroy)
|
||||
|
||||
disp.extension_add_method('display',
|
||||
'damage_subtract',
|
||||
damage_subtract)
|
||||
|
||||
disp.extension_add_method('drawable',
|
||||
'damage_add',
|
||||
damage_add)
|
||||
|
||||
disp.extension_add_event(info.first_event + DamageNotifyCode, DamageNotify)
|
||||
|
||||
disp.extension_add_error(code=BadDamageCode, err=BadDamageError)
|
|
@ -0,0 +1,232 @@
|
|||
# Xlib.ext.dpms -- X Display Power Management Signaling
|
||||
#
|
||||
# Copyright (C) 2020 Thiago Kenji Okada <thiagokokada@gmail.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 59 Temple Place,
|
||||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
'''
|
||||
This extension provides X Protocol control over the VESA Display
|
||||
Power Management Signaling (DPMS) characteristics of video boards
|
||||
under control of the X Window System.
|
||||
|
||||
Documentation: https://www.x.org/releases/X11R7.7/doc/xextproto/dpms.html
|
||||
'''
|
||||
|
||||
from Xlib.protocol import rq
|
||||
|
||||
extname = 'DPMS'
|
||||
|
||||
|
||||
# DPMS Extension Power Levels
|
||||
# 0 DPMSModeOn In use
|
||||
# 1 DPMSModeStandby Blanked, low power
|
||||
# 2 DPMSModeSuspend Blanked, lower power
|
||||
# 3 DPMSModeOff Shut off, awaiting activity
|
||||
DPMSModeOn = 0
|
||||
DPMSModeStandby = 1
|
||||
DPMSModeSuspend = 2
|
||||
DPMSModeOff = 3
|
||||
|
||||
DPMSPowerLevel = (
|
||||
DPMSModeOn,
|
||||
DPMSModeStandby,
|
||||
DPMSModeSuspend,
|
||||
DPMSModeOff,
|
||||
)
|
||||
|
||||
|
||||
class DPMSGetVersion(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(0),
|
||||
rq.RequestLength(),
|
||||
rq.Card16('major_version'),
|
||||
rq.Card16('minor_version'),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Card16('major_version'),
|
||||
rq.Card16('minor_version'),
|
||||
rq.Pad(20),
|
||||
)
|
||||
|
||||
|
||||
def get_version(self):
|
||||
return DPMSGetVersion(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1)
|
||||
|
||||
|
||||
class DPMSCapable(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(1),
|
||||
rq.RequestLength(),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Bool('capable'),
|
||||
rq.Pad(23),
|
||||
)
|
||||
|
||||
|
||||
def capable(self):
|
||||
return DPMSCapable(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1)
|
||||
|
||||
|
||||
class DPMSGetTimeouts(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(2),
|
||||
rq.RequestLength(),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Card16('standby_timeout'),
|
||||
rq.Card16('suspend_timeout'),
|
||||
rq.Card16('off_timeout'),
|
||||
rq.Pad(18),
|
||||
)
|
||||
|
||||
|
||||
def get_timeouts(self):
|
||||
return DPMSGetTimeouts(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1)
|
||||
|
||||
|
||||
class DPMSSetTimeouts(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(3),
|
||||
rq.RequestLength(),
|
||||
rq.Card16('standby_timeout'),
|
||||
rq.Card16('suspend_timeout'),
|
||||
rq.Card16('off_timeout'),
|
||||
rq.Pad(2)
|
||||
)
|
||||
|
||||
|
||||
def set_timeouts(self, standby_timeout, suspend_timeout, off_timeout):
|
||||
return DPMSSetTimeouts(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1,
|
||||
standby_timeout=standby_timeout,
|
||||
suspend_timeout=suspend_timeout,
|
||||
off_timeout=off_timeout)
|
||||
|
||||
|
||||
class DPMSEnable(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(4),
|
||||
rq.RequestLength(),
|
||||
)
|
||||
|
||||
|
||||
def enable(self):
|
||||
return DPMSEnable(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1)
|
||||
|
||||
|
||||
class DPMSDisable(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(5),
|
||||
rq.RequestLength(),
|
||||
)
|
||||
|
||||
|
||||
def disable(self):
|
||||
return DPMSDisable(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1)
|
||||
|
||||
|
||||
class DPMSForceLevel(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(6),
|
||||
rq.RequestLength(),
|
||||
rq.Resource('power_level', DPMSPowerLevel),
|
||||
)
|
||||
|
||||
|
||||
def force_level(self, power_level):
|
||||
return DPMSForceLevel(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1,
|
||||
power_level=power_level)
|
||||
|
||||
|
||||
class DPMSInfo(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(7),
|
||||
rq.RequestLength(),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Card16('power_level'),
|
||||
rq.Bool('state'),
|
||||
rq.Pad(21),
|
||||
)
|
||||
|
||||
|
||||
def info(self):
|
||||
return DPMSInfo(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=1)
|
||||
|
||||
|
||||
def init(disp, _info):
|
||||
disp.extension_add_method('display', 'dpms_get_version', get_version)
|
||||
disp.extension_add_method('display', 'dpms_capable', capable)
|
||||
disp.extension_add_method('display', 'dpms_get_timeouts', get_timeouts)
|
||||
disp.extension_add_method('display', 'dpms_set_timeouts', set_timeouts)
|
||||
disp.extension_add_method('display', 'dpms_enable', enable)
|
||||
disp.extension_add_method('display', 'dpms_disable', disable)
|
||||
disp.extension_add_method('display', 'dpms_force_level', force_level)
|
||||
disp.extension_add_method('display', 'dpms_info', info)
|
File diff suppressed because it is too large
Load Diff
|
@ -22,10 +22,10 @@
|
|||
|
||||
"""RandR - provide access to the RandR extension information.
|
||||
|
||||
This implementation is based off version 1.3 of the XRandR protocol, and may
|
||||
This implementation is based off version 1.5 of the XRandR protocol, and may
|
||||
not be compatible with other versions.
|
||||
|
||||
Version 1.2 of the protocol is documented at:
|
||||
Version 1.5 of the protocol is documented at:
|
||||
http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt
|
||||
|
||||
Version 1.3.1 here:
|
||||
|
@ -35,7 +35,7 @@ http://www.x.org/releases/X11R7.5/doc/randrproto/randrproto.txt
|
|||
|
||||
|
||||
from Xlib import X
|
||||
from Xlib.protocol import rq, structs
|
||||
from Xlib.protocol import rq
|
||||
|
||||
extname = 'RANDR'
|
||||
|
||||
|
@ -122,6 +122,12 @@ BadRROutput = 0
|
|||
BadRRCrtc = 1
|
||||
BadRRMode = 2
|
||||
|
||||
# Error classes #
|
||||
class BadRROutputError(Exception): pass
|
||||
|
||||
class BadRRCrtcError(Exception): pass
|
||||
|
||||
class BadRRModeError(Exception): pass
|
||||
|
||||
# Data Structures #
|
||||
|
||||
|
@ -168,6 +174,19 @@ Render_Transform = rq.Struct(
|
|||
rq.Card32('matrix33'),
|
||||
)
|
||||
|
||||
MonitorInfo = rq.Struct(
|
||||
rq.Card32('name'),
|
||||
rq.Bool('primary'),
|
||||
rq.Bool('automatic'),
|
||||
rq.LengthOf('crtcs', 2),
|
||||
rq.Int16('x'),
|
||||
rq.Int16('y'),
|
||||
rq.Card16('width_in_pixels'),
|
||||
rq.Card16('height_in_pixels'),
|
||||
rq.Card32('width_in_millimeters'),
|
||||
rq.Card32('height_in_millimeters'),
|
||||
rq.List('crtcs', rq.Card32Obj)
|
||||
)
|
||||
|
||||
# Requests #
|
||||
|
||||
|
@ -197,7 +216,7 @@ def query_version(self):
|
|||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=3,
|
||||
minor_version=5,
|
||||
)
|
||||
|
||||
|
||||
|
@ -699,7 +718,7 @@ class DeleteOutputMode(rq.Request):
|
|||
rq.Card32('mode'),
|
||||
)
|
||||
|
||||
def delete_output_mode(self):
|
||||
def delete_output_mode(self, output, mode):
|
||||
return DeleteOutputMode(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
|
@ -1078,6 +1097,76 @@ def get_output_primary(self):
|
|||
)
|
||||
|
||||
|
||||
# Version 1.5 methods
|
||||
|
||||
class GetMonitors(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(42),
|
||||
rq.RequestLength(),
|
||||
rq.Window('window'),
|
||||
rq.Bool('is_active'),
|
||||
rq.Pad(3)
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Card32('timestamp'),
|
||||
rq.LengthOf('monitors', 4),
|
||||
rq.Card32('outputs'),
|
||||
rq.Pad(12),
|
||||
rq.List('monitors', MonitorInfo)
|
||||
)
|
||||
|
||||
|
||||
def get_monitors(self, is_active=True):
|
||||
return GetMonitors(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
window=self,
|
||||
is_active=is_active
|
||||
)
|
||||
|
||||
class SetMonitor(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(43),
|
||||
rq.RequestLength(),
|
||||
rq.Window('window'),
|
||||
rq.Object('monitor_info', MonitorInfo)
|
||||
)
|
||||
|
||||
|
||||
def set_monitor(self, monitor_info):
|
||||
return SetMonitor(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
window=self,
|
||||
monitor_info=monitor_info
|
||||
)
|
||||
|
||||
|
||||
class DeleteMonitor(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(44),
|
||||
rq.RequestLength(),
|
||||
rq.Window('window'),
|
||||
rq.Card32('name')
|
||||
)
|
||||
|
||||
|
||||
def delete_monitor(self, name):
|
||||
return DeleteMonitor(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
window=self,
|
||||
name=name
|
||||
)
|
||||
|
||||
# Events #
|
||||
|
||||
class ScreenChangeNotify(rq.Event):
|
||||
|
@ -1149,8 +1238,6 @@ class OutputPropertyNotify(rq.Event):
|
|||
rq.Card8('state'),
|
||||
rq.Pad(11),
|
||||
)
|
||||
|
||||
|
||||
# Initialization #
|
||||
|
||||
def init(disp, info):
|
||||
|
@ -1186,12 +1273,20 @@ def init(disp, info):
|
|||
disp.extension_add_method('display', 'xrandr_get_panning', get_panning)
|
||||
disp.extension_add_method('display', 'xrandr_set_panning', set_panning)
|
||||
|
||||
disp.extension_add_event(info.first_event + RRScreenChangeNotify, ScreenChangeNotify)
|
||||
# add RRNotify events (1 event code with 3 subcodes)
|
||||
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_CrtcChange, CrtcChangeNotify)
|
||||
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputChange, OutputChangeNotify)
|
||||
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputProperty, OutputPropertyNotify)
|
||||
# If the server is running RANDR 1.5+, enable 1.5 compatible methods and events
|
||||
version = query_version(disp)
|
||||
if version.major_version == 1 and version.minor_version >= 5:
|
||||
# version 1.5 compatible
|
||||
disp.extension_add_method('window', 'xrandr_get_monitors', get_monitors)
|
||||
disp.extension_add_method('window', 'xrandr_set_monitor', set_monitor)
|
||||
disp.extension_add_method('window', 'xrandr_delete_monitor', delete_monitor)
|
||||
|
||||
#disp.extension_add_error(BadRROutput, BadRROutputError)
|
||||
#disp.extension_add_error(BadRRCrtc, BadRRCrtcError)
|
||||
#disp.extension_add_error(BadRRMode, BadRRModeError)
|
||||
disp.extension_add_event(info.first_event + RRScreenChangeNotify, ScreenChangeNotify)
|
||||
# add RRNotify events (1 event code with 3 subcodes)
|
||||
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_CrtcChange, CrtcChangeNotify)
|
||||
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputChange, OutputChangeNotify)
|
||||
disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputProperty, OutputPropertyNotify)
|
||||
|
||||
disp.extension_add_error(BadRROutput, BadRROutputError)
|
||||
disp.extension_add_error(BadRRCrtc, BadRRCrtcError)
|
||||
disp.extension_add_error(BadRRMode, BadRRModeError)
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
from Xlib import X
|
||||
from Xlib.protocol import rq
|
||||
|
||||
extname = 'RECORD'
|
||||
|
|
|
@ -0,0 +1,288 @@
|
|||
# Xlib.ext.res -- X-Resource extension module
|
||||
#
|
||||
# Copyright (C) 2021 Aleksei Bavshin <alebastr89@gmail.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street,
|
||||
# Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA
|
||||
|
||||
"""X-Resource extension allows a client to query the X server about its usage
|
||||
of various resources.
|
||||
|
||||
For detailed description see any of the following documents.
|
||||
Protocol specification:
|
||||
https://www.x.org/releases/current/doc/resourceproto/resproto.txt
|
||||
XCB Protocol specification:
|
||||
https://cgit.freedesktop.org/xcb/proto/tree/src/res.xml
|
||||
"""
|
||||
from Xlib.protocol import rq
|
||||
|
||||
RES_MAJOR_VERSION = 1
|
||||
RES_MINOR_VERSION = 2
|
||||
|
||||
extname = "X-Resource"
|
||||
|
||||
# v1.0
|
||||
ResQueryVersion = 0
|
||||
ResQueryClients = 1
|
||||
ResQueryClientResources = 2
|
||||
ResQueryClientPixmapBytes = 3
|
||||
# v1.2
|
||||
ResQueryClientIds = 4
|
||||
ResQueryResourceBytes = 5
|
||||
|
||||
|
||||
class QueryVersion(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8("opcode"),
|
||||
rq.Opcode(ResQueryVersion),
|
||||
rq.RequestLength(),
|
||||
rq.Card8("client_major"),
|
||||
rq.Card8("client_minor"),
|
||||
rq.Pad(2))
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16("sequence_number"),
|
||||
rq.ReplyLength(),
|
||||
rq.Card16("server_major"),
|
||||
rq.Card16("server_minor"),
|
||||
rq.Pad(20))
|
||||
|
||||
|
||||
def query_version(self, client_major=RES_MAJOR_VERSION,
|
||||
client_minor=RES_MINOR_VERSION):
|
||||
""" Query the protocol version supported by the X server.
|
||||
|
||||
The client sends the highest supported version to the server and the
|
||||
server sends the highest version it supports, but no higher than the
|
||||
requested version."""
|
||||
return QueryVersion(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
client_major=client_major,
|
||||
client_minor=client_minor)
|
||||
|
||||
|
||||
Client = rq.Struct(
|
||||
rq.Card32("resource_base"),
|
||||
rq.Card32("resource_mask"))
|
||||
|
||||
|
||||
class QueryClients(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8("opcode"),
|
||||
rq.Opcode(ResQueryClients),
|
||||
rq.RequestLength())
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16("sequence_number"),
|
||||
rq.ReplyLength(),
|
||||
rq.LengthOf("clients", 4),
|
||||
rq.Pad(20),
|
||||
rq.List("clients", Client))
|
||||
|
||||
|
||||
def query_clients(self):
|
||||
"""Request the list of all currently connected clients."""
|
||||
return QueryClients(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname))
|
||||
|
||||
|
||||
Type = rq.Struct(
|
||||
rq.Card32("resource_type"),
|
||||
rq.Card32("count"))
|
||||
|
||||
|
||||
class QueryClientResources(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8("opcode"),
|
||||
rq.Opcode(ResQueryClientResources),
|
||||
rq.RequestLength(),
|
||||
rq.Card32("client"))
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16("sequence_number"),
|
||||
rq.ReplyLength(),
|
||||
rq.LengthOf("types", 4),
|
||||
rq.Pad(20),
|
||||
rq.List("types", Type))
|
||||
|
||||
|
||||
def query_client_resources(self, client):
|
||||
"""Request the number of resources owned by a client.
|
||||
|
||||
The server will return the counts of each type of resource.
|
||||
"""
|
||||
return QueryClientResources(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
client=client)
|
||||
|
||||
|
||||
class QueryClientPixmapBytes(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8("opcode"),
|
||||
rq.Opcode(ResQueryClientPixmapBytes),
|
||||
rq.RequestLength(),
|
||||
rq.Card32("client"))
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16("sequence_number"),
|
||||
rq.ReplyLength(),
|
||||
rq.Card32("bytes"),
|
||||
rq.Card32("bytes_overflow"),
|
||||
rq.Pad(16))
|
||||
|
||||
|
||||
def query_client_pixmap_bytes(self, client):
|
||||
"""Query the pixmap usage of some client.
|
||||
|
||||
The returned number is a sum of memory usage of each pixmap that can be
|
||||
attributed to the given client.
|
||||
"""
|
||||
return QueryClientPixmapBytes(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
client=client)
|
||||
|
||||
|
||||
class SizeOf(rq.LengthOf):
|
||||
"""A SizeOf stores the size in bytes of some other Field whose size
|
||||
may vary, e.g. List
|
||||
"""
|
||||
def __init__(self, name, size, item_size):
|
||||
rq.LengthOf.__init__(self, name, size)
|
||||
self.item_size = item_size
|
||||
|
||||
def parse_value(self, length, display):
|
||||
return length // self.item_size
|
||||
|
||||
|
||||
ClientXIDMask = 1 << 0
|
||||
LocalClientPIDMask = 1 << 1
|
||||
|
||||
|
||||
ClientIdSpec = rq.Struct(
|
||||
rq.Card32("client"),
|
||||
rq.Card32("mask"))
|
||||
|
||||
|
||||
ClientIdValue = rq.Struct(
|
||||
rq.Object("spec", ClientIdSpec),
|
||||
SizeOf("value", 4, 4),
|
||||
rq.List("value", rq.Card32Obj))
|
||||
|
||||
|
||||
class QueryClientIds(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8("opcode"),
|
||||
rq.Opcode(ResQueryClientIds),
|
||||
rq.RequestLength(),
|
||||
rq.LengthOf("specs", 4),
|
||||
rq.List("specs", ClientIdSpec))
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16("sequence_number"),
|
||||
rq.ReplyLength(),
|
||||
rq.LengthOf("ids", 4),
|
||||
rq.Pad(20),
|
||||
rq.List("ids", ClientIdValue))
|
||||
|
||||
|
||||
def query_client_ids(self, specs):
|
||||
"""Request to identify a given set of clients with some identification method.
|
||||
|
||||
The request sends a list of specifiers that select clients and
|
||||
identification methods to server. The server then tries to identify the
|
||||
chosen clients using the identification methods specified for each client.
|
||||
The server returns IDs for those clients that were successfully identified.
|
||||
"""
|
||||
return QueryClientIds(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
specs=specs)
|
||||
|
||||
|
||||
ResourceIdSpec = rq.Struct(
|
||||
rq.Card32("resource"),
|
||||
rq.Card32("type"))
|
||||
|
||||
|
||||
ResourceSizeSpec = rq.Struct(
|
||||
# inline struct ResourceIdSpec to work around
|
||||
# a parser bug with nested objects
|
||||
rq.Card32("resource"),
|
||||
rq.Card32("type"),
|
||||
rq.Card32("bytes"),
|
||||
rq.Card32("ref_count"),
|
||||
rq.Card32("use_count"))
|
||||
|
||||
|
||||
ResourceSizeValue = rq.Struct(
|
||||
rq.Object("size", ResourceSizeSpec),
|
||||
rq.LengthOf("cross_references", 4),
|
||||
rq.List("cross_references", ResourceSizeSpec))
|
||||
|
||||
|
||||
class QueryResourceBytes(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8("opcode"),
|
||||
rq.Opcode(ResQueryResourceBytes),
|
||||
rq.RequestLength(),
|
||||
rq.Card32("client"),
|
||||
rq.LengthOf("specs", 4),
|
||||
rq.List("specs", ResourceIdSpec))
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16("sequence_number"),
|
||||
rq.ReplyLength(),
|
||||
rq.LengthOf("sizes", 4),
|
||||
rq.Pad(20),
|
||||
rq.List("sizes", ResourceSizeValue))
|
||||
|
||||
|
||||
def query_resource_bytes(self, client, specs):
|
||||
"""Query the sizes of resources from X server.
|
||||
|
||||
The request sends a list of specifiers that selects resources for size
|
||||
calculation. The server tries to calculate the sizes of chosen resources
|
||||
and returns an estimate for a resource only if the size could be determined
|
||||
"""
|
||||
return QueryResourceBytes(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
client=client,
|
||||
specs=specs)
|
||||
|
||||
|
||||
def init(disp, info):
|
||||
disp.extension_add_method("display", "res_query_version", query_version)
|
||||
disp.extension_add_method("display", "res_query_clients", query_clients)
|
||||
disp.extension_add_method("display", "res_query_client_resources",
|
||||
query_client_resources)
|
||||
disp.extension_add_method("display", "res_query_client_pixmap_bytes",
|
||||
query_client_pixmap_bytes)
|
||||
disp.extension_add_method("display", "res_query_client_ids",
|
||||
query_client_ids)
|
||||
disp.extension_add_method("display", "res_query_resource_bytes",
|
||||
query_resource_bytes)
|
|
@ -0,0 +1,198 @@
|
|||
# Xlib.ext.screensaver -- X ScreenSaver extension module
|
||||
#
|
||||
# Copyright (C) 2022 Vladimir Panteleev <git@cy.md>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street,
|
||||
# Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA
|
||||
|
||||
"""This extension allows registering the client as an X screensaver,
|
||||
or query information about the current screensaver.
|
||||
|
||||
For detailed description see any of the following documents.
|
||||
Protocol specification:
|
||||
https://www.x.org/releases/X11R7.7/doc/scrnsaverproto/saver.html
|
||||
XCB Protocol specification:
|
||||
https://cgit.freedesktop.org/xcb/proto/tree/src/screensaver.xml
|
||||
|
||||
"""
|
||||
|
||||
from Xlib import X
|
||||
from Xlib.protocol import rq, structs
|
||||
|
||||
extname = 'MIT-SCREEN-SAVER'
|
||||
|
||||
# Event members
|
||||
NotifyMask = 1
|
||||
CycleMask = 2
|
||||
|
||||
# Notify state
|
||||
StateOff = 0
|
||||
StateOn = 1
|
||||
StateCycle = 2
|
||||
|
||||
# Notify kind
|
||||
KindBlanked = 0
|
||||
KindInternal = 1
|
||||
KindExternal = 2
|
||||
|
||||
class QueryVersion(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(0),
|
||||
rq.RequestLength(),
|
||||
rq.Card8('major_version'),
|
||||
rq.Card8('minor_version'),
|
||||
rq.Pad(2),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Card16('major_version'),
|
||||
rq.Card16('minor_version'),
|
||||
rq.Pad(20),
|
||||
)
|
||||
|
||||
def query_version(self):
|
||||
return QueryVersion(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
major_version=1,
|
||||
minor_version=0)
|
||||
|
||||
|
||||
class QueryInfo(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(1),
|
||||
rq.RequestLength(),
|
||||
rq.Drawable('drawable'),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Card8('state'),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Window('saver_window'),
|
||||
rq.Card32('til_or_since'),
|
||||
rq.Card32('idle'),
|
||||
rq.Card32('event_mask'), # rq.Set('event_mask', 4, (NotifyMask, CycleMask)),
|
||||
rq.Card8('kind'),
|
||||
rq.Pad(7),
|
||||
)
|
||||
|
||||
def query_info(self):
|
||||
return QueryInfo(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
drawable=self,
|
||||
)
|
||||
|
||||
|
||||
class SelectInput(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(2),
|
||||
rq.RequestLength(),
|
||||
rq.Drawable('drawable'),
|
||||
rq.Card32('event_mask'), # rq.Set('event_mask', 4, (NotifyMask, CycleMask)),
|
||||
)
|
||||
|
||||
def select_input(self, mask):
|
||||
return SelectInput(display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
drawable=self,
|
||||
event_mask=mask,
|
||||
)
|
||||
|
||||
|
||||
class SetAttributes(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(3),
|
||||
rq.RequestLength(),
|
||||
rq.Drawable('drawable'),
|
||||
rq.Int16('x'),
|
||||
rq.Int16('y'),
|
||||
rq.Card16('width'),
|
||||
rq.Card16('height'),
|
||||
rq.Card16('border_width'),
|
||||
rq.Set('window_class', 1, (X.CopyFromParent, X.InputOutput, X.InputOnly)),
|
||||
rq.Card8('depth'),
|
||||
rq.Card32('visual'),
|
||||
structs.WindowValues('attrs'),
|
||||
)
|
||||
|
||||
def set_attributes(self, x, y, width, height, border_width,
|
||||
window_class = X.CopyFromParent,
|
||||
depth = X.CopyFromParent,
|
||||
visual = X.CopyFromParent,
|
||||
onerror = None,
|
||||
**keys):
|
||||
return SetAttributes(display=self.display,
|
||||
onerror = onerror,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
drawable=self,
|
||||
x = x,
|
||||
y = y,
|
||||
width = width,
|
||||
height = height,
|
||||
border_width = border_width,
|
||||
window_class = window_class,
|
||||
depth = depth,
|
||||
visual = visual,
|
||||
attrs = keys)
|
||||
|
||||
|
||||
class UnsetAttributes(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(4),
|
||||
rq.RequestLength(),
|
||||
rq.Drawable('drawable'),
|
||||
)
|
||||
|
||||
def unset_attributes(self, onerror = None):
|
||||
return UnsetAttributes(display=self.display,
|
||||
onerror = onerror,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
drawable=self)
|
||||
|
||||
|
||||
class Notify(rq.Event):
|
||||
_code = None
|
||||
_fields = rq.Struct(
|
||||
rq.Card8('type'),
|
||||
rq.Set('state', 1, (StateOff, StateOn, StateCycle)),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.Card32('timestamp'),
|
||||
rq.Window('root'),
|
||||
rq.Window('window'),
|
||||
rq.Set('kind', 1, (KindBlanked, KindInternal, KindExternal)),
|
||||
rq.Bool('forced'),
|
||||
rq.Pad(14),
|
||||
)
|
||||
|
||||
def init(disp, info):
|
||||
disp.extension_add_method('display', 'screensaver_query_version', query_version)
|
||||
disp.extension_add_method('drawable', 'screensaver_query_info', query_info)
|
||||
disp.extension_add_method('drawable', 'screensaver_select_input', select_input)
|
||||
disp.extension_add_method('drawable', 'screensaver_set_attributes', set_attributes)
|
||||
disp.extension_add_method('drawable', 'screensaver_unset_attributes', unset_attributes)
|
||||
|
||||
disp.extension_add_event(info.first_event + 0, Notify)
|
|
@ -22,13 +22,25 @@
|
|||
|
||||
'''
|
||||
A partial implementation of the XFIXES extension. Only the HideCursor and
|
||||
ShowCursor requests are provided.
|
||||
ShowCursor requests and SelectionNotify events are provided.
|
||||
'''
|
||||
|
||||
from Xlib.protocol import rq
|
||||
|
||||
extname = 'XFIXES'
|
||||
|
||||
XFixesSelectionNotify = 0
|
||||
XFixesCursorNotify = 1
|
||||
|
||||
XFixesSetSelectionOwnerNotifyMask = (1 << 0)
|
||||
XFixesSelectionWindowDestroyNotifyMask = (1 << 1)
|
||||
XFixesSelectionClientCloseNotifyMask = (1 << 2)
|
||||
XFixesDisplayCursorNotifyMask = (1 << 0)
|
||||
|
||||
XFixesSetSelectionOwnerNotify = 0
|
||||
XFixesSelectionWindowDestroyNotify = 1
|
||||
XFixesSelectionClientCloseNotify = 2
|
||||
XFixesDisplayCursorNotify = 0
|
||||
|
||||
class QueryVersion(rq.ReplyRequest):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
|
@ -80,8 +92,109 @@ def show_cursor(self):
|
|||
opcode=self.display.get_extension_major(extname),
|
||||
window=self)
|
||||
|
||||
class SelectSelectionInput(rq.Request):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(2),
|
||||
rq.RequestLength(),
|
||||
rq.Window('window'),
|
||||
rq.Card32('selection'),
|
||||
rq.Card32('mask')
|
||||
)
|
||||
|
||||
def select_selection_input(self, window, selection, mask):
|
||||
return SelectSelectionInput(opcode=self.display.get_extension_major(extname),
|
||||
display=self.display,
|
||||
window=window,
|
||||
selection=selection,
|
||||
mask=mask)
|
||||
|
||||
|
||||
class SelectionNotify(rq.Event):
|
||||
_code = None
|
||||
_fields = rq.Struct(rq.Card8('type'),
|
||||
rq.Card8('sub_code'),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.Window('window'),
|
||||
rq.Window('owner'),
|
||||
rq.Card32('selection'),
|
||||
rq.Card32('timestamp'),
|
||||
rq.Card32('selection_timestamp'),
|
||||
rq.Pad(8))
|
||||
|
||||
|
||||
class SetSelectionOwnerNotify(SelectionNotify):
|
||||
pass
|
||||
|
||||
|
||||
class SelectionWindowDestroyNotify(SelectionNotify):
|
||||
pass
|
||||
|
||||
|
||||
class SelectionClientCloseNotify(SelectionNotify):
|
||||
pass
|
||||
|
||||
|
||||
class SelectCursorInput(rq.Request):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(3),
|
||||
rq.RequestLength(),
|
||||
rq.Window('window'),
|
||||
rq.Card32('mask')
|
||||
)
|
||||
|
||||
def select_cursor_input(self, window, mask):
|
||||
return SelectCursorInput(opcode=self.display.get_extension_major(extname),
|
||||
display=self.display,
|
||||
window=window,
|
||||
cursor_serial=0,
|
||||
mask=mask)
|
||||
|
||||
|
||||
class GetCursorImage(rq.ReplyRequest):
|
||||
_request = rq.Struct(rq.Card8('opcode'),
|
||||
rq.Opcode(4),
|
||||
rq.RequestLength()
|
||||
)
|
||||
_reply = rq.Struct(rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Int16('x'),
|
||||
rq.Int16('y'),
|
||||
rq.Card16('width'),
|
||||
rq.Card16('height'),
|
||||
rq.Card16('xhot'),
|
||||
rq.Card16('yhot'),
|
||||
rq.Card32('cursor_serial'),
|
||||
rq.Pad(8),
|
||||
rq.List('cursor_image', rq.Card32)
|
||||
)
|
||||
|
||||
def get_cursor_image(self, window):
|
||||
return GetCursorImage(opcode=self.display.get_extension_major(extname),
|
||||
display=self.display,
|
||||
)
|
||||
|
||||
|
||||
class DisplayCursorNotify(rq.Event):
|
||||
_code = None
|
||||
_fields = rq.Struct(rq.Card8('type'),
|
||||
rq.Card8('sub_code'),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.Window('window'),
|
||||
rq.Card32('cursor_serial'),
|
||||
rq.Card32('timestamp'))
|
||||
|
||||
|
||||
def init(disp, info):
|
||||
disp.extension_add_method('display', 'xfixes_select_selection_input', select_selection_input)
|
||||
disp.extension_add_method('display', 'xfixes_query_version', query_version)
|
||||
disp.extension_add_method('window', 'xfixes_hide_cursor', hide_cursor)
|
||||
disp.extension_add_method('window', 'xfixes_show_cursor', show_cursor)
|
||||
disp.extension_add_method('display', 'xfixes_select_cursor_input', select_cursor_input)
|
||||
disp.extension_add_method('display', 'xfixes_get_cursor_image', get_cursor_image)
|
||||
|
||||
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSetSelectionOwnerNotify, SetSelectionOwnerNotify)
|
||||
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSelectionWindowDestroyNotify, SelectionWindowDestroyNotify)
|
||||
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSelectionClientCloseNotify, SelectionClientCloseNotify)
|
||||
disp.extension_add_subevent(info.first_event + XFixesCursorNotify, XFixesDisplayCursorNotify, DisplayCursorNotify)
|
||||
|
|
|
@ -30,12 +30,11 @@ provide code for the lone Sun 1.0 request that isn't part of 1.1, but
|
|||
this is untested because I don't have a server that implements it.
|
||||
|
||||
The functions loosely follow the libXineram functions. Mostly, they
|
||||
return an rq.Struct in lieue of passing in pointers that get data from
|
||||
return an rq.Struct in lieu of passing in pointers that get data from
|
||||
the rq.Struct crammed into them. The exception is isActive, which
|
||||
returns the state information - because that's what libXinerama does."""
|
||||
|
||||
|
||||
from Xlib import X
|
||||
from Xlib.protocol import rq, structs
|
||||
|
||||
extname = 'XINERAMA'
|
||||
|
|
|
@ -158,6 +158,8 @@ DEVICEID = rq.Card16
|
|||
DEVICE = rq.Card16
|
||||
DEVICEUSE = rq.Card8
|
||||
|
||||
PROPERTY_TYPE_FLOAT = 'FLOAT'
|
||||
|
||||
class FP1616(rq.Int32):
|
||||
|
||||
def check_value(self, value):
|
||||
|
@ -236,7 +238,7 @@ class Mask(rq.List):
|
|||
else:
|
||||
mask_seq.extend(val)
|
||||
|
||||
return mask_seq.tostring(), len(mask_seq), None
|
||||
return rq.encode_array(mask_seq), len(mask_seq), None
|
||||
|
||||
EventMask = rq.Struct(
|
||||
DEVICE('deviceid'),
|
||||
|
@ -426,6 +428,114 @@ def query_device(self, deviceid):
|
|||
deviceid=deviceid,
|
||||
)
|
||||
|
||||
class XIListProperties(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(56),
|
||||
rq.RequestLength(),
|
||||
DEVICEID('deviceid'),
|
||||
rq.Pad(2),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.LengthOf('atoms', 2),
|
||||
rq.Pad(22),
|
||||
rq.List('atoms', rq.Card32Obj),
|
||||
)
|
||||
|
||||
def list_device_properties(self, deviceid):
|
||||
return XIListProperties(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
deviceid=deviceid,
|
||||
)
|
||||
|
||||
class XIGetProperty(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(59),
|
||||
rq.RequestLength(),
|
||||
DEVICEID('deviceid'),
|
||||
rq.Card8('delete'),
|
||||
rq.Pad(1),
|
||||
rq.Card32('property'),
|
||||
rq.Card32('type'),
|
||||
rq.Card32('offset'),
|
||||
rq.Card32('length'),
|
||||
)
|
||||
|
||||
_reply = rq.Struct(
|
||||
rq.ReplyCode(),
|
||||
rq.Pad(1),
|
||||
rq.Card16('sequence_number'),
|
||||
rq.ReplyLength(),
|
||||
rq.Card32('type'),
|
||||
rq.Card32('bytes_after'),
|
||||
rq.LengthOf('value', 4),
|
||||
rq.Format('value', 1),
|
||||
rq.Pad(11),
|
||||
rq.PropertyData('value')
|
||||
)
|
||||
|
||||
def get_device_property(self, deviceid, property, type, offset, length, delete=False):
|
||||
return XIGetProperty(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
deviceid=deviceid,
|
||||
property=property,
|
||||
type=type,
|
||||
offset=offset,
|
||||
length=length,
|
||||
delete=delete,
|
||||
)
|
||||
|
||||
class XIChangeProperty(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(57),
|
||||
rq.RequestLength(),
|
||||
DEVICEID('deviceid'),
|
||||
rq.Card8('mode'),
|
||||
rq.Format('value', 1),
|
||||
rq.Card32('property'),
|
||||
rq.Card32('type'),
|
||||
rq.LengthOf('value', 4),
|
||||
rq.PropertyData('value'),
|
||||
)
|
||||
|
||||
def change_device_property(self, deviceid, property, type, mode, value):
|
||||
return XIChangeProperty(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
deviceid=deviceid,
|
||||
property=property,
|
||||
type=type,
|
||||
mode=mode,
|
||||
value=value,
|
||||
)
|
||||
|
||||
class XIDeleteProperty(rq.Request):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
rq.Opcode(58),
|
||||
rq.RequestLength(),
|
||||
DEVICEID('deviceid'),
|
||||
rq.Pad(2),
|
||||
rq.Card32('property'),
|
||||
)
|
||||
|
||||
def delete_device_property(self, deviceid, property):
|
||||
return XIDeleteProperty(
|
||||
display=self.display,
|
||||
opcode=self.display.get_extension_major(extname),
|
||||
deviceid=deviceid,
|
||||
property=property,
|
||||
)
|
||||
|
||||
class XIGrabDevice(rq.ReplyRequest):
|
||||
_request = rq.Struct(
|
||||
rq.Card8('opcode'),
|
||||
|
@ -639,6 +749,14 @@ DeviceChangedEventData = rq.Struct(
|
|||
rq.List('classes', ClassInfo),
|
||||
)
|
||||
|
||||
PropertyEventData = rq.Struct(
|
||||
DEVICEID('deviceid'),
|
||||
rq.Card32('time'),
|
||||
rq.Card32('property'),
|
||||
rq.Card8('what'),
|
||||
rq.Pad(11),
|
||||
)
|
||||
|
||||
def init(disp, info):
|
||||
disp.extension_add_method('display', 'xinput_query_version', query_version)
|
||||
disp.extension_add_method('window', 'xinput_select_events', select_events)
|
||||
|
@ -647,8 +765,13 @@ def init(disp, info):
|
|||
disp.extension_add_method('display', 'xinput_ungrab_device', ungrab_device)
|
||||
disp.extension_add_method('window', 'xinput_grab_keycode', grab_keycode)
|
||||
disp.extension_add_method('window', 'xinput_ungrab_keycode', ungrab_keycode)
|
||||
|
||||
for device_event in (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion):
|
||||
disp.ge_add_event_data(info.major_opcode, device_event, DeviceEventData)
|
||||
disp.ge_add_event_data(info.major_opcode, DeviceChanged, DeviceEventData)
|
||||
disp.ge_add_event_data(info.major_opcode, HierarchyChanged, HierarchyEventData)
|
||||
disp.extension_add_method('display', 'xinput_get_device_property', get_device_property)
|
||||
disp.extension_add_method('display', 'xinput_list_device_properties', list_device_properties)
|
||||
disp.extension_add_method('display', 'xinput_change_device_property', change_device_property)
|
||||
disp.extension_add_method('display', 'xinput_delete_device_property', delete_device_property)
|
||||
if hasattr(disp,"ge_add_event_data"):
|
||||
for device_event in (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion):
|
||||
disp.ge_add_event_data(info.major_opcode, device_event, DeviceEventData)
|
||||
disp.ge_add_event_data(info.major_opcode, DeviceChanged, DeviceEventData)
|
||||
disp.ge_add_event_data(info.major_opcode, HierarchyChanged, HierarchyEventData)
|
||||
disp.ge_add_event_data(info.major_opcode, PropertyEvent, PropertyEventData)
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
XK_XF86_MonBrightnessUp = 0x1008FF02
|
||||
XK_XF86_MonBrightnessDown = 0x1008FF03
|
||||
XK_XF86_KbdLightOnOff = 0x1008FF04
|
||||
XK_XF86_KbdBrightnessUp = 0x1008FF05
|
||||
XK_XF86_KbdBrightnessDown = 0x1008FF06
|
||||
XK_XF86_ModeLock = 0x1008FF01
|
||||
|
||||
XK_XF86_MonBrightnessUp = 0x1008FF02
|
||||
XK_XF86_MonBrightnessDown = 0x1008FF03
|
||||
XK_XF86_KbdLightOnOff = 0x1008FF04
|
||||
XK_XF86_KbdBrightnessUp = 0x1008FF05
|
||||
XK_XF86_KbdBrightnessDown = 0x1008FF06
|
||||
XK_XF86_MonBrightnessCycle = 0x1008FF07
|
||||
|
||||
XK_XF86_Standby = 0x1008FF10
|
||||
XK_XF86_AudioLowerVolume = 0x1008FF11
|
||||
|
@ -159,6 +162,25 @@ XK_XF86_Green = 0x1008FFA4
|
|||
XK_XF86_Yellow = 0x1008FFA5
|
||||
XK_XF86_Blue = 0x1008FFA6
|
||||
|
||||
XK_XF86_Suspend = 0x1008FFA7
|
||||
XK_XF86_Hibernate = 0x1008FFA8
|
||||
XK_XF86_TouchpadToggle = 0x1008FFA9
|
||||
XK_XF86_TouchpadOn = 0x1008FFB0
|
||||
XK_XF86_TouchpadOff = 0x1008FFB1
|
||||
|
||||
XK_XF86_AudioMicMute = 0x1008FFB2
|
||||
|
||||
XK_XF86_Keyboard = 0x1008FFB3
|
||||
|
||||
XK_XF86_WWAN = 0x1008FFB4
|
||||
XK_XF86_RFKill = 0x1008FFB5
|
||||
|
||||
XK_XF86_AudioPreset = 0x1008FFB6
|
||||
|
||||
XK_XF86_RotationLockToggle = 0x1008FFB7
|
||||
|
||||
XK_XF86_FullScreen = 0x1008FFB8
|
||||
|
||||
XK_XF86_Switch_VT_1 = 0x1008FE01
|
||||
XK_XF86_Switch_VT_2 = 0x1008FE02
|
||||
XK_XF86_Switch_VT_3 = 0x1008FE03
|
||||
|
@ -176,3 +198,5 @@ XK_XF86_Ungrab = 0x1008FE20
|
|||
XK_XF86_ClearGrab = 0x1008FE21
|
||||
XK_XF86_Next_VMode = 0x1008FE22
|
||||
XK_XF86_Prev_VMode = 0x1008FE23
|
||||
XK_XF86_LogWindowTree = 0x1008FE24
|
||||
XK_XF86_LogGrabInfo = 0x1008FE25
|
||||
|
|
|
@ -76,7 +76,6 @@ else:
|
|||
|
||||
|
||||
class Display(object):
|
||||
resource_classes = {}
|
||||
extension_major_opcodes = {}
|
||||
error_classes = error.xerror_class.copy()
|
||||
event_classes = event.event_class.copy()
|
||||
|
@ -89,8 +88,8 @@ class Display(object):
|
|||
|
||||
self.socket = connect.get_socket(name, protocol, host, displayno)
|
||||
|
||||
auth_name, auth_data = connect.get_auth(self.socket,
|
||||
name, host, displayno)
|
||||
auth_name, auth_data = connect.get_auth(self.socket, name,
|
||||
protocol, host, displayno)
|
||||
|
||||
# Internal structures for communication, grouped
|
||||
# by their function and locks
|
||||
|
@ -110,7 +109,7 @@ class Display(object):
|
|||
self.request_serial = 1
|
||||
self.request_queue = []
|
||||
|
||||
# Send-and-recieve loop, see function send_and_recive
|
||||
# Send-and-receive loop, see function send_and_receive
|
||||
# for a detailed explanation
|
||||
self.send_recv_lock = lock.allocate_lock()
|
||||
self.send_active = 0
|
||||
|
@ -127,7 +126,7 @@ class Display(object):
|
|||
buffer_size = math.pow(2, math.floor(math.log(buffer_size, 2)))
|
||||
self.recv_buffer_size = int(buffer_size)
|
||||
|
||||
# Data used by the send-and-recieve loop
|
||||
# Data used by the send-and-receive loop
|
||||
self.sent_requests = []
|
||||
self.recv_packet_len = 0
|
||||
self.data_send = b''
|
||||
|
@ -146,7 +145,7 @@ class Display(object):
|
|||
# Right, now we're all set up for the connection setup
|
||||
# request with the server.
|
||||
|
||||
# Figure out which endianess the hardware uses
|
||||
# Figure out which endianness the hardware uses
|
||||
self.big_endian = struct.unpack('BB', struct.pack('H', 0x0100))[0]
|
||||
|
||||
if self.big_endian:
|
||||
|
@ -204,7 +203,7 @@ class Display(object):
|
|||
|
||||
while not self.event_queue:
|
||||
|
||||
# Lock send_recv so no send_and_recieve
|
||||
# Lock send_recv so no send_and_receive
|
||||
# can start or stop while we're checking
|
||||
# whether there are one active.
|
||||
self.send_recv_lock.acquire()
|
||||
|
@ -215,7 +214,7 @@ class Display(object):
|
|||
|
||||
# Call send_and_recv, which will return when
|
||||
# something has occured
|
||||
self.send_and_recv(event = 1)
|
||||
self.send_and_recv(event = True)
|
||||
|
||||
# Before looping around, lock the event queue against
|
||||
# modifications.
|
||||
|
@ -241,7 +240,7 @@ class Display(object):
|
|||
|
||||
# Make a send_and_recv pass, receiving any events
|
||||
self.send_recv_lock.acquire()
|
||||
self.send_and_recv(recv = 1)
|
||||
self.send_and_recv(recv = True)
|
||||
|
||||
# Lock the queue, get the event count, and unlock again.
|
||||
self.event_queue_write_lock.acquire()
|
||||
|
@ -253,7 +252,7 @@ class Display(object):
|
|||
def flush(self):
|
||||
self.check_for_error()
|
||||
self.send_recv_lock.acquire()
|
||||
self.send_and_recv(flush = 1)
|
||||
self.send_and_recv(flush = True)
|
||||
|
||||
def close(self):
|
||||
self.flush()
|
||||
|
@ -385,7 +384,7 @@ class Display(object):
|
|||
self.socket_error_lock.release()
|
||||
|
||||
|
||||
def send_and_recv(self, flush = None, event = None, request = None, recv = None):
|
||||
def send_and_recv(self, flush = False, event = False, request = None, recv = False):
|
||||
"""send_and_recv(flush = None, event = None, request = None, recv = None)
|
||||
|
||||
Perform I/O, or wait for some other thread to do it for us.
|
||||
|
@ -400,10 +399,10 @@ class Display(object):
|
|||
be true. Will return immediately if another thread is
|
||||
already doing send_and_recv.
|
||||
|
||||
To wait for an event to be recieved, event should be true.
|
||||
To wait for an event to be received, event should be true.
|
||||
|
||||
To wait for a response to a certain request (either an error
|
||||
or a response), request should be set the that request's
|
||||
or a response), request should be set to that request's
|
||||
serial number.
|
||||
|
||||
To just read any pending data from the server, recv should be true.
|
||||
|
@ -485,19 +484,19 @@ class Display(object):
|
|||
# There's no thread doing what we need to do. Find out exactly
|
||||
# what to do
|
||||
|
||||
# There must always be some thread recieving data, but it must not
|
||||
# There must always be some thread receiving data, but it must not
|
||||
# necessarily be us
|
||||
|
||||
if not self.recv_active:
|
||||
recieving = 1
|
||||
receiving = 1
|
||||
self.recv_active = 1
|
||||
else:
|
||||
recieving = 0
|
||||
receiving = 0
|
||||
|
||||
flush_bytes = None
|
||||
sending = 0
|
||||
|
||||
# Loop, recieving and sending data.
|
||||
# Loop, receiving and sending data.
|
||||
while 1:
|
||||
|
||||
# We might want to start sending data
|
||||
|
@ -529,7 +528,7 @@ class Display(object):
|
|||
self.send_recv_lock.release()
|
||||
|
||||
# There's no longer anything useful we can do here.
|
||||
if not (sending or recieving):
|
||||
if not (sending or receiving):
|
||||
break
|
||||
|
||||
# If we're flushing, figure out how many bytes we
|
||||
|
@ -542,9 +541,9 @@ class Display(object):
|
|||
try:
|
||||
# We're only checking for the socket to be writable
|
||||
# if we're the sending thread. We always check for it
|
||||
# to become readable: either we are the recieving thread
|
||||
# and should take care of the data, or the recieving thread
|
||||
# might finish recieving after having read the data
|
||||
# to become readable: either we are the receiving thread
|
||||
# and should take care of the data, or the receiving thread
|
||||
# might finish receiving after having read the data
|
||||
|
||||
if sending:
|
||||
writeset = [self.socket]
|
||||
|
@ -561,7 +560,7 @@ class Display(object):
|
|||
|
||||
rs, ws, es = select.select([self.socket], writeset, [], timeout)
|
||||
|
||||
# Ignore errors caused by a signal recieved while blocking.
|
||||
# Ignore errors caused by a signal received while blocking.
|
||||
# All other errors are re-raised.
|
||||
except select.error as err:
|
||||
if isinstance(err, OSError):
|
||||
|
@ -583,7 +582,7 @@ class Display(object):
|
|||
try:
|
||||
i = self.socket.send(self.data_send)
|
||||
except socket.error as err:
|
||||
self.close_internal('server: %s' % err[1])
|
||||
self.close_internal('server: %s' % err)
|
||||
raise self.socket_error
|
||||
|
||||
self.data_send = self.data_send[i:]
|
||||
|
@ -594,14 +593,14 @@ class Display(object):
|
|||
gotreq = 0
|
||||
if rs:
|
||||
|
||||
# We're the recieving thread, parse the data
|
||||
if recieving:
|
||||
# We're the receiving thread, parse the data
|
||||
if receiving:
|
||||
try:
|
||||
count = self.recv_packet_len - len(self.data_recv)
|
||||
count = max(self.recv_buffer_size, count)
|
||||
bytes_recv = self.socket.recv(count)
|
||||
except socket.error as err:
|
||||
self.close_internal('server: %s' % err[1])
|
||||
self.close_internal('server: %s' % err)
|
||||
raise self.socket_error
|
||||
|
||||
if not bytes_recv:
|
||||
|
@ -627,7 +626,7 @@ class Display(object):
|
|||
|
||||
# There are three different end of send-recv-loop conditions.
|
||||
# However, we don't leave the loop immediately, instead we
|
||||
# try to send and recieve any data that might be left. We
|
||||
# try to send and receive any data that might be left. We
|
||||
# do this by giving a timeout of 0 to select to poll
|
||||
# the socket.
|
||||
|
||||
|
@ -643,7 +642,7 @@ class Display(object):
|
|||
if request is not None and gotreq:
|
||||
break
|
||||
|
||||
# Always break if we just want to recieve as much as possible
|
||||
# Always break if we just want to receive as much as possible
|
||||
if recv:
|
||||
break
|
||||
|
||||
|
@ -661,7 +660,7 @@ class Display(object):
|
|||
|
||||
if sending:
|
||||
self.send_active = 0
|
||||
if recieving:
|
||||
if receiving:
|
||||
self.recv_active = 0
|
||||
|
||||
if self.event_waiting:
|
||||
|
@ -678,9 +677,9 @@ class Display(object):
|
|||
def parse_response(self, request):
|
||||
"""Internal method.
|
||||
|
||||
Parse data recieved from server. If REQUEST is not None
|
||||
Parse data received from server. If REQUEST is not None
|
||||
true is returned if the request with that serial number
|
||||
was recieved, otherwise false is returned.
|
||||
was received, otherwise false is returned.
|
||||
|
||||
If REQUEST is -1, we're parsing the server connection setup
|
||||
response.
|
||||
|
@ -690,8 +689,8 @@ class Display(object):
|
|||
return self.parse_connection_setup()
|
||||
|
||||
# Parse ordinary server response
|
||||
gotreq = 0
|
||||
while 1:
|
||||
gotreq = False
|
||||
while True:
|
||||
if self.data_recv:
|
||||
# Check the first byte to find out what kind of response it is
|
||||
rtype = byte2int(self.data_recv)
|
||||
|
@ -711,11 +710,11 @@ class Display(object):
|
|||
raise AssertionError(rtype)
|
||||
|
||||
# Every response is at least 32 bytes long, so don't bother
|
||||
# until we have recieved that much
|
||||
# until we have received that much
|
||||
if len(self.data_recv) < 32:
|
||||
return gotreq
|
||||
|
||||
# Error resposne
|
||||
# Error response
|
||||
if rtype == 0:
|
||||
gotreq = self.parse_error_response(request) or gotreq
|
||||
|
||||
|
@ -773,7 +772,7 @@ class Display(object):
|
|||
else:
|
||||
self.default_error_handler(e)
|
||||
|
||||
return 0
|
||||
return False
|
||||
|
||||
|
||||
def default_error_handler(self, err):
|
||||
|
@ -822,8 +821,14 @@ class Display(object):
|
|||
|
||||
estruct = self.event_classes.get(etype, event.AnyEvent)
|
||||
if type(estruct) == dict:
|
||||
subcode = self.data_recv[1]
|
||||
|
||||
# Python2 compatibility
|
||||
if type(subcode) == str:
|
||||
subcode = ord(subcode)
|
||||
|
||||
# this etype refers to a set of sub-events with individual subcodes
|
||||
estruct = estruct[ord(self.data_recv[1])]
|
||||
estruct = estruct[subcode]
|
||||
|
||||
e = estruct(display = self, binarydata = self.data_recv[:length])
|
||||
|
||||
|
@ -932,7 +937,7 @@ class Display(object):
|
|||
# Only the ConnectionSetupRequest has been sent so far
|
||||
r = self.sent_requests[0]
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
# print 'data_send:', repr(self.data_send)
|
||||
# print 'data_recv:', repr(self.data_recv)
|
||||
|
||||
|
@ -941,7 +946,7 @@ class Display(object):
|
|||
|
||||
# The full response haven't arrived yet
|
||||
if len(self.data_recv) < alen:
|
||||
return 0
|
||||
return False
|
||||
|
||||
# Connection failed or further authentication is needed.
|
||||
# Set reason to the reason string
|
||||
|
@ -951,22 +956,22 @@ class Display(object):
|
|||
# Else connection succeeded, parse the reply
|
||||
else:
|
||||
x, d = r._success_reply.parse_binary(self.data_recv[:alen],
|
||||
self, rawdict = 1)
|
||||
self, rawdict = True)
|
||||
r._data.update(x)
|
||||
|
||||
del self.sent_requests[0]
|
||||
|
||||
self.data_recv = self.data_recv[alen:]
|
||||
|
||||
return 1
|
||||
return True
|
||||
|
||||
else:
|
||||
# The base reply is 8 bytes long
|
||||
if len(self.data_recv) < 8:
|
||||
return 0
|
||||
return False
|
||||
|
||||
r._data, d = r._reply.parse_binary(self.data_recv[:8],
|
||||
self, rawdict = 1)
|
||||
self, rawdict = True)
|
||||
self.data_recv = self.data_recv[8:]
|
||||
|
||||
# Loop around to see if we have got the additional data
|
||||
|
@ -1061,7 +1066,7 @@ class ConnectionSetupRequest(rq.GetAttrData):
|
|||
# Don't bother about locking, since no other threads have
|
||||
# access to the display yet
|
||||
|
||||
display.request_queue.append((self, 1))
|
||||
display.request_queue.append((self, True))
|
||||
|
||||
# However, we must lock send_and_recv, but we don't have
|
||||
# to loop.
|
||||
|
|
|
@ -1640,7 +1640,8 @@ class ChangeHosts(rq.Request):
|
|||
rq.Opcode(109),
|
||||
rq.Set('mode', 1, (X.HostInsert, X.HostDelete)),
|
||||
rq.RequestLength(),
|
||||
rq.Set('host_family', 1, (X.FamilyInternet, X.FamilyDECnet, X.FamilyChaos)),
|
||||
rq.Set('host_family', 1, (X.FamilyInternet, X.FamilyDECnet, X.FamilyChaos,
|
||||
X.FamilyServerInterpreted, X.FamilyInternetV6)),
|
||||
rq.Pad(1),
|
||||
rq.LengthOf('host', 2),
|
||||
rq.List('host', rq.Card8Obj)
|
||||
|
|
|
@ -24,7 +24,6 @@ import sys
|
|||
import traceback
|
||||
import struct
|
||||
from array import array
|
||||
import types
|
||||
|
||||
# Python 2/3 compatibility.
|
||||
from six import PY3, binary_type, byte2int, indexbytes, iterbytes
|
||||
|
@ -119,7 +118,7 @@ class Field(object):
|
|||
check_value = None
|
||||
parse_value = None
|
||||
|
||||
keyword_args = 0
|
||||
keyword_args = False
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
@ -724,7 +723,7 @@ class FixedPropertyData(PropertyData):
|
|||
|
||||
class ValueList(Field):
|
||||
structcode = None
|
||||
keyword_args = 1
|
||||
keyword_args = True
|
||||
default = 'usekeywords'
|
||||
|
||||
def __init__(self, name, mask, pad, *fields):
|
||||
|
@ -1058,7 +1057,7 @@ class Struct(object):
|
|||
pack_items.append(field_args[f.name])
|
||||
|
||||
# Multivalue field. Handled like single valuefield,
|
||||
# but the value are tuple unpacked into seperate arguments
|
||||
# but the value are tuple unpacked into separate arguments
|
||||
# which are appended to pack_items
|
||||
else:
|
||||
if f.check_value is not None:
|
||||
|
@ -1089,7 +1088,7 @@ class Struct(object):
|
|||
raise BadDataError('%s is not a tuple or a list' % (value))
|
||||
|
||||
|
||||
def parse_value(self, val, display, rawdict = 0):
|
||||
def parse_value(self, val, display, rawdict = False):
|
||||
|
||||
"""This function is used by List and Object fields to convert
|
||||
Struct objects with no var_fields into Python values.
|
||||
|
@ -1132,9 +1131,9 @@ class Struct(object):
|
|||
return DictWrapper(ret)
|
||||
return ret
|
||||
|
||||
def parse_binary(self, data, display, rawdict = 0):
|
||||
def parse_binary(self, data, display, rawdict = False):
|
||||
|
||||
"""values, remdata = s.parse_binary(data, display, rawdict = 0)
|
||||
"""values, remdata = s.parse_binary(data, display, rawdict = False)
|
||||
|
||||
Convert a binary representation of the structure into Python values.
|
||||
|
||||
|
@ -1221,7 +1220,7 @@ class TextElements8(ValueField):
|
|||
|
||||
for v in value:
|
||||
# Let values be simple strings, meaning a delta of 0
|
||||
if type(v) is bytes:
|
||||
if type(v) in (str, bytes):
|
||||
v = (0, v)
|
||||
|
||||
# A tuple, it should be (delta, string)
|
||||
|
@ -1230,19 +1229,19 @@ class TextElements8(ValueField):
|
|||
if isinstance(v, (tuple, dict, DictWrapper)):
|
||||
|
||||
if isinstance(v, tuple):
|
||||
delta, str = v
|
||||
delta, m_str = v
|
||||
else:
|
||||
delta = v['delta']
|
||||
str = v['string']
|
||||
m_str = v['string']
|
||||
|
||||
while delta or str:
|
||||
while delta or m_str:
|
||||
args['delta'] = delta
|
||||
args['string'] = str[:254]
|
||||
args['string'] = m_str[:254]
|
||||
|
||||
data = data + self.string_textitem.to_binary(*(), **args)
|
||||
|
||||
delta = 0
|
||||
str = str[254:]
|
||||
m_str = m_str[254:]
|
||||
|
||||
# Else an integer, i.e. a font change
|
||||
else:
|
||||
|
@ -1320,7 +1319,7 @@ class DictWrapper(GetAttrData):
|
|||
return str(self._data)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__, repr(self._data))
|
||||
return '%s(%s)' % (self.__class__.__name__, repr(self._data))
|
||||
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, DictWrapper):
|
||||
|
@ -1355,7 +1354,7 @@ class Request(object):
|
|||
return 0
|
||||
|
||||
class ReplyRequest(GetAttrData):
|
||||
def __init__(self, display, defer = 0, *args, **keys):
|
||||
def __init__(self, display, defer = False, *args, **keys):
|
||||
self._display = display
|
||||
self._binary = self._request.to_binary(*args, **keys)
|
||||
self._serial = None
|
||||
|
@ -1364,7 +1363,7 @@ class ReplyRequest(GetAttrData):
|
|||
|
||||
self._response_lock = lock.allocate_lock()
|
||||
|
||||
self._display.send_request(self, 1)
|
||||
self._display.send_request(self, True)
|
||||
if not defer:
|
||||
self.reply()
|
||||
|
||||
|
@ -1390,7 +1389,7 @@ class ReplyRequest(GetAttrData):
|
|||
|
||||
def _parse_response(self, data):
|
||||
self._response_lock.acquire()
|
||||
self._data, d = self._reply.parse_binary(data, self._display, rawdict = 1)
|
||||
self._data, d = self._reply.parse_binary(data, self._display, rawdict = True)
|
||||
self._response_lock.release()
|
||||
|
||||
def _set_error(self, error):
|
||||
|
@ -1400,7 +1399,7 @@ class ReplyRequest(GetAttrData):
|
|||
return 1
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s serial = %s, data = %s, error = %s>' % (self.__class__, self._serial, self._data, self._error)
|
||||
return '<%s serial = %s, data = %s, error = %s>' % (self.__class__.__name__, self._serial, self._data, self._error)
|
||||
|
||||
|
||||
class Event(GetAttrData):
|
||||
|
@ -1409,7 +1408,7 @@ class Event(GetAttrData):
|
|||
if binarydata:
|
||||
self._binary = binarydata
|
||||
self._data, data = self._fields.parse_binary(binarydata, display,
|
||||
rawdict = 1)
|
||||
rawdict = True)
|
||||
# split event type into type and send_event bit
|
||||
self._data['send_event'] = not not self._data['type'] & 0x80
|
||||
self._data['type'] = self._data['type'] & 0x7f
|
||||
|
@ -1434,7 +1433,7 @@ class Event(GetAttrData):
|
|||
kwlist.append('%s = %s' % (kw, repr(val)))
|
||||
|
||||
kws = ', '.join(kwlist)
|
||||
return '%s(%s)' % (self.__class__, kws)
|
||||
return '%s(%s)' % (self.__class__.__name__, kws)
|
||||
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, Event):
|
||||
|
|
|
@ -699,7 +699,7 @@ stdopts = {'-bg': SepArg('*background'),
|
|||
# the resource object.
|
||||
|
||||
# Example: Inserting "foo.bar*gazonk: yep" into an otherwise empty
|
||||
# resource database would give the folliwing structure:
|
||||
# resource database would give the following structure:
|
||||
|
||||
# { 'foo': ( { 'bar': ( { },
|
||||
# { 'gazonk': ( { },
|
||||
|
|
|
@ -87,11 +87,11 @@ def get_socket(dname, protocol, host, dno):
|
|||
return mod.get_socket(dname, protocol, host, dno)
|
||||
|
||||
|
||||
def get_auth(sock, dname, host, dno):
|
||||
"""auth_name, auth_data = get_auth(sock, dname, host, dno)
|
||||
def get_auth(sock, dname, protocol, host, dno):
|
||||
"""auth_name, auth_data = get_auth(sock, dname, protocol, host, dno)
|
||||
|
||||
Return authentication data for the display on the other side of
|
||||
SOCK, which was opened with DNAME, HOST and DNO.
|
||||
SOCK, which was opened with DNAME, HOST and DNO, using PROTOCOL.
|
||||
|
||||
Return AUTH_NAME and AUTH_DATA, two strings to be used in the
|
||||
connection setup request.
|
||||
|
@ -99,4 +99,4 @@ def get_auth(sock, dname, host, dno):
|
|||
|
||||
modname = _auth_mods.get(platform, _default_auth_mod)
|
||||
mod = _relative_import(modname)
|
||||
return mod.get_auth(sock, dname, host, dno)
|
||||
return mod.get_auth(sock, dname, protocol, host, dno)
|
||||
|
|
|
@ -23,55 +23,52 @@ import re
|
|||
import os
|
||||
import platform
|
||||
import socket
|
||||
|
||||
# FCNTL is deprecated from Python 2.2, so only import it if we doesn't
|
||||
# get the names we need. Furthermore, FD_CLOEXEC seems to be missing
|
||||
# in Python 2.2.
|
||||
|
||||
import fcntl
|
||||
|
||||
if hasattr(fcntl, 'F_SETFD'):
|
||||
F_SETFD = fcntl.F_SETFD
|
||||
if hasattr(fcntl, 'FD_CLOEXEC'):
|
||||
FD_CLOEXEC = fcntl.FD_CLOEXEC
|
||||
else:
|
||||
FD_CLOEXEC = 1
|
||||
else:
|
||||
from FCNTL import F_SETFD, FD_CLOEXEC
|
||||
|
||||
|
||||
from Xlib import error, xauth
|
||||
|
||||
|
||||
SUPPORTED_PROTOCOLS = (None, 'tcp', 'unix')
|
||||
|
||||
# Darwin funky socket.
|
||||
uname = platform.uname()
|
||||
if (uname[0] == 'Darwin') and ([int(x) for x in uname[2].split('.')] >= [9, 0]):
|
||||
SUPPORTED_PROTOCOLS += ('darwin',)
|
||||
DARWIN_DISPLAY_RE = re.compile(r'^/private/tmp/[-:a-zA-Z0-9._]*:(?P<dno>[0-9]+)(\.(?P<screen>[0-9]+))?$')
|
||||
|
||||
display_re = re.compile(r'^(?P<proto>)(?P<host>[-:a-zA-Z0-9._/]*):(?P<dno>[0-9]+)(\.(?P<screen>[0-9]+))?$')
|
||||
DISPLAY_RE = re.compile(r'^((?P<proto>tcp|unix)/)?(?P<host>[-:a-zA-Z0-9._]*):(?P<dno>[0-9]+)(\.(?P<screen>[0-9]+))?$')
|
||||
|
||||
else:
|
||||
|
||||
display_re = re.compile(r'^((?P<proto>tcp|unix)/)?(?P<host>[-:a-zA-Z0-9._]*):(?P<dno>[0-9]+)(\.(?P<screen>[0-9]+))?$')
|
||||
|
||||
def get_display(display):
|
||||
# Use $DISPLAY if display isn't provided
|
||||
if display is None:
|
||||
display = os.environ.get('DISPLAY', '')
|
||||
|
||||
m = display_re.match(display)
|
||||
if not m:
|
||||
re_list = [(DISPLAY_RE, {})]
|
||||
|
||||
if 'darwin' in SUPPORTED_PROTOCOLS:
|
||||
re_list.insert(0, (DARWIN_DISPLAY_RE, {'protocol': 'darwin'}))
|
||||
|
||||
for re, defaults in re_list:
|
||||
m = re.match(display)
|
||||
if m is not None:
|
||||
protocol, host, dno, screen = [
|
||||
m.groupdict().get(field, defaults.get(field))
|
||||
for field in ('proto', 'host', 'dno', 'screen')
|
||||
]
|
||||
break
|
||||
else:
|
||||
raise error.DisplayNameError(display)
|
||||
|
||||
name = display
|
||||
protocol, host, dno, screen = m.group('proto', 'host', 'dno', 'screen')
|
||||
if protocol == 'tcp' and not host:
|
||||
# Host is mandatory when protocol is TCP.
|
||||
raise error.DisplayNameError(display)
|
||||
|
||||
dno = int(dno)
|
||||
if screen:
|
||||
screen = int(screen)
|
||||
else:
|
||||
screen = 0
|
||||
|
||||
return name, protocol, host, dno, screen
|
||||
return display, protocol, host, dno, screen
|
||||
|
||||
|
||||
def _get_tcp_socket(host, dno):
|
||||
|
@ -79,20 +76,22 @@ def _get_tcp_socket(host, dno):
|
|||
s.connect((host, 6000 + dno))
|
||||
return s
|
||||
|
||||
|
||||
def _get_unix_socket(address):
|
||||
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
s.connect(address)
|
||||
return s
|
||||
|
||||
|
||||
def get_socket(dname, protocol, host, dno):
|
||||
assert protocol in (None, 'tcp', 'unix')
|
||||
assert protocol in SUPPORTED_PROTOCOLS
|
||||
try:
|
||||
# Darwin funky socket.
|
||||
if uname[0] == 'Darwin' and host and host.startswith('/private/tmp/'):
|
||||
if protocol == 'darwin':
|
||||
s = _get_unix_socket(dname)
|
||||
|
||||
# TCP socket, note the special case: `unix:0.0` is equivalent to `:0.0`.
|
||||
elif (not protocol or protocol != 'unix') and host and host != 'unix':
|
||||
elif (protocol is None or protocol != 'unix') and host and host != 'unix':
|
||||
s = _get_tcp_socket(host, dno)
|
||||
|
||||
# Unix socket.
|
||||
|
@ -113,18 +112,45 @@ def get_socket(dname, protocol, host, dno):
|
|||
raise error.DisplayConnectionError(dname, str(val))
|
||||
|
||||
# Make sure that the connection isn't inherited in child processes.
|
||||
fcntl.fcntl(s.fileno(), F_SETFD, FD_CLOEXEC)
|
||||
_ensure_not_inheritable(s)
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def new_get_auth(sock, dname, host, dno):
|
||||
def _ensure_not_inheritable(sock):
|
||||
# According to PEP446, in Python 3.4 and above,
|
||||
# it is not inherited in child processes by default.
|
||||
# However, just in case, we explicitly make it non-inheritable.
|
||||
# Also, we don't use the code like the following,
|
||||
# because there would be no possibility of backporting to past versions.
|
||||
# if sys.version_info.major == 3 and sys.version_info.minor >= 4:
|
||||
# sock.set_inheritable(False)
|
||||
# return
|
||||
# We just check if the socket has `set_inheritable`.
|
||||
if hasattr(sock, 'set_inheritable'):
|
||||
sock.set_inheritable(False)
|
||||
return
|
||||
|
||||
# On Windows,
|
||||
# Python doesn't support fcntl module because Windows doesn't have fcntl API.
|
||||
# At least by not importing fcntl, we will be able to import python-xlib on Windows.
|
||||
if platform.system() == 'Windows':
|
||||
# so.. unfortunately, for Python 3.3 and below, on Windows,
|
||||
# we can't make sure that the connection isn't inherited in child processes for now.
|
||||
return
|
||||
|
||||
import fcntl
|
||||
fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
|
||||
|
||||
|
||||
def new_get_auth(sock, dname, protocol, host, dno):
|
||||
assert protocol in SUPPORTED_PROTOCOLS
|
||||
# Translate socket address into the xauth domain
|
||||
if (uname[0] == 'Darwin') and host and host.startswith('/private/tmp/'):
|
||||
if protocol == 'darwin':
|
||||
family = xauth.FamilyLocal
|
||||
addr = socket.gethostname()
|
||||
|
||||
elif host:
|
||||
elif protocol == 'tcp':
|
||||
family = xauth.FamilyInternet
|
||||
|
||||
# Convert the prettyprinted IP number into 4-octet string.
|
||||
|
@ -186,14 +212,6 @@ def old_get_auth(sock, dname, host, dno):
|
|||
except os.error:
|
||||
pass
|
||||
|
||||
if not auth_data and host=='localhost':
|
||||
# 127.0.0.1 counts as FamilyLocal, not FamilyInternet
|
||||
# See Xtransutil.c:ConvertAddress.
|
||||
# There might be more ways to spell 127.0.0.1 but
|
||||
# 'localhost', yet this code fixes a the case of
|
||||
# OpenSSH tunneling X.
|
||||
return get_auth('unix:%d' % dno, 'unix', dno)
|
||||
|
||||
return auth_name, auth_data
|
||||
|
||||
get_auth = new_get_auth
|
||||
|
|
|
@ -27,6 +27,8 @@ from Xlib import X, error
|
|||
FamilyInternet = X.FamilyInternet
|
||||
FamilyDECnet = X.FamilyDECnet
|
||||
FamilyChaos = X.FamilyChaos
|
||||
FamilyServerInterpreted = X.FamilyServerInterpreted
|
||||
FamilyInternetV6 = X.FamilyInternetV6
|
||||
FamilyLocal = 256
|
||||
|
||||
class Xauthority(object):
|
||||
|
@ -118,6 +120,8 @@ class Xauthority(object):
|
|||
matches = {}
|
||||
|
||||
for efam, eaddr, enum, ename, edata in self.entries:
|
||||
if enum == b'' and ename not in matches:
|
||||
enum = num
|
||||
if efam == family and eaddr == address and num == enum:
|
||||
matches[ename] = edata
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
from Xlib import X, Xatom, Xutil
|
||||
from Xlib import X, Xatom
|
||||
from Xlib.protocol import request, rq
|
||||
|
||||
# Other X resource objects
|
||||
|
@ -451,7 +451,7 @@ class Window(Drawable):
|
|||
window = self.id,
|
||||
property = property)
|
||||
|
||||
def get_property(self, property, property_type, offset, length, delete = 0):
|
||||
def get_property(self, property, property_type, offset, length, delete = False):
|
||||
r = request.GetProperty(display = self.display,
|
||||
delete = delete,
|
||||
window = self.id,
|
||||
|
@ -516,7 +516,7 @@ class Window(Drawable):
|
|||
property = property,
|
||||
time = time)
|
||||
|
||||
def send_event(self, event, event_mask = 0, propagate = 0, onerror = None):
|
||||
def send_event(self, event, event_mask = 0, propagate = False, onerror = None):
|
||||
request.SendEvent(display = self.display,
|
||||
onerror = onerror,
|
||||
propagate = propagate,
|
||||
|
@ -629,7 +629,7 @@ class Window(Drawable):
|
|||
focus = self.id,
|
||||
time = time)
|
||||
|
||||
def clear_area(self, x = 0, y = 0, width = 0, height = 0, exposures = 0, onerror = None):
|
||||
def clear_area(self, x = 0, y = 0, width = 0, height = 0, exposures = False, onerror = None):
|
||||
request.ClearArea(display = self.display,
|
||||
onerror = onerror,
|
||||
exposures = exposures,
|
||||
|
@ -779,7 +779,7 @@ class Window(Drawable):
|
|||
def _get_struct_prop(self, pname, ptype, pstruct):
|
||||
r = self.get_property(pname, ptype, 0, pstruct.static_size // 4)
|
||||
if r and r.format == 32:
|
||||
value = r.value.tostring()
|
||||
value = rq.encode_array(r.value)
|
||||
if len(value) == pstruct.static_size:
|
||||
return pstruct.parse_binary(value, self.display)[0]
|
||||
|
||||
|
|
|
@ -45,11 +45,8 @@ class Resource(object):
|
|||
def __hash__(self):
|
||||
return int(self.id)
|
||||
|
||||
def __str__(self):
|
||||
return '%s(0x%08x)' % (self.__class__, self.id)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s 0x%08x>' % (self.__class__, self.id)
|
||||
return '<%s 0x%08x>' % (self.__class__.__name__, self.id)
|
||||
|
||||
def kill_client(self, onerror = None):
|
||||
request.KillClient(display = self.display,
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
python-xlib (0.23-ok1) yangtze; urgency=medium
|
||||
python-xlib (0.8-1) unstable; urgency=low
|
||||
|
||||
* Build for openKylin.
|
||||
* Initial Release. (Closes: #105388)
|
||||
|
||||
-- openKylinBot <openKylinBot@openkylin.com> Mon, 25 Apr 2022 22:03:04 +0800
|
||||
-- Moshe Zadka <moshez@debian.org> Sun, 15 Jul 2001 13:12:01 +0300
|
||||
|
||||
Local variables:
|
||||
mode: debian-changelog
|
||||
End:
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
.eggs/*
|
|
@ -1 +0,0 @@
|
|||
9
|
|
@ -1,46 +1,13 @@
|
|||
Source: python-xlib
|
||||
Section: python
|
||||
Priority: optional
|
||||
Maintainer: Debian Python Modules Team <python-modules-team@lists.alioth.debian.org>
|
||||
Build-Depends: debhelper (>= 9),
|
||||
dh-python,
|
||||
python-all (>= 2.6.6-0),
|
||||
python-setuptools (>= 0.6.24),
|
||||
python-setuptools-scm,
|
||||
python-mock <!nocheck>,
|
||||
python-six <!nocheck>,
|
||||
python3-all,
|
||||
python3-setuptools (>= 0.6.24),
|
||||
python3-setuptools-scm,
|
||||
python3-mock <!nocheck>,
|
||||
python3-six <!nocheck>,
|
||||
texinfo,
|
||||
xauth <!nocheck>,
|
||||
xvfb <!nocheck>
|
||||
Standards-Version: 3.9.6
|
||||
Homepage: https://github.com/python-xlib/python-xlib
|
||||
Vcs-Git: https://salsa.debian.org/python-team/modules/python-xlib.git
|
||||
Vcs-Browser: https://salsa.debian.org/python-team/modules/python-xlib
|
||||
X-Python-Version: >= 2.5
|
||||
X-Python3-Version: >= 3.1
|
||||
Section: x11
|
||||
Priority: extra
|
||||
Maintainer: Moshe Zadka <moshez@debian.org>
|
||||
Build-Depends: debhelper
|
||||
Standards-Version: 3.0.1
|
||||
|
||||
Package: python-xlib
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, ${python:Depends}
|
||||
Provides: ${python:Provides}
|
||||
Description: interface for Python to the X11 protocol
|
||||
python-xlib is a 100% pure Python implementation of the X11
|
||||
protocol. It currently implements client-side X11R6 fully, supports
|
||||
the resource database, ICCM, and the Shape extension.
|
||||
.
|
||||
This is a Python 2 version of the package
|
||||
|
||||
Package: python3-xlib
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, ${python3:Depends}
|
||||
Description: interface for Python 3 to the X11 protocol
|
||||
python-xlib is a 100% pure Python 3 implementation of the X11
|
||||
protocol. It currently implements client-side X11R6 fully, supports
|
||||
the resource database, ICCM, and the Shape extension.
|
||||
.
|
||||
This is a Python 3 version of the package
|
||||
Depends: python
|
||||
Description: Interface for Python to the X11 Protocol
|
||||
python-xlib is a 100% pure python implementation of the X11
|
||||
protocol.
|
||||
|
|
|
@ -3,37 +3,11 @@ sun, 15 Jul 2001 13:03:04 +0300.
|
|||
|
||||
It was downloaded from http://python-xlib.sf.net
|
||||
|
||||
Upstream Author: Peter Liljenberg
|
||||
Upstream Author(s): Peter Liljenberg
|
||||
|
||||
examples/record_demo.py is Copyright (C) 2006 Alex Badea <vamposdecampos@gmail.com>
|
||||
Xlib/ext/record.py is Copyright (C) 2006 Alex Badea <vamposdecampos@gmail.com>
|
||||
Xlib/ext/xinerama.py is Copyright (C) 2006 Mike Meyer <mwm@mired.org>
|
||||
Xlib/ext/shape.py is Copyright (C) 2002 Jeffrey Boser <verin@lvcm.com>
|
||||
Copyright:
|
||||
|
||||
doc/html/texi2html is Copyright (C) 1998, 1999 Lionel Cons, Lionel.Cons@cern.ch
|
||||
Copyright (C) 2000,2001 Peter Liljenberg
|
||||
|
||||
Other files are Copyright (C) 2000-2002 Peter Liljenberg
|
||||
|
||||
The Debian packaging is
|
||||
Copyright (C) 2001-2002 Moshe Zadka
|
||||
2005 Martin v. Loewis
|
||||
|
||||
License:
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'.
|
||||
The Python X Library is released under GPL, see the file COPYING for
|
||||
details.
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
usr/lib/python1.5/site-packages/Xlib
|
||||
usr/share/info
|
||||
usr/share/doc/python-xlib/
|
||||
usr/share/doc/python-xlib/examples
|
||||
usr/share/doc/python-xlib/html
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
if [ "$1" = "configure" -o "$1" = "upgrade" ]; then
|
||||
install-info --section "Development" "Development" --quiet /usr/share/info/python-xlib.info
|
||||
fi
|
||||
|
||||
if [ "$1" = "configure" ]; then
|
||||
if [ -d /usr/doc -a ! -e /usr/doc/python-xlib -a -d /usr/share/doc/python-xlib ]; then
|
||||
ln -sf ../share/doc/python-xlib /usr/doc/python-xlib
|
||||
fi
|
||||
fi
|
||||
|
||||
NAME=python-xlib
|
||||
case "$1" in
|
||||
configure|abort-upgrade|abort-remove|abort-deconfigure)
|
||||
dpkg --listfiles $NAME | grep '\.py$' | \
|
||||
xargs -n 1 /usr/bin/python -c 'import py_compile,sys;py_compile.compile(sys.argv[1])'
|
||||
dpkg --listfiles $NAME | grep '\.py$' | \
|
||||
xargs -n 1 /usr/bin/python -O -c 'import py_compile,sys;py_compile.compile(sys.argv[1])'
|
||||
;;
|
||||
esac
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
if [ "$1" = "remove" -o "$1" = "upgrade" ]; then
|
||||
install-info --quiet --remove /usr/share/info/python-xlib.info
|
||||
fi
|
||||
|
||||
NAME=python-xlib
|
||||
|
||||
dpkg --listfiles $NAME |
|
||||
awk '$0~/\.py$/ {print $0"c\n" $0"o"}' |
|
||||
xargs rm -f >&2
|
||||
|
||||
if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/python-xlib ]; then
|
||||
rm -f /usr/doc/python-xlib
|
||||
fi
|
|
@ -1,3 +0,0 @@
|
|||
README.rst
|
||||
TODO
|
||||
doc/html
|
|
@ -1 +0,0 @@
|
|||
examples/*
|
|
@ -1,3 +0,0 @@
|
|||
README.rst
|
||||
TODO
|
||||
doc/html
|
|
@ -1 +0,0 @@
|
|||
examples/*
|
|
@ -1,41 +1,67 @@
|
|||
#!/usr/bin/make -f
|
||||
#-*- makefile -*-
|
||||
# Made with the aid of dh_make, by Craig Small
|
||||
# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
|
||||
# Some lines taken from debmake, by Christoph Lameter.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
export PYBUILD_NAME=xlib
|
||||
# This is the debhelper compatibility version to use.
|
||||
export DH_COMPAT=1
|
||||
|
||||
%:
|
||||
dh $@ --with python2,python3 --buildsystem=pybuild
|
||||
build: build-stamp
|
||||
build-stamp:
|
||||
dh_testdir
|
||||
|
||||
override_dh_auto_build:
|
||||
dh_auto_build
|
||||
make -C doc html
|
||||
# for some reason makeinfo doesn’t create toc on the first run
|
||||
make -C doc html
|
||||
touch build-stamp
|
||||
|
||||
override_dh_auto_clean:
|
||||
dh_auto_clean
|
||||
make -C doc clean
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp install-stamp
|
||||
|
||||
override_dh_installdocs:
|
||||
dh_installdocs
|
||||
rm -f debian/*/usr/share/doc/*/*/Makefile
|
||||
# Add here commands to clean up after the build process.
|
||||
dh_clean
|
||||
|
||||
override_dh_installexamples:
|
||||
dh_installexamples
|
||||
# adjust python3 examples hashbang
|
||||
sed -i '1 s/python$$/python3/' debian/python3-xlib/usr/share/doc/*/examples/*.py
|
||||
# set all examples executable
|
||||
chmod +x debian/python*-xlib/usr/share/doc/*/examples/*.py
|
||||
install: install-stamp
|
||||
install-stamp: build-stamp
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
override_dh_compress:
|
||||
dh_compress -X.py
|
||||
# Add here commands to install the package into debian/tmp.
|
||||
cp -r Xlib debian/tmp/usr/lib/python1.5/site-packages/
|
||||
cp README NEWS TODO debian/tmp/usr/share/doc/python-xlib
|
||||
cp doc/html/*.html debian/tmp/usr/share/doc/python-xlib/html
|
||||
cp doc/info/*.info debian/tmp/usr/share/info
|
||||
gzip -9 debian/tmp/usr/share/info/python-xlib.info
|
||||
cp examples/*.py debian/tmp/usr/share/doc/python-xlib/examples
|
||||
cp debian/copyright debian/tmp/usr/share/doc/python-xlib/
|
||||
|
||||
override_dh_auto_test:
|
||||
ifeq (,$(filter nocheck, $(DEB_BUILD_OPTIONS)))
|
||||
xvfb-run dh_auto_test
|
||||
endif
|
||||
touch install-stamp
|
||||
|
||||
.PHONY: override_dh_auto_build override_dh_auto_clean override_dh_installexamples override_dh_compress
|
||||
binary-arch: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
binary-indep: build install
|
||||
# dh_testversion
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_installchangelogs
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
source diff:
|
||||
@echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
3.0 (native)
|
|
@ -1,4 +0,0 @@
|
|||
version=4
|
||||
|
||||
https://github.com/@PACKAGE@/@PACKAGE@/releases \
|
||||
.*/@PACKAGE@@ANY_VERSION@@ARCHIVE_EXT@
|
|
@ -3,7 +3,7 @@
|
|||
include ../src/defs
|
||||
|
||||
python-xlib_toc.html: $(SRCS)
|
||||
makeinfo --output=. --html --split=node $(TOPSRC)
|
||||
texi2html --output=. --split=node --menu $(TOPSRC)
|
||||
ln -sf python-xlib_toc.html index.html
|
||||
|
||||
clean:
|
||||
|
|
|
@ -9,4 +9,4 @@
|
|||
Here you might find an introduction to X concepts sometime in the
|
||||
future. For now, I just refer to the introduction parts of the standard
|
||||
X documentation. A vast collection of X documentation links can be
|
||||
found at @uref{http://www.rahul.net/kenton/xsites.html}.
|
||||
found at @uref{https://web.archive.org/web/20201228053920/http://www.rahul.net/kenton/xsites.html}.
|
||||
|
|
|
@ -142,7 +142,7 @@ Forget any caught error.
|
|||
|
||||
|
||||
Since the X protocol is mostly asynchronous any error we're watching for
|
||||
might not have been recieved when we call @code{get_error}. To make
|
||||
might not have been received when we call @code{get_error}. To make
|
||||
sure that the request has been processed by the server and any error
|
||||
generated has been received by the Xlib, we must synchronize with the
|
||||
server.
|
||||
|
|
|
@ -22,7 +22,7 @@ typically by doing one or more X requests.
|
|||
@section Getting Events
|
||||
|
||||
Events can be sent at any time, not necessarily when the client is ready
|
||||
to recieve an event. Therefore they must be stored temporarily from that
|
||||
to receive an event. Therefore they must be stored temporarily from that
|
||||
they are read from the network until the client is ready to handle them.
|
||||
Read but unhandled events are stored on an event queue in the Display
|
||||
object. There are two functions to access this queue:
|
||||
|
@ -72,7 +72,7 @@ while 1:
|
|||
if not readable:
|
||||
handle_timeout()
|
||||
|
||||
# if display is readable, handle as many events as have been recieved
|
||||
# if display is readable, handle as many events as have been received
|
||||
elif disp in readable:
|
||||
i = disp.pending_events()
|
||||
while i > 0:
|
||||
|
|
|
@ -205,7 +205,7 @@ list items have the following attributes:
|
|||
The ID of this visual.
|
||||
|
||||
@item visual_class
|
||||
One of @code{X.StaticGrey}, @code{X.StaticColor}, @code{X.TrueColor},
|
||||
One of @code{X.StaticGray}, @code{X.StaticColor}, @code{X.TrueColor},
|
||||
@code{X.GrayScale}, @code{X.PseudoColor}, or @code{X.DirectColor}.
|
||||
|
||||
@item bits_per_rgb_value
|
||||
|
@ -475,7 +475,7 @@ The name of the font.
|
|||
@itemx font_ascent
|
||||
@itemx font_descent
|
||||
@itemx replies_hint
|
||||
See the descripton of XFontStruct in XGetFontProperty(3X11) for details
|
||||
See the description of XFontStruct in XGetFontProperty(3X11) for details
|
||||
on these values.
|
||||
|
||||
@item properties
|
||||
|
@ -678,7 +678,8 @@ XGetScreenSaver(3X11) for details.
|
|||
|
||||
@var{mode} is either @code{X.HostInsert} or @code{X.HostDelete}.
|
||||
@var{host_family} is one of @code{X.FamilyInternet},
|
||||
@code{X.FamilyDECnet} or @code{X.FamilyChaos}.
|
||||
@code{X.FamilyDECnet}, @code{X.FamilyChaos}, @code{X.FamilyServerInterpreted}
|
||||
or @code{X.FamilyInternetV6}.
|
||||
|
||||
@var{host} is a list of bytes. For the Internet family, it should be
|
||||
the four bytes of an IPv4 address.
|
||||
|
@ -699,7 +700,8 @@ The hosts on the access list. Each entry has the following attributes:
|
|||
|
||||
@table @code
|
||||
@item family
|
||||
@code{X.FamilyInternet}, @code{X.FamilyDECnet}, or @code{X.FamilyChaos}.
|
||||
@code{X.FamilyInternet}, @code{X.FamilyDECnet}, @code{X.FamilyChaos},
|
||||
@code{X.FamilyServerInterpreted} or @code{X.FamilyInternetV6}.
|
||||
|
||||
@item name
|
||||
A list of byte values, the coding depends on @code{family}. For the
|
||||
|
@ -1175,7 +1177,7 @@ Returns None or string.
|
|||
@end defmethod
|
||||
|
||||
@defmethod Window get_wm_class ( )
|
||||
Returns None or (isntance, class)
|
||||
Returns None or (instance, class)
|
||||
@end defmethod
|
||||
|
||||
@defmethod Window set_wm_transient_for ( window, onerror = None )
|
||||
|
|
|
@ -39,13 +39,6 @@ except that this permission notice may be stated in a
|
|||
translation approved by the Free Software Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@ifinfo
|
||||
@dircategory Python
|
||||
@direntry
|
||||
* python-xlib: (python-xlib). Interface for Python to the X11 Protocol
|
||||
@end direntry
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@title The Python X Library
|
||||
@author Peter Liljenberg
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# examples/dpms.py -- DPMS usage examples.
|
||||
#
|
||||
# Copyright (C) 2020 Thiago Kenji Okada <thiagokokada@gmail.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 59 Temple Place,
|
||||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
import random
|
||||
import time
|
||||
|
||||
from Xlib import display
|
||||
from Xlib.ext import dpms
|
||||
|
||||
|
||||
class DPMSExamples(object):
|
||||
def __init__(self):
|
||||
self.d = display.Display()
|
||||
|
||||
capable = self.d.dpms_capable()
|
||||
assert capable, 'DPMS is not supported in your system'
|
||||
|
||||
self.initial_info = self.d.dpms_info()
|
||||
self.initial_timeouts = self.d.dpms_get_timeouts()
|
||||
|
||||
# Making sure that DPMS is enable for this examples
|
||||
self.d.dpms_enable()
|
||||
self.d.sync()
|
||||
|
||||
def print_dpms(self):
|
||||
current_info = self.d.dpms_info()
|
||||
print('\nDPMS state: {}\nPower level: {}'.format(current_info.state,
|
||||
current_info.power_level))
|
||||
current_timeouts = self.d.dpms_get_timeouts()
|
||||
print('Standby: {}, Suspend: {}, Off: {}\n'.format(current_timeouts.standby_timeout,
|
||||
current_timeouts.suspend_timeout,
|
||||
current_timeouts.off_timeout))
|
||||
|
||||
def toggle_dpms(self):
|
||||
current_info = self.d.dpms_info()
|
||||
if current_info.state:
|
||||
self.d.dpms_disable()
|
||||
else:
|
||||
self.d.dpms_enable()
|
||||
|
||||
self.d.sync()
|
||||
|
||||
def restore(self):
|
||||
print('Restoring DPMS configuration')
|
||||
self.d.dpms_set_timeouts(self.initial_timeouts.standby_timeout,
|
||||
self.initial_timeouts.suspend_timeout,
|
||||
self.initial_timeouts.off_timeout)
|
||||
if self.initial_info.state:
|
||||
self.d.dpms_enable()
|
||||
else:
|
||||
self.d.dpms_disable()
|
||||
|
||||
self.d.sync()
|
||||
|
||||
self.print_dpms()
|
||||
|
||||
def set_random_timeouts(self):
|
||||
# Can be any number greater than 0
|
||||
# Using 10 just to not turnoff the screen suddenly
|
||||
standby_timeout = random.randint(10, 600)
|
||||
# Shouldn't be smaller than standby_timeout
|
||||
suspend_timeout = random.randint(standby_timeout, 600)
|
||||
# Shouldn't be smaller than standby_timeout or suspend_timeout
|
||||
off_timeout = random.randint(suspend_timeout, 600)
|
||||
self.d.dpms_set_timeouts(standby_timeout, suspend_timeout, off_timeout)
|
||||
self.d.sync()
|
||||
|
||||
def turn_off_display(self):
|
||||
self.d.dpms_force_level(dpms.DPMSModeOff)
|
||||
self.d.sync()
|
||||
|
||||
def turn_on_display(self):
|
||||
self.d.dpms_force_level(dpms.DPMSModeOn)
|
||||
self.d.sync()
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
examples = DPMSExamples()
|
||||
|
||||
print('Initial state')
|
||||
examples.print_dpms()
|
||||
|
||||
print('Setting random timeouts')
|
||||
examples.set_random_timeouts()
|
||||
examples.print_dpms()
|
||||
|
||||
print('The next example will turn-off your screen, press Ctrl-C to cancel.')
|
||||
time.sleep(2)
|
||||
examples.turn_off_display()
|
||||
|
||||
print('Turning it on again...')
|
||||
time.sleep(2)
|
||||
examples.turn_on_display()
|
||||
|
||||
print()
|
||||
|
||||
print('Toggle DPMS')
|
||||
examples.toggle_dpms()
|
||||
examples.print_dpms()
|
||||
|
||||
print('Toggle it again')
|
||||
examples.toggle_dpms()
|
||||
examples.print_dpms()
|
||||
finally:
|
||||
examples.restore()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -83,7 +83,7 @@ def main():
|
|||
# since we don't have an event here we have to.
|
||||
w.convert_selection(sel_atom, target_atom, data_atom, X.CurrentTime)
|
||||
|
||||
# Wait for the notificiaton that we got the selection
|
||||
# Wait for the notification that we got the selection
|
||||
while True:
|
||||
e = d.next_event()
|
||||
if e.type == X.SelectionNotify:
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# examples/nvcontrol.py -- demonstrate the NV-CONTROL extension
|
||||
#
|
||||
# Copyright (C) 2019 Roberto Leinardi <roberto@leinardi.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 59 Temple Place,
|
||||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
# Python 2/3 compatibility.
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Change path so we find Xlib
|
||||
from pprint import pprint
|
||||
|
||||
from Xlib.display import Display
|
||||
from Xlib.ext.nvcontrol import Gpu, Cooler
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
display = Display()
|
||||
# Check for extension
|
||||
if not display.has_extension('NV-CONTROL'):
|
||||
sys.stderr.write('{}: server does not have the NV-CONTROL extension\n'.format(sys.argv[0]))
|
||||
ext = display.query_extension('NV-CONTROL')
|
||||
print(ext)
|
||||
sys.stderr.write("\n".join(display.list_extensions()))
|
||||
if ext is None:
|
||||
sys.exit(1)
|
||||
|
||||
gpu = Gpu(0)
|
||||
fan = Cooler(0)
|
||||
|
||||
perf_level = 3
|
||||
|
||||
dic = {
|
||||
'get_gpu_count': display.nvcontrol_get_gpu_count(),
|
||||
'get_vram': display.nvcontrol_get_vram(gpu),
|
||||
'get_irq': display.nvcontrol_get_irq(gpu),
|
||||
'supports_framelock': display.nvcontrol_supports_framelock(gpu),
|
||||
'get_core_temp': display.nvcontrol_get_core_temp(gpu),
|
||||
'get_core_threshold': display.nvcontrol_get_core_threshold(gpu),
|
||||
'get_default_core_threshold': display.nvcontrol_get_default_core_threshold(gpu),
|
||||
'get_max_core_threshold': display.nvcontrol_get_max_core_threshold(gpu),
|
||||
'get_ambient_temp': display.nvcontrol_get_ambient_temp(gpu),
|
||||
'get_cuda_cores': display.nvcontrol_get_cuda_cores(gpu),
|
||||
'get_memory_bus_width': display.nvcontrol_get_memory_bus_width(gpu),
|
||||
'get_total_dedicated_gpu_memory': display.nvcontrol_get_total_dedicated_gpu_memory(gpu),
|
||||
'get_used_dedicated_gpu_memory': display.nvcontrol_get_used_dedicated_gpu_memory(gpu),
|
||||
'get_curr_pcie_link_width': display.nvcontrol_get_curr_pcie_link_width(gpu),
|
||||
'get_max_pcie_link_width': display.nvcontrol_get_max_pcie_link_width(gpu),
|
||||
'get_curr_pcie_link_generation': display.nvcontrol_get_curr_pcie_link_generation(gpu),
|
||||
'get_encoder_utilization': display.nvcontrol_get_encoder_utilization(gpu),
|
||||
'get_decoder_utilization': display.nvcontrol_get_decoder_utilization(gpu),
|
||||
'get_current_performance_level': display.nvcontrol_get_current_performance_level(gpu),
|
||||
'get_gpu_nvclock_offset': display.nvcontrol_get_gpu_nvclock_offset(gpu, perf_level),
|
||||
'get_mem_transfer_rate_offset': display.nvcontrol_get_mem_transfer_rate_offset(gpu, perf_level),
|
||||
'get_cooler_manual_control_enabled': display.nvcontrol_get_cooler_manual_control_enabled(gpu),
|
||||
'get_fan_duty': display.nvcontrol_get_fan_duty(fan),
|
||||
'get_fan_rpm': display.nvcontrol_get_fan_rpm(fan),
|
||||
'get_coolers_used_by_gpu': display.nvcontrol_get_coolers_used_by_gpu(gpu),
|
||||
'get_max_displays': display.nvcontrol_get_max_displays(gpu),
|
||||
'get_name': display.nvcontrol_get_name(gpu),
|
||||
'get_driver_version': display.nvcontrol_get_driver_version(gpu),
|
||||
'get_vbios_version': display.nvcontrol_get_vbios_version(gpu),
|
||||
'get_gpu_uuid': display.nvcontrol_get_gpu_uuid(gpu),
|
||||
'get_utilization_rates': display.nvcontrol_get_utilization_rates(gpu),
|
||||
'get_performance_modes': display.nvcontrol_get_performance_modes(gpu),
|
||||
'get_gpu_nvclock_offset_range': display.nvcontrol_get_gpu_nvclock_offset_range(gpu, perf_level),
|
||||
'get_mem_transfer_rate_offset_range': display.nvcontrol_get_mem_transfer_rate_offset_range(gpu, perf_level),
|
||||
'get_clock_info': display.nvcontrol_get_clock_info(gpu)
|
||||
}
|
||||
|
||||
pprint(dic)
|
||||
|
||||
display.close()
|
|
@ -77,6 +77,10 @@ class TestExamples(unittest.TestCase):
|
|||
""" Run xlsatoms.py -- show list atoms on X server """
|
||||
self.assertEqual(run_example(examples_folder + "xlsatoms.py"), 0)
|
||||
|
||||
def test_xres(self):
|
||||
""" Run xres.py -- demonstrate the X-Resource extension """
|
||||
self.assertEqual(run_example(examples_folder + "xres.py"), 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# examples/xdamage.py -- demonstrate damage extension
|
||||
#
|
||||
# Copyright (C) 2019 Mohit Garg <mrmohitgarg1990@gmail.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 59 Temple Place,
|
||||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
# Python 2/3 compatibility.
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Change path so we find Xlib
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from Xlib import display, X, threaded,Xutil
|
||||
import time
|
||||
|
||||
try:
|
||||
import thread
|
||||
except ModuleNotFoundError:
|
||||
import _thread as thread
|
||||
|
||||
from Xlib.ext import damage
|
||||
from PIL import Image, ImageTk
|
||||
import traceback
|
||||
|
||||
def redraw(win, gc):
|
||||
# win.clear_area()
|
||||
win.fill_rectangle(gc, 0, 0, 60, 60)
|
||||
|
||||
def blink(display, win, gc, cols):
|
||||
while 1:
|
||||
time.sleep(2)
|
||||
print('Changing color', cols[0])
|
||||
gc.change(foreground = cols[0])
|
||||
cols = (cols[1], cols[0])
|
||||
redraw(win, gc)
|
||||
display.flush()
|
||||
|
||||
def get_image_from_win(win, pt_w, pt_h, pt_x=0, pt_y=0):
|
||||
try:
|
||||
raw = win.get_image(pt_x, pt_y, pt_w, pt_h, X.ZPixmap, 0xffffffff)
|
||||
image = Image.frombytes("RGB", (pt_w, pt_h), raw.data, "raw", "BGRX")
|
||||
return image
|
||||
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
def check_ext(disp):
|
||||
# Check for extension
|
||||
if not disp.has_extension('DAMAGE'):
|
||||
sys.stderr.write('server does not have the DAMAGE extension\n')
|
||||
sys.stderr.write("\n".join(disp.list_extensions()))
|
||||
|
||||
if disp.query_extension('DAMAGE') is None:
|
||||
sys.exit(1)
|
||||
else:
|
||||
r = disp.damage_query_version()
|
||||
print('DAMAGE version {}.{}'.format(r.major_version, r.minor_version))
|
||||
|
||||
def main():
|
||||
d = display.Display()
|
||||
root = d.screen().root
|
||||
|
||||
check_ext(d)
|
||||
colormap = d.screen().default_colormap
|
||||
|
||||
red = colormap.alloc_named_color("red").pixel
|
||||
blue = colormap.alloc_named_color("blue").pixel
|
||||
background = colormap.alloc_named_color("white").pixel
|
||||
|
||||
window1 = root.create_window(100, 100, 250, 100, 1,
|
||||
X.CopyFromParent, X.InputOutput,
|
||||
X.CopyFromParent,
|
||||
background_pixel = background,
|
||||
event_mask = X.StructureNotifyMask | X.ExposureMask)
|
||||
window1.set_wm_name('Changing Window')
|
||||
window1.map()
|
||||
gc = window1.create_gc(foreground = red)
|
||||
|
||||
thread.start_new_thread(blink, (d, window1, gc, (blue, red)))
|
||||
|
||||
window1.damage_create(damage.DamageReportRawRectangles)
|
||||
window1.set_wm_normal_hints(
|
||||
flags=(Xutil.PPosition | Xutil.PSize | Xutil.PMinSize),
|
||||
min_width=50,
|
||||
min_height=50
|
||||
)
|
||||
|
||||
window2 = root.create_window(100, 250, 250, 100, 1,
|
||||
X.CopyFromParent, X.InputOutput,
|
||||
X.CopyFromParent,
|
||||
background_pixel = background,
|
||||
event_mask = X.StructureNotifyMask | X.ExposureMask)
|
||||
window2.set_wm_normal_hints(
|
||||
flags=(Xutil.PPosition | Xutil.PSize | Xutil.PMinSize),
|
||||
min_width=50,
|
||||
min_height=50
|
||||
)
|
||||
|
||||
window2.set_wm_name('Tracking Window')
|
||||
window2.map()
|
||||
|
||||
while 1:
|
||||
event = d.next_event()
|
||||
if event.type == X.Expose:
|
||||
if event.count == 0:
|
||||
redraw(window1, gc)
|
||||
elif event.type == d.extension_event.DamageNotify:
|
||||
image = get_image_from_win(window1, event.area.width, event.area.height, event.area.x, event.area.y)
|
||||
bgpm = window2.create_pixmap(image.width, image.height, d.screen().root_depth)
|
||||
bggc = window2.create_gc(foreground=0, background=0)
|
||||
bgpm.put_pil_image(bggc, 0, 0, image)
|
||||
window2.copy_area(bggc, bgpm, 0, 0, image.width, image.height, 0, 0)
|
||||
# bggc.free()
|
||||
elif event.type == X.DestroyNotify:
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# examples/xfixes-cursor-notify.py -- demonstrate the XFIXES extension
|
||||
# CursorNotify event.
|
||||
#
|
||||
# Copyright (C) 2022
|
||||
# Dan Isla <dan.isla@gmail.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 59 Temple Place,
|
||||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
# Python 2/3 compatibility.
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
from Xlib.display import Display
|
||||
from Xlib.ext import xfixes
|
||||
|
||||
def main():
|
||||
display = Display()
|
||||
|
||||
if not display.has_extension('XFIXES'):
|
||||
if display.query_extension('XFIXES') is None:
|
||||
print('XFIXES extension not supported')
|
||||
return 1
|
||||
|
||||
xfixes_version = display.xfixes_query_version()
|
||||
print('Found XFIXES version {}.{}'.format(
|
||||
xfixes_version.major_version,
|
||||
xfixes_version.minor_version
|
||||
))
|
||||
|
||||
screen = display.screen()
|
||||
|
||||
display.xfixes_select_cursor_input(screen.root, xfixes.XFixesDisplayCursorNotifyMask)
|
||||
|
||||
cursor_cache = {}
|
||||
|
||||
while True:
|
||||
e = display.next_event()
|
||||
print(e)
|
||||
|
||||
if (e.type, e.sub_code) == display.extension_event.DisplayCursorNotify:
|
||||
print("DisplayCursorNotify: cursor_serial={}".format(e.cursor_serial))
|
||||
image = display.xfixes_get_cursor_image(screen.root)
|
||||
cached = False
|
||||
if cursor_cache.get(image.cursor_serial):
|
||||
cached = True
|
||||
else:
|
||||
cursor_cache[image.cursor_serial] = image.cursor_image
|
||||
|
||||
print("Cursor position={},{}, size={}x{}, xyhot={},{}, cursor_serial={}, cached={}".format(
|
||||
image.x, image.y, image.width,image.height, image.xhot, image.yhot, image.cursor_serial, cached
|
||||
))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# examples/xfixes-selection-notify.py -- demonstrate the XFIXES extension
|
||||
# SelectionNotify event.
|
||||
#
|
||||
# Copyright (C) 2019
|
||||
# Tony Crisci <tony@dubstepdish.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 59 Temple Place,
|
||||
# Suite 330,
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
# Python 2/3 compatibility.
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
|
||||
# Change path so we find Xlib
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from Xlib.display import Display
|
||||
from Xlib.ext import xfixes
|
||||
|
||||
def main(argv):
|
||||
if len(sys.argv) != 2:
|
||||
sys.exit('usage: {0} SELECTION\n\n'
|
||||
'SELECTION is typically PRIMARY, SECONDARY or CLIPBOARD.\n'
|
||||
.format(sys.argv[0]))
|
||||
|
||||
display = Display()
|
||||
|
||||
sel_name = sys.argv[1]
|
||||
sel_atom = display.get_atom(sel_name)
|
||||
|
||||
if not display.has_extension('XFIXES'):
|
||||
if display.query_extension('XFIXES') is None:
|
||||
print('XFIXES extension not supported', file=sys.stderr)
|
||||
return 1
|
||||
|
||||
xfixes_version = display.xfixes_query_version()
|
||||
print('Found XFIXES version %s.%s' % (
|
||||
xfixes_version.major_version,
|
||||
xfixes_version.minor_version,
|
||||
), file=sys.stderr)
|
||||
|
||||
screen = display.screen()
|
||||
|
||||
mask = xfixes.XFixesSetSelectionOwnerNotifyMask | \
|
||||
xfixes.XFixesSelectionWindowDestroyNotifyMask | \
|
||||
xfixes.XFixesSelectionClientCloseNotifyMask
|
||||
|
||||
display.xfixes_select_selection_input(screen.root, sel_atom, mask)
|
||||
|
||||
while True:
|
||||
e = display.next_event()
|
||||
print(e)
|
||||
|
||||
if (e.type, e.sub_code) == display.extension_event.SetSelectionOwnerNotify:
|
||||
print('SetSelectionOwner: owner=0x{0:08x}'.format(e.owner.id))
|
||||
elif (e.type, e.sub_code) == display.extension_event.SelectionWindowDestroyNotify:
|
||||
print('SelectionWindowDestroy: owner=0x{0:08x}'.format(e.owner.id))
|
||||
elif (e.type, e.sub_code) == display.extension_event.SelectionClientCloseNotify:
|
||||
print('SelectionClientClose: owner=0x{0:08x}'.format(e.owner.id))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
|
@ -58,7 +58,7 @@ def main(argv):
|
|||
time.sleep(5)
|
||||
|
||||
print('Showing cursor ...', file=sys.stderr)
|
||||
screen.root.xfixes_hide_cursor()
|
||||
screen.root.xfixes_show_cursor()
|
||||
display.sync()
|
||||
|
||||
|
||||
|
|
|
@ -42,11 +42,11 @@ class Window(object):
|
|||
|
||||
# Check for extension
|
||||
if not self.d.has_extension('XINERAMA'):
|
||||
sys.stderr.write('%s: server does not have the XINERAMA extension\n'
|
||||
% sys.argv[0])
|
||||
print(self.d.query_extension('XINERAMA'))
|
||||
sys.stderr.write('{}: server does not have the XINERAMA extension\n'.format(sys.argv[0]))
|
||||
ext = self.d.query_extension('XINERAMA')
|
||||
print(ext)
|
||||
sys.stderr.write("\n".join(self.d.list_extensions()))
|
||||
if self.d.query_extension('XINERAMA') is None:
|
||||
if ext is None:
|
||||
sys.exit(1)
|
||||
|
||||
# print version
|
||||
|
|
|
@ -42,11 +42,11 @@ class Window(object):
|
|||
|
||||
# Check for extension
|
||||
if not self.d.has_extension('RANDR'):
|
||||
sys.stderr.write('%s: server does not have the RANDR extension\n'
|
||||
% sys.argv[0])
|
||||
print(self.d.query_extension('RANDR'))
|
||||
sys.stderr.write('{}: server does not have the RANDR extension\n'.format(sys.argv[0]))
|
||||
ext = self.d.query_extension('RANDR')
|
||||
print(ext)
|
||||
sys.stderr.write("\n".join(self.d.list_extensions()))
|
||||
if self.d.query_extension('RANDR') is None:
|
||||
if ext is None:
|
||||
sys.exit(1)
|
||||
|
||||
# print(version)
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# examples/xres.py -- demonstrate the X-Resource extension
|
||||
#
|
||||
# Copyright (C) 2021 Aleksei Bavshin <alebastr89@gmail.com>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2.1
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street,
|
||||
# Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Change path so we find Xlib
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
||||
from Xlib.display import Display
|
||||
from Xlib.ext import res as XRes
|
||||
|
||||
|
||||
def check_ext(disp, extname, version):
|
||||
if disp.query_extension(extname) is None:
|
||||
raise AssertionError("Server has {} extension".format(extname))
|
||||
|
||||
r = disp.res_query_version()
|
||||
if (r.server_major, r.server_minor) < version:
|
||||
raise AssertionError(
|
||||
"Server has requested version {} of {} extension".format(version, extname)
|
||||
)
|
||||
|
||||
|
||||
def query_client_id(display, wid):
|
||||
specs = [{"client": wid, "mask": XRes.LocalClientPIDMask}]
|
||||
r = display.res_query_client_ids(specs)
|
||||
for id in r.ids:
|
||||
if id.spec.client > 0 and id.spec.mask == XRes.LocalClientPIDMask:
|
||||
for value in id.value:
|
||||
return value
|
||||
return None
|
||||
|
||||
|
||||
def print_client_info(disp, client):
|
||||
print("client: {}".format(client))
|
||||
|
||||
resources = disp.res_query_client_resources(client)
|
||||
rc = [r.count for r in resources.types]
|
||||
print("\tresouces: {} resources of {} types".format(sum(rc), len(rc)))
|
||||
|
||||
pb = disp.res_query_client_pixmap_bytes(client)
|
||||
print("\tpixmaps: {} bytes {} overflow".format(pb.bytes, pb.bytes_overflow))
|
||||
|
||||
pid = query_client_id(disp, client)
|
||||
print("\tpid: {}".format(pid))
|
||||
|
||||
rb = disp.res_query_resource_bytes(client, [{"resource": 0, "type": 0}])
|
||||
sizes = [s.size.bytes for s in rb.sizes]
|
||||
print("\t{} resources consume {} bytes".format(len(sizes), sum(sizes)))
|
||||
|
||||
|
||||
def main():
|
||||
display = Display()
|
||||
check_ext(display, XRes.extname, (1, 2))
|
||||
|
||||
clients = display.res_query_clients().clients
|
||||
print("{} clients connected to the server".format(len(clients)))
|
||||
|
||||
for client in clients:
|
||||
print_client_info(display, client.resource_base)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,150 +0,0 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: python-xlib
|
||||
Version: 0.23
|
||||
Summary: Python X Library
|
||||
Home-page: https://github.com/python-xlib/python-xlib
|
||||
Author: Peter Liljenberg
|
||||
Author-email: petli@ctrl-c.liu.se
|
||||
License: LGPLv2+
|
||||
Download-URL: https://github.com/python-xlib/python-xlib/releases
|
||||
Description-Content-Type: UNKNOWN
|
||||
Description: The Python X Library
|
||||
====================
|
||||
|
||||
|Build Status| |codecov.io| |Code Health|
|
||||
|
||||
`Homepage`_ | `Releases`_ | `Changelog`_
|
||||
|
||||
Copyright
|
||||
~~~~~~~~~
|
||||
|
||||
The main part of the code is
|
||||
|
||||
::
|
||||
|
||||
Copyright (C) 2000-2002 Peter Liljenberg
|
||||
|
||||
Some contributed code is copyrighted by `the contributors <Contributors_>`_,
|
||||
in these cases that is indicated in the source files in question.
|
||||
|
||||
The Python X Library is released under LGPL v2.1 or later (since 2016),
|
||||
see the file LICENSE for details. 0.15rc1 and before were released under
|
||||
GPL v2.
|
||||
|
||||
Requirements
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The Python X Library requires Python 2.7 or newer. It has been tested to
|
||||
various extents with Python 2.7 and 3.3 through 3.6.
|
||||
|
||||
Installation
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The Python Xlib uses the standard setuptools package, to install run
|
||||
this command:
|
||||
|
||||
::
|
||||
|
||||
python setup.py install
|
||||
|
||||
See the command help for details: ``python setup.py install -h``.
|
||||
|
||||
Alternatively, you can run programs from the distribution directory, or
|
||||
change the module path in programs.
|
||||
|
||||
There's a simple example program, implemented twice using both the
|
||||
high-level interface and the low-level protocol.
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The Python X Library is intended to be a fully functional X client
|
||||
library for Python programs. It is written entirely in Python, in
|
||||
contrast to earlier X libraries for Python (the ancient X extension and
|
||||
the newer plxlib) which were interfaces to the C Xlib.
|
||||
|
||||
This is possible to do since X client programs communicate with the X
|
||||
server via the X protocol. The communication takes place over TCP/IP,
|
||||
Unix sockets, DECnet or any other streaming network protocol. The C Xlib
|
||||
is merely an interface to this protocol, providing functions suitable
|
||||
for a C environment.
|
||||
|
||||
There are three advantages of implementing a pure Python library:
|
||||
|
||||
- Integration: The library can make use of the wonderful object system
|
||||
in Python, providing an easy-to-use class hierarchy.
|
||||
|
||||
- Portability: The library will be usable on (almost) any computer
|
||||
which have Python installed. A C interface could be problematic to
|
||||
port to non-Unix systems, such as MS Windows or OpenVMS.
|
||||
|
||||
- Maintainability: It is much easier to develop and debug native Python
|
||||
modules than modules written in C.
|
||||
|
||||
Documentation
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The reference manual is not finished by far, but is probably still useful. It
|
||||
can be `browsed online <http://python-xlib.sourceforge.net/doc/html/index.html>`__.
|
||||
|
||||
There are also some `example programs <Examples_>`_ and, of course,
|
||||
`the standard X11 documentation <http://tronche.com/gui/x/xlib/>`__ applies.
|
||||
|
||||
|
||||
Project status
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The low-level protocol is complete, implementing client-side X11R6. The
|
||||
high-level object oriented interface is also fully functional. It is
|
||||
possible to write client applications with the library. Currently, the
|
||||
only real application using Python Xlib is the window manager PLWM,
|
||||
starting with version 2.0.
|
||||
|
||||
There is a resource database implementation, ICCCM support and a
|
||||
framework for adding X extension code. Several extensions have been
|
||||
implemented; (RECORD, SHAPE, Xinerama, Composite, RANDR, and XTEST)
|
||||
patches for additions are very welcome.
|
||||
|
||||
There are most likely still bugs, but the library is at least stable
|
||||
enough to run PLWM. A continuously bigger part of the library is covered
|
||||
by regression tests, improving stability.
|
||||
|
||||
The documentation is still quite rudimentary, but should be of some help
|
||||
for people programming with the Xlib. X beginners should first find some
|
||||
general texts on X. A very good starting point is
|
||||
http://www.rahul.net/kenton/xsites.html
|
||||
|
||||
See the file TODO for a detailed list of what is missing, approximately
|
||||
ordered by importance.
|
||||
|
||||
.. _Homepage: https://github.com/python-xlib/python-xlib
|
||||
.. _Releases: https://github.com/python-xlib/python-xlib/releases
|
||||
.. _Changelog: https://github.com/python-xlib/python-xlib/tree/master/CHANGELOG.md
|
||||
.. _Contributors: https://github.com/python-xlib/python-xlib/graphs/contributors
|
||||
.. _Examples: https://github.com/python-xlib/python-xlib/tree/master/examples
|
||||
|
||||
.. |Build Status| image:: https://travis-ci.org/python-xlib/python-xlib.svg?branch=master
|
||||
:target: https://travis-ci.org/python-xlib/python-xlib
|
||||
.. |codecov.io| image:: https://codecov.io/github/python-xlib/python-xlib/coverage.svg?branch=master
|
||||
:target: https://codecov.io/github/python-xlib/python-xlib?branch=master
|
||||
.. |Code Health| image:: https://landscape.io/github/python-xlib/python-xlib/master/landscape.svg?style=flat
|
||||
:target: https://landscape.io/github/python-xlib/python-xlib/master
|
||||
|
||||
Keywords: windows,x,x11,xlib
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: X11 Applications
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
Classifier: Topic :: Software Development :: User Interfaces
|
|
@ -1,137 +0,0 @@
|
|||
.gitignore
|
||||
.landscape.yml
|
||||
.travis.yml
|
||||
CHANGELOG.md
|
||||
LICENSE
|
||||
README.rst
|
||||
TODO
|
||||
codecov.yml
|
||||
dev-requirements.txt
|
||||
requirements.txt
|
||||
runtests.py
|
||||
setup.cfg
|
||||
setup.py
|
||||
test.sh
|
||||
tox.ini
|
||||
Xlib/ChangeLog
|
||||
Xlib/X.py
|
||||
Xlib/XK.py
|
||||
Xlib/Xatom.py
|
||||
Xlib/Xcursorfont.py
|
||||
Xlib/Xutil.py
|
||||
Xlib/__init__.py
|
||||
Xlib/display.py
|
||||
Xlib/error.py
|
||||
Xlib/rdb.py
|
||||
Xlib/threaded.py
|
||||
Xlib/xauth.py
|
||||
Xlib/ext/__init__.py
|
||||
Xlib/ext/composite.py
|
||||
Xlib/ext/ge.py
|
||||
Xlib/ext/randr.py
|
||||
Xlib/ext/record.py
|
||||
Xlib/ext/security.py
|
||||
Xlib/ext/shape.py
|
||||
Xlib/ext/xfixes.py
|
||||
Xlib/ext/xinerama.py
|
||||
Xlib/ext/xinput.py
|
||||
Xlib/ext/xtest.py
|
||||
Xlib/keysymdef/__init__.py
|
||||
Xlib/keysymdef/apl.py
|
||||
Xlib/keysymdef/arabic.py
|
||||
Xlib/keysymdef/cyrillic.py
|
||||
Xlib/keysymdef/greek.py
|
||||
Xlib/keysymdef/hebrew.py
|
||||
Xlib/keysymdef/katakana.py
|
||||
Xlib/keysymdef/korean.py
|
||||
Xlib/keysymdef/latin1.py
|
||||
Xlib/keysymdef/latin2.py
|
||||
Xlib/keysymdef/latin3.py
|
||||
Xlib/keysymdef/latin4.py
|
||||
Xlib/keysymdef/miscellany.py
|
||||
Xlib/keysymdef/publishing.py
|
||||
Xlib/keysymdef/special.py
|
||||
Xlib/keysymdef/technical.py
|
||||
Xlib/keysymdef/thai.py
|
||||
Xlib/keysymdef/xf86.py
|
||||
Xlib/keysymdef/xk3270.py
|
||||
Xlib/keysymdef/xkb.py
|
||||
Xlib/protocol/ChangeLog
|
||||
Xlib/protocol/__init__.py
|
||||
Xlib/protocol/display.py
|
||||
Xlib/protocol/event.py
|
||||
Xlib/protocol/request.py
|
||||
Xlib/protocol/rq.py
|
||||
Xlib/protocol/structs.py
|
||||
Xlib/support/__init__.py
|
||||
Xlib/support/connect.py
|
||||
Xlib/support/lock.py
|
||||
Xlib/support/unix_connect.py
|
||||
Xlib/support/vms_connect.py
|
||||
Xlib/xobject/__init__.py
|
||||
Xlib/xobject/colormap.py
|
||||
Xlib/xobject/cursor.py
|
||||
Xlib/xobject/drawable.py
|
||||
Xlib/xobject/fontable.py
|
||||
Xlib/xobject/icccm.py
|
||||
Xlib/xobject/resource.py
|
||||
debian/changelog
|
||||
debian/control
|
||||
debian/copyright
|
||||
debian/dirs
|
||||
debian/postinst
|
||||
debian/prerm
|
||||
debian/rules
|
||||
doc/Makefile
|
||||
doc/html/Makefile
|
||||
doc/info/Makefile
|
||||
doc/ps/Makefile
|
||||
doc/src/Makefile
|
||||
doc/src/concepts.texi
|
||||
doc/src/connect.texi
|
||||
doc/src/defs
|
||||
doc/src/errors.texi
|
||||
doc/src/events.texi
|
||||
doc/src/objects.texi
|
||||
doc/src/package.texi
|
||||
doc/src/python-xlib.texi
|
||||
examples/childwin.py
|
||||
examples/draw-proto.py
|
||||
examples/draw.py
|
||||
examples/eventthread.py
|
||||
examples/get_selection.py
|
||||
examples/profilex.py
|
||||
examples/put_selection.py
|
||||
examples/record_demo.py
|
||||
examples/run_examples.py
|
||||
examples/security.py
|
||||
examples/shapewin.py
|
||||
examples/threadtest.py
|
||||
examples/xfixes.py
|
||||
examples/xinerama.py
|
||||
examples/xinput.py
|
||||
examples/xlsatoms.py
|
||||
examples/xrandr.py
|
||||
python_xlib.egg-info/PKG-INFO
|
||||
python_xlib.egg-info/SOURCES.txt
|
||||
python_xlib.egg-info/dependency_links.txt
|
||||
python_xlib.egg-info/requires.txt
|
||||
python_xlib.egg-info/top_level.txt
|
||||
test/__init__.py
|
||||
test/test_bytesview.py
|
||||
test/test_events_be.py
|
||||
test/test_events_le.py
|
||||
test/test_manual.py
|
||||
test/test_rdb.py
|
||||
test/test_requests_be.py
|
||||
test/test_requests_le.py
|
||||
test/test_struct.py
|
||||
test/test_unix_connect.py
|
||||
test/test_xlib_display.py
|
||||
test/gen/.gitignore
|
||||
test/gen/eventdef
|
||||
test/gen/genprotocol.awk
|
||||
test/gen/genprottest.py
|
||||
test/gen/protdef
|
||||
utils/parsexbug.py
|
||||
utils/tcpbug.py
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
six>=1.10.0
|
|
@ -1 +0,0 @@
|
|||
Xlib
|
11
setup.cfg
11
setup.cfg
|
@ -8,12 +8,12 @@ url = https://github.com/python-xlib/python-xlib
|
|||
license = LGPLv2+
|
||||
author = Peter Liljenberg
|
||||
author_email = petli@ctrl-c.liu.se
|
||||
keywords =
|
||||
keywords =
|
||||
windows
|
||||
x
|
||||
x11
|
||||
xlib
|
||||
classifiers =
|
||||
classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: X11 Applications
|
||||
Intended Audience :: Developers
|
||||
|
@ -26,6 +26,8 @@ classifiers =
|
|||
Programming Language :: Python :: 3.5
|
||||
Programming Language :: Python :: 3.5
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Topic :: Software Development :: Libraries :: Python Modules
|
||||
Topic :: Software Development :: Libraries
|
||||
|
@ -34,7 +36,4 @@ classifiers =
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
||||
[egg_info]
|
||||
tag_build =
|
||||
tag_date = 0
|
||||
|
||||
# vim: list
|
||||
|
|
|
@ -72,8 +72,8 @@ class TestUnixConnect(unittest.TestCase):
|
|||
def path_exists(returns, path):
|
||||
calls.append(('os.path.exists', path))
|
||||
return returns
|
||||
def fcntl(*args):
|
||||
calls.append(('fcntl',) + args)
|
||||
def ensure_not_inheritable(*args):
|
||||
calls.append(('ensure_not_inheritable',) + args)
|
||||
for params, allow_unix, unix_addr_exists, allow_tcp, expect_connection_error, expected_calls in (
|
||||
# Successful explicit TCP socket connection.
|
||||
(('tcp/host:6', None, 'host', 6), False, False, True, False, [
|
||||
|
@ -141,7 +141,7 @@ class TestUnixConnect(unittest.TestCase):
|
|||
partial(_get_socket, 'tcp', not allow_tcp)), \
|
||||
patch('os.path.exists',
|
||||
partial(path_exists, unix_addr_exists)), \
|
||||
patch('fcntl.fcntl', fcntl):
|
||||
patch('Xlib.support.unix_connect._ensure_not_inheritable', ensure_not_inheritable):
|
||||
del calls[:]
|
||||
if expect_connection_error:
|
||||
with self.assertRaises(DisplayConnectionError):
|
||||
|
@ -149,9 +149,7 @@ class TestUnixConnect(unittest.TestCase):
|
|||
else:
|
||||
s = unix_connect.get_socket(*params)
|
||||
self.assertIsInstance(s, FakeSocket)
|
||||
expected_calls.append(('fcntl', 42,
|
||||
unix_connect.F_SETFD,
|
||||
unix_connect.FD_CLOEXEC))
|
||||
expected_calls.append(('ensure_not_inheritable', s))
|
||||
self.assertEqual(calls, expected_calls)
|
||||
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ class TestXlibDisplay(unittest.TestCase):
|
|||
self.assertRaises(AssertionError, self.display.extension_add_method, "font", "__init__", lambda x: x)
|
||||
|
||||
def test_can_add_extension_error(self):
|
||||
self.display.add_extension_error(1, Xlib.error.XError)
|
||||
self.display.extension_add_error(1, Xlib.error.XError)
|
||||
self.assertEqual(self.display.display.error_classes[1], Xlib.error.XError)
|
||||
|
||||
def test_keycode_to_keysym_for_invalid_index(self):
|
||||
|
|
Loading…
Reference in New Issue