Metadata-Version: 2.4
Name: aioxlib
Version: 0.2.0
Summary: Human friendly interface to XLib subsystems using asyncio python
Author-email: Jose Tiago Macara Coutinho <coutinhotiago@gmail.com>
License-Expression: GPL-3.0-or-later
Project-URL: Documentation, https://codeberg.org/tiagocoutinho/aioxlib/
Project-URL: Homepage, https://codeberg.org/tiagocoutinho/aioxlib/
Project-URL: Repository, https://codeberg.org/tiagocoutinho/aioxlib/
Keywords: x11,asyncio
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Multimedia :: Video :: Capture
Requires-Python: >=3.12
Description-Content-Type: text/markdown

# aioxlib

**Human-friendly asyncio interface to the X11 protocol**

[![PyPI](https://img.shields.io/pypi/v/aioxlib.svg)](https://pypi.org/project/aioxlib/)
[![Python Versions](https://img.shields.io/pypi/pyversions/aioxlib.svg)](https://pypi.org/project/aioxlib/)
[![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

`aioxlib` is a pure-Python library that speaks the X11 wire protocol over
asyncio. It aims to make displays, windows, drawing, events, and extensions
feel natural in async Python—without blocking the event loop and without
linking to libX11.

Inspired by [linuxpy](https://github.com/tiagocoutinho/linuxpy) (same author):
a clean high-level API with protocol details still available when you need
them.

## Features

- Fully asynchronous connection to the X server (Unix socket or TCP)
- High-level objects: `Display`, `Screen`, `Window`, `GC`, resources
- Event stream via `async for event in display.events()`
- Windows: create/map/configure/reparent, WM name & delete handling
- Core drawing: rectangles, arcs, segments, points, text, images
- **RENDER**: pictures, solid fills, gradients, triangles/trapezoids/strips, glyphs
- **MIT-SHM** for high-throughput image transfer
- **DOUBLE-BUFFER**, **BIG-REQUESTS**, plus GLX / DRI3 / Present helpers
- Atoms, properties (with type encode/decode), fonts, colormaps
- Python ≥ 3.12, GPLv3, **no third-party runtime dependencies**
- Implementation in a single module

## Installation

```bash
pip install aioxlib
```

From source:

```bash
git clone https://codeberg.org/tiagocoutinho/aioxlib.git
cd aioxlib
pip install -e .
```

## Quick start

```python
import asyncio
import aioxlib


async def main():
    wnd = await aioxlib.create_window(
        width=640,
        height=480,
        title="Hello from aioxlib",
    )
    await wnd.show()

    async for event in aioxlib.events():
        if wnd.is_delete_window(event):
            break


asyncio.run(main())
```

`create_window(..., delete_on_close=True)` (the default) registers
`WM_DELETE_WINDOW`. Use `Window.is_delete_window(event)` in the event loop.

## Documentation

User guide and full API reference (Material for MkDocs + mkdocstrings):

```bash
pip install mkdocs mkdocs-material 'mkdocstrings[python]'
mkdocs serve
```

Then open <http://127.0.0.1:8000/>.

## Examples

| File | Description |
|------|-------------|
| `basic.py` | Minimal window + close handling |
| `text.py` | Text on Expose |
| `grid.py` | Grid of filled rectangles |
| `points.py` / `segments.py` | Points and line segments |
| `3d.py` | Rotating mesh (Penger) |
| `cube_render_triangles.py` | Cube with RENDER gradients |
| `tristrip.py` | RENDER triangle strip |
| `render.py` | RENDER basics |
| `dbe.py` / `cube_dbe.py` | Double buffering |
| `shm.py` | MIT-SHM image path |
| `video.py` / `video_shm.py` | V4L2 video (optional) |
| `configure.py` | ConfigureWindow |
| `game_of_life.py` | Small interactive demo |

```bash
python examples/basic.py
```

## API overview

```python
display = await aioxlib.get_display()  # or get_display(":0")
async with display:
    screen = display.default_screen()

    wnd = await screen.create_window(
        width=800,
        height=600,
        title="Demo",
        event_mask=aioxlib.EventMask.Exposure,
    )
    await wnd.show()

    gc = await wnd.create_gc(foreground=0x00FFFF, background=0)
    await wnd.poly_fill_rectangles(gc, [(10, 10, 100, 50)])
    await wnd.poly_fill_arcs(gc, [(50, 50, 80, 80, 0, 360 * 64)])

    # Optional: RENDER
    render = await display.query_extension("RENDER")
    if render:
        formats = await render.query_picture_formats()
        ...

    async for event in display.events():
        if wnd.is_delete_window(event):
            break
        if event["code"] == aioxlib.EventType.Expose:
            ...
```

Events are dicts; core codes are in `aioxlib.EventType`.

### Properties

```python
await wnd.change_property(aioxlib.Atom.WM_NAME, aioxlib.Atom.STRING, data="Title")
reply = await wnd.get_property(aioxlib.Atom.WM_NAME)
print(reply["value"])  # decoded str / list[int] / …
```

## Requirements

- Python ≥ 3.12
- An X11 server (Xorg, Xwayland, Xephyr, …)
- `$DISPLAY` set, or pass the display URI explicitly

## Development

```bash
pip install -e .
pip install pytest pytest-asyncio pytest-cov
pytest
```

## License

GPLv3 or later — see [LICENSE](LICENSE).

## Author

José Tiago Macara Coutinho  
<https://codeberg.org/tiagocoutinho>

---

*aioxlib 0.1.0 — feedback and contributions welcome.*
