File: //home/arjun/projects/env/lib/python3.10/site-packages/cairocffi/test_xcb.py
"""
cairocffi.test_xcb
~~~~~~~~~~~~~~~~~~
Test suite for cairocffi.xcb.
:copyright: Copyright 2014-2019 by Simon Sapin
:license: BSD, see LICENSE for details.
"""
import os
import time
import pytest
xcffib = pytest.importorskip('xcffib') # noqa
import xcffib.xproto # noqa isort:skip
from xcffib.xproto import ConfigWindow, CW, EventMask, GC # noqa isort:skip
from . import Context, XCBSurface, cairo_version # noqa isort:skip
@pytest.fixture
def xcb_conn():
"""
Fixture that will setup and take down a xcffib.Connection object running on
a display spawned by xvfb
"""
display = os.environ.get('DISPLAY')
if display is None: # pragma: no cover
pytest.skip('DISPLAY environment variable not set')
conn = xcffib.connect(display)
yield conn
conn.disconnect()
def find_root_visual(conn):
"""Find the xcffib.xproto.VISUALTYPE corresponding to the root visual"""
default_screen = conn.setup.roots[conn.pref_screen]
for i in default_screen.allowed_depths:
for v in i.visuals:
if v.visual_id == default_screen.root_visual:
return v
def create_window(conn, width, height):
"""Creates a window of the given dimensions and returns the XID"""
wid = conn.generate_id()
default_screen = conn.setup.roots[conn.pref_screen]
conn.core.CreateWindow(
default_screen.root_depth, # depth
wid, # id
default_screen.root, # parent
0, 0, width, height, 0, # x, y, w, h, border width
xcffib.xproto.WindowClass.InputOutput, # window class
default_screen.root_visual, # visual
CW.BackPixel | CW.EventMask, # value mask
[ # value list
default_screen.black_pixel,
EventMask.Exposure | EventMask.StructureNotify
]
)
return wid
def create_pixmap(conn, wid, width, height):
"""Creates a window of the given dimensions and returns the XID"""
pixmap = conn.generate_id()
default_screen = conn.setup.roots[conn.pref_screen]
conn.core.CreatePixmap(
default_screen.root_depth, # depth
pixmap, wid, # pixmap id, drawable id (window)
width, height
)
return pixmap
def create_gc(conn):
"""Creates a simple graphics context"""
gc = conn.generate_id()
default_screen = conn.setup.roots[conn.pref_screen]
conn.core.CreateGC(
gc, default_screen.root, # gc id, drawable
GC.Foreground | GC.Background, # value mask
[ # value list
default_screen.black_pixel,
default_screen.white_pixel
]
)
return gc
@pytest.mark.xfail(cairo_version() < 11200,
reason="Cairo version too low")
def test_xcb_pixmap(xcb_conn):
width = 10
height = 10
# create a new window
wid = create_window(xcb_conn, width, height)
# create the pixmap used to draw with cairo
pixmap = create_pixmap(xcb_conn, wid, width, height)
# create graphics context to copy pixmap on window
gc = create_gc(xcb_conn)
# create XCB surface on pixmap
root_visual = find_root_visual(xcb_conn)
surface = XCBSurface(xcb_conn, pixmap, root_visual, width, height)
assert surface
# use xcb surface to create context, draw white
ctx = Context(surface)
ctx.set_source_rgb(1, 1, 1)
ctx.paint()
# map the window and wait for it to appear
xcb_conn.core.MapWindow(wid)
xcb_conn.flush()
start = time.time()
while time.time() < start + 10:
event = xcb_conn.wait_for_event()
if isinstance(event, xcffib.xproto.ExposeEvent):
break
else:
pytest.fail("Never received ExposeEvent")
# copy the pixmap to the window
xcb_conn.core.CopyArea(
pixmap, # source
wid, # dest
gc, # gc
0, 0, # source x, source y
0, 0, # dest x, dest y
width, height
)
ctx = None
surface = None
xcb_conn.core.FreeGC(gc)
xcb_conn.core.FreePixmap(pixmap)
# flush the connection, make sure no errors were thrown
xcb_conn.flush()
while event:
event = xcb_conn.poll_for_event()
@pytest.mark.xfail(cairo_version() < 11200,
reason="Cairo version too low")
def test_xcb_window(xcb_conn):
width = 10
height = 10
# create a new window used to draw with cairo
wid = create_window(xcb_conn, width, height)
# map the window and wait for it to appear
xcb_conn.core.MapWindow(wid)
xcb_conn.flush()
start = time.time()
while time.time() < start + 10:
event = xcb_conn.wait_for_event()
if isinstance(event, xcffib.xproto.ExposeEvent):
break
else:
pytest.fail("Never received ExposeEvent")
# create XCB surface on window
root_visual = find_root_visual(xcb_conn)
surface = XCBSurface(xcb_conn, wid, root_visual, width, height)
assert surface
# use xcb surface to create context, draw white
ctx = Context(surface)
ctx.set_source_rgb(1, 1, 1)
ctx.paint()
xcb_conn.flush()
# now move the window and change its size
xcb_conn.core.ConfigureWindow(
wid,
(ConfigWindow.X | ConfigWindow.Y
| ConfigWindow.Width | ConfigWindow.Height),
[
5, 5, # x, y
width * 2, height * 2 # width, height
]
)
xcb_conn.flush()
# wait for the notification of the size change
start = time.time()
while time.time() < start + 10:
event = xcb_conn.wait_for_event()
if isinstance(event, xcffib.xproto.ConfigureNotifyEvent):
assert event.width == 2*width
assert event.height == 2*height
width = event.width
height = event.height
break
else:
pytest.fail("Never received ConfigureNotifyEvent")
# re-size and re-draw the surface
surface.set_size(width, height)
ctx = Context(surface)
ctx.set_source_rgb(1, 1, 1)
ctx.paint()
# flush the connection, make sure no errors were thrown
xcb_conn.flush()
while event:
event = xcb_conn.poll_for_event()