aioxlib 0.0.6__tar.gz → 0.0.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aioxlib-0.0.6 → aioxlib-0.0.7}/PKG-INFO +1 -1
- {aioxlib-0.0.6 → aioxlib-0.0.7}/aioxlib/__init__.py +988 -1
- {aioxlib-0.0.6 → aioxlib-0.0.7}/aioxlib.egg-info/PKG-INFO +1 -1
- {aioxlib-0.0.6 → aioxlib-0.0.7}/README.md +0 -0
- {aioxlib-0.0.6 → aioxlib-0.0.7}/aioxlib.egg-info/SOURCES.txt +0 -0
- {aioxlib-0.0.6 → aioxlib-0.0.7}/aioxlib.egg-info/dependency_links.txt +0 -0
- {aioxlib-0.0.6 → aioxlib-0.0.7}/aioxlib.egg-info/top_level.txt +0 -0
- {aioxlib-0.0.6 → aioxlib-0.0.7}/pyproject.toml +0 -0
- {aioxlib-0.0.6 → aioxlib-0.0.7}/setup.cfg +0 -0
- {aioxlib-0.0.6 → aioxlib-0.0.7}/tests/test_aioxlib.py +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Copyright (c) 2026 Tiago Coutinho
|
|
5
5
|
# Distributed under the GPLv3 license. See LICENSE for more info.
|
|
6
6
|
|
|
7
|
-
__version__ = "0.0.
|
|
7
|
+
__version__ = "0.0.7"
|
|
8
8
|
|
|
9
9
|
import asyncio
|
|
10
10
|
import enum
|
|
@@ -3771,6 +3771,992 @@ class Present(Extension):
|
|
|
3771
3771
|
return await self.display.write_read(payload, unpack_present_query_capabilities)
|
|
3772
3772
|
|
|
3773
3773
|
|
|
3774
|
+
# ---------------------------------------------------------------------------
|
|
3775
|
+
# RENDER extension (X Rendering Extension)
|
|
3776
|
+
# ---------------------------------------------------------------------------
|
|
3777
|
+
|
|
3778
|
+
|
|
3779
|
+
class RenderCommand(enum.IntEnum):
|
|
3780
|
+
QueryVersion = 0
|
|
3781
|
+
QueryPictFormats = 1
|
|
3782
|
+
QueryPictIndexValues = 2
|
|
3783
|
+
QueryDithers = 3
|
|
3784
|
+
CreatePicture = 4
|
|
3785
|
+
ChangePicture = 5
|
|
3786
|
+
SetPictureClipRectangles = 6
|
|
3787
|
+
FreePicture = 7
|
|
3788
|
+
Composite = 8
|
|
3789
|
+
Scale = 9
|
|
3790
|
+
Trapezoids = 10
|
|
3791
|
+
Triangles = 11
|
|
3792
|
+
TriStrip = 12
|
|
3793
|
+
TriFan = 13
|
|
3794
|
+
ColorTrapezoids = 14
|
|
3795
|
+
ColorTriangles = 15
|
|
3796
|
+
CreateGlyphSet = 17
|
|
3797
|
+
ReferenceGlyphSet = 18
|
|
3798
|
+
FreeGlyphSet = 19
|
|
3799
|
+
AddGlyphs = 20
|
|
3800
|
+
AddGlyphsFromPicture = 21
|
|
3801
|
+
FreeGlyphs = 22
|
|
3802
|
+
CompositeGlyphs8 = 23
|
|
3803
|
+
CompositeGlyphs16 = 24
|
|
3804
|
+
CompositeGlyphs32 = 25
|
|
3805
|
+
FillRectangles = 26
|
|
3806
|
+
CreateCursor = 27
|
|
3807
|
+
SetPictureTransform = 28
|
|
3808
|
+
QueryFilters = 29
|
|
3809
|
+
SetPictureFilter = 30
|
|
3810
|
+
CreateAnimCursor = 31
|
|
3811
|
+
AddTraps = 32
|
|
3812
|
+
CreateSolidFill = 33
|
|
3813
|
+
CreateLinearGradient = 34
|
|
3814
|
+
CreateRadialGradient = 35
|
|
3815
|
+
CreateConicalGradient = 36
|
|
3816
|
+
|
|
3817
|
+
|
|
3818
|
+
class PictType(enum.IntEnum):
|
|
3819
|
+
Indexed = 0
|
|
3820
|
+
Direct = 1
|
|
3821
|
+
|
|
3822
|
+
|
|
3823
|
+
class PictOp(enum.IntEnum):
|
|
3824
|
+
"""Porter-Duff / blend operators for Composite and FillRectangles."""
|
|
3825
|
+
|
|
3826
|
+
Clear = 0
|
|
3827
|
+
Src = 1
|
|
3828
|
+
Dst = 2
|
|
3829
|
+
Over = 3
|
|
3830
|
+
OverReverse = 4
|
|
3831
|
+
In = 5
|
|
3832
|
+
InReverse = 6
|
|
3833
|
+
Out = 7
|
|
3834
|
+
OutReverse = 8
|
|
3835
|
+
Atop = 9
|
|
3836
|
+
AtopReverse = 10
|
|
3837
|
+
Xor = 11
|
|
3838
|
+
Add = 12
|
|
3839
|
+
Saturate = 13
|
|
3840
|
+
# Disjoint (0.2+)
|
|
3841
|
+
DisjointClear = 0x10
|
|
3842
|
+
DisjointSrc = 0x11
|
|
3843
|
+
DisjointDst = 0x12
|
|
3844
|
+
DisjointOver = 0x13
|
|
3845
|
+
DisjointOverReverse = 0x14
|
|
3846
|
+
DisjointIn = 0x15
|
|
3847
|
+
DisjointInReverse = 0x16
|
|
3848
|
+
DisjointOut = 0x17
|
|
3849
|
+
DisjointOutReverse = 0x18
|
|
3850
|
+
DisjointAtop = 0x19
|
|
3851
|
+
DisjointAtopReverse = 0x1A
|
|
3852
|
+
DisjointXor = 0x1B
|
|
3853
|
+
# Conjoint (0.2+)
|
|
3854
|
+
ConjointClear = 0x20
|
|
3855
|
+
ConjointSrc = 0x21
|
|
3856
|
+
ConjointDst = 0x22
|
|
3857
|
+
ConjointOver = 0x23
|
|
3858
|
+
ConjointOverReverse = 0x24
|
|
3859
|
+
ConjointIn = 0x25
|
|
3860
|
+
ConjointInReverse = 0x26
|
|
3861
|
+
ConjointOut = 0x27
|
|
3862
|
+
ConjointOutReverse = 0x28
|
|
3863
|
+
ConjointAtop = 0x29
|
|
3864
|
+
ConjointAtopReverse = 0x2A
|
|
3865
|
+
ConjointXor = 0x2B
|
|
3866
|
+
# Blend (0.11+)
|
|
3867
|
+
Multiply = 0x30
|
|
3868
|
+
Screen = 0x31
|
|
3869
|
+
Overlay = 0x32
|
|
3870
|
+
Darken = 0x33
|
|
3871
|
+
Lighten = 0x34
|
|
3872
|
+
ColorDodge = 0x35
|
|
3873
|
+
ColorBurn = 0x36
|
|
3874
|
+
HardLight = 0x37
|
|
3875
|
+
SoftLight = 0x38
|
|
3876
|
+
Difference = 0x39
|
|
3877
|
+
Exclusion = 0x3A
|
|
3878
|
+
HSLHue = 0x3B
|
|
3879
|
+
HSLSaturation = 0x3C
|
|
3880
|
+
HSLColor = 0x3D
|
|
3881
|
+
HSLLuminosity = 0x3E
|
|
3882
|
+
|
|
3883
|
+
|
|
3884
|
+
class PictureAttributes(enum.IntFlag):
|
|
3885
|
+
Repeat = 1 << 0
|
|
3886
|
+
AlphaMap = 1 << 1
|
|
3887
|
+
AlphaXOrigin = 1 << 2
|
|
3888
|
+
AlphaYOrigin = 1 << 3
|
|
3889
|
+
ClipXOrigin = 1 << 4
|
|
3890
|
+
ClipYOrigin = 1 << 5
|
|
3891
|
+
ClipMask = 1 << 6
|
|
3892
|
+
GraphicsExposures = 1 << 7
|
|
3893
|
+
SubwindowMode = 1 << 8
|
|
3894
|
+
PolyEdge = 1 << 9
|
|
3895
|
+
PolyMode = 1 << 10
|
|
3896
|
+
Dither = 1 << 11
|
|
3897
|
+
ComponentAlpha = 1 << 12
|
|
3898
|
+
|
|
3899
|
+
|
|
3900
|
+
PICTURE_ATTR_ORDER = (
|
|
3901
|
+
("repeat", PictureAttributes.Repeat),
|
|
3902
|
+
("alpha_map", PictureAttributes.AlphaMap),
|
|
3903
|
+
("alpha_x_origin", PictureAttributes.AlphaXOrigin),
|
|
3904
|
+
("alpha_y_origin", PictureAttributes.AlphaYOrigin),
|
|
3905
|
+
("clip_x_origin", PictureAttributes.ClipXOrigin),
|
|
3906
|
+
("clip_y_origin", PictureAttributes.ClipYOrigin),
|
|
3907
|
+
("clip_mask", PictureAttributes.ClipMask),
|
|
3908
|
+
("graphics_exposures", PictureAttributes.GraphicsExposures),
|
|
3909
|
+
("subwindow_mode", PictureAttributes.SubwindowMode),
|
|
3910
|
+
("poly_edge", PictureAttributes.PolyEdge),
|
|
3911
|
+
("poly_mode", PictureAttributes.PolyMode),
|
|
3912
|
+
("dither", PictureAttributes.Dither),
|
|
3913
|
+
("component_alpha", PictureAttributes.ComponentAlpha),
|
|
3914
|
+
)
|
|
3915
|
+
|
|
3916
|
+
|
|
3917
|
+
class PolyEdge(enum.IntEnum):
|
|
3918
|
+
Sharp = 0
|
|
3919
|
+
Smooth = 1
|
|
3920
|
+
|
|
3921
|
+
|
|
3922
|
+
class PolyMode(enum.IntEnum):
|
|
3923
|
+
Precise = 0
|
|
3924
|
+
Imprecise = 1
|
|
3925
|
+
|
|
3926
|
+
|
|
3927
|
+
class SubPixel(enum.IntEnum):
|
|
3928
|
+
Unknown = 0
|
|
3929
|
+
HorizontalRGB = 1
|
|
3930
|
+
HorizontalBGR = 2
|
|
3931
|
+
VerticalRGB = 3
|
|
3932
|
+
VerticalBGR = 4
|
|
3933
|
+
None_ = 5
|
|
3934
|
+
|
|
3935
|
+
|
|
3936
|
+
class Repeat(enum.IntEnum):
|
|
3937
|
+
None_ = 0
|
|
3938
|
+
Normal = 1
|
|
3939
|
+
Pad = 2
|
|
3940
|
+
Reflect = 3
|
|
3941
|
+
|
|
3942
|
+
|
|
3943
|
+
def fixed(value) -> int:
|
|
3944
|
+
"""Convert a float (or int) to X Fixed (16.16 signed)."""
|
|
3945
|
+
if isinstance(value, int) and not isinstance(value, bool):
|
|
3946
|
+
# already fixed or integer pixels → treat bare ints as fixed when |v| is large?
|
|
3947
|
+
# Convention: ints are whole numbers in fixed form (value << 16) unless already Fixed.
|
|
3948
|
+
return int(value) << 16
|
|
3949
|
+
return int(round(float(value) * 65536.0))
|
|
3950
|
+
|
|
3951
|
+
|
|
3952
|
+
def fixed_to_float(v: int) -> float:
|
|
3953
|
+
return int(v) / 65536.0
|
|
3954
|
+
|
|
3955
|
+
|
|
3956
|
+
def pack_render_color(r, g, b, a=1.0):
|
|
3957
|
+
"""Pack an xRenderColor from 0..1 floats or 0..0xffff ints."""
|
|
3958
|
+
|
|
3959
|
+
def _chan(c):
|
|
3960
|
+
if isinstance(c, float):
|
|
3961
|
+
return max(0, min(0xFFFF, int(round(c * 0xFFFF))))
|
|
3962
|
+
return max(0, min(0xFFFF, int(c)))
|
|
3963
|
+
|
|
3964
|
+
return struct.pack("HHHH", _chan(r), _chan(g), _chan(b), _chan(a))
|
|
3965
|
+
|
|
3966
|
+
|
|
3967
|
+
def _picture_values(**attrs):
|
|
3968
|
+
mask = PictureAttributes(0)
|
|
3969
|
+
values = []
|
|
3970
|
+
for name, bit in PICTURE_ATTR_ORDER:
|
|
3971
|
+
if (val := attrs.get(name)) is None:
|
|
3972
|
+
continue
|
|
3973
|
+
mask |= bit
|
|
3974
|
+
values.append(val)
|
|
3975
|
+
return mask, values
|
|
3976
|
+
|
|
3977
|
+
|
|
3978
|
+
def pack_render_query_version(opcode, major=0, minor=11):
|
|
3979
|
+
return struct.pack(
|
|
3980
|
+
"BBHII",
|
|
3981
|
+
opcode,
|
|
3982
|
+
RenderCommand.QueryVersion,
|
|
3983
|
+
3,
|
|
3984
|
+
major,
|
|
3985
|
+
minor,
|
|
3986
|
+
)
|
|
3987
|
+
|
|
3988
|
+
|
|
3989
|
+
def unpack_render_query_version(data, offset=0):
|
|
3990
|
+
result, offset = unpack_reply_head(data, offset)
|
|
3991
|
+
major, minor = struct.unpack_from("II", data, offset)
|
|
3992
|
+
offset += 8 + 16
|
|
3993
|
+
result["major_version"] = major
|
|
3994
|
+
result["minor_version"] = minor
|
|
3995
|
+
return result, offset
|
|
3996
|
+
|
|
3997
|
+
|
|
3998
|
+
def pack_render_query_pict_formats(opcode):
|
|
3999
|
+
return struct.pack("BBH", opcode, RenderCommand.QueryPictFormats, 1)
|
|
4000
|
+
|
|
4001
|
+
|
|
4002
|
+
def unpack_render_query_pict_formats(data, offset=0):
|
|
4003
|
+
result, offset = unpack_reply_head(data, offset)
|
|
4004
|
+
(
|
|
4005
|
+
num_formats,
|
|
4006
|
+
num_screens,
|
|
4007
|
+
num_depths,
|
|
4008
|
+
num_visuals,
|
|
4009
|
+
num_subpixel,
|
|
4010
|
+
) = struct.unpack_from("5I", data, offset)
|
|
4011
|
+
offset += 20 + 4 # 5I + pad
|
|
4012
|
+
|
|
4013
|
+
formats = []
|
|
4014
|
+
for _ in range(num_formats):
|
|
4015
|
+
(
|
|
4016
|
+
fid,
|
|
4017
|
+
ftype,
|
|
4018
|
+
depth,
|
|
4019
|
+
red,
|
|
4020
|
+
red_mask,
|
|
4021
|
+
green,
|
|
4022
|
+
green_mask,
|
|
4023
|
+
blue,
|
|
4024
|
+
blue_mask,
|
|
4025
|
+
alpha,
|
|
4026
|
+
alpha_mask,
|
|
4027
|
+
colormap,
|
|
4028
|
+
) = struct.unpack_from("IBB2x8HI", data, offset)
|
|
4029
|
+
offset += 28
|
|
4030
|
+
formats.append(
|
|
4031
|
+
{
|
|
4032
|
+
"id": fid,
|
|
4033
|
+
"type": PictType(ftype),
|
|
4034
|
+
"depth": depth,
|
|
4035
|
+
"direct": {
|
|
4036
|
+
"red": red,
|
|
4037
|
+
"red_mask": red_mask,
|
|
4038
|
+
"green": green,
|
|
4039
|
+
"green_mask": green_mask,
|
|
4040
|
+
"blue": blue,
|
|
4041
|
+
"blue_mask": blue_mask,
|
|
4042
|
+
"alpha": alpha,
|
|
4043
|
+
"alpha_mask": alpha_mask,
|
|
4044
|
+
},
|
|
4045
|
+
"colormap": colormap,
|
|
4046
|
+
}
|
|
4047
|
+
)
|
|
4048
|
+
|
|
4049
|
+
# screens: each has nDepth + fallback, then depths follow contiguously
|
|
4050
|
+
screens = []
|
|
4051
|
+
depth_headers = []
|
|
4052
|
+
for _ in range(num_screens):
|
|
4053
|
+
n_depth, fallback = struct.unpack_from("II", data, offset)
|
|
4054
|
+
offset += 8
|
|
4055
|
+
screens.append({"fallback": fallback, "n_depth": n_depth, "depths": []})
|
|
4056
|
+
depth_headers.append(n_depth)
|
|
4057
|
+
|
|
4058
|
+
depths = []
|
|
4059
|
+
for _ in range(num_depths):
|
|
4060
|
+
depth, n_visuals = struct.unpack_from("BxH4x", data, offset)
|
|
4061
|
+
offset += 8
|
|
4062
|
+
depths.append({"depth": depth, "n_visuals": n_visuals, "visuals": []})
|
|
4063
|
+
|
|
4064
|
+
visuals = []
|
|
4065
|
+
for _ in range(num_visuals):
|
|
4066
|
+
visual, fmt = struct.unpack_from("II", data, offset)
|
|
4067
|
+
offset += 8
|
|
4068
|
+
visuals.append({"visual": visual, "format": fmt})
|
|
4069
|
+
|
|
4070
|
+
# attach visuals → depths → screens
|
|
4071
|
+
vi = 0
|
|
4072
|
+
for d in depths:
|
|
4073
|
+
d["visuals"] = visuals[vi : vi + d["n_visuals"]]
|
|
4074
|
+
vi += d["n_visuals"]
|
|
4075
|
+
di = 0
|
|
4076
|
+
for s, n in zip(screens, depth_headers):
|
|
4077
|
+
s["depths"] = depths[di : di + n]
|
|
4078
|
+
di += n
|
|
4079
|
+
|
|
4080
|
+
subpixels = []
|
|
4081
|
+
if num_subpixel:
|
|
4082
|
+
for _ in range(num_subpixel):
|
|
4083
|
+
(sp,) = struct.unpack_from("I", data, offset)
|
|
4084
|
+
offset += 4
|
|
4085
|
+
try:
|
|
4086
|
+
subpixels.append(SubPixel(sp))
|
|
4087
|
+
except ValueError:
|
|
4088
|
+
subpixels.append(sp)
|
|
4089
|
+
# pad to 32-bit boundary already
|
|
4090
|
+
|
|
4091
|
+
result["formats"] = formats
|
|
4092
|
+
result["screens"] = screens
|
|
4093
|
+
result["subpixels"] = subpixels
|
|
4094
|
+
return result, offset
|
|
4095
|
+
|
|
4096
|
+
|
|
4097
|
+
def pack_render_create_picture(opcode, pid, drawable, format, **attrs):
|
|
4098
|
+
mask, values = _picture_values(**attrs)
|
|
4099
|
+
length = 5 + len(values)
|
|
4100
|
+
header = struct.pack(
|
|
4101
|
+
"BBHIIII",
|
|
4102
|
+
opcode,
|
|
4103
|
+
RenderCommand.CreatePicture,
|
|
4104
|
+
length,
|
|
4105
|
+
pid,
|
|
4106
|
+
drawable,
|
|
4107
|
+
format,
|
|
4108
|
+
mask,
|
|
4109
|
+
)
|
|
4110
|
+
body = b"".join(struct.pack("I", v) for v in values)
|
|
4111
|
+
return header + body
|
|
4112
|
+
|
|
4113
|
+
|
|
4114
|
+
def pack_render_change_picture(opcode, picture, **attrs):
|
|
4115
|
+
mask, values = _picture_values(**attrs)
|
|
4116
|
+
length = 3 + len(values)
|
|
4117
|
+
header = struct.pack(
|
|
4118
|
+
"BBHII",
|
|
4119
|
+
opcode,
|
|
4120
|
+
RenderCommand.ChangePicture,
|
|
4121
|
+
length,
|
|
4122
|
+
picture,
|
|
4123
|
+
mask,
|
|
4124
|
+
)
|
|
4125
|
+
body = b"".join(struct.pack("I", v) for v in values)
|
|
4126
|
+
return header + body
|
|
4127
|
+
|
|
4128
|
+
|
|
4129
|
+
def pack_render_set_picture_clip_rectangles(opcode, picture, x_origin, y_origin, rects):
|
|
4130
|
+
"""rects: sequence of (x, y, width, height)."""
|
|
4131
|
+
n = len(rects)
|
|
4132
|
+
length = 3 + n # each rect is 8 bytes = 2 CARD32 units
|
|
4133
|
+
header = struct.pack(
|
|
4134
|
+
"BBHIhh",
|
|
4135
|
+
opcode,
|
|
4136
|
+
RenderCommand.SetPictureClipRectangles,
|
|
4137
|
+
length,
|
|
4138
|
+
picture,
|
|
4139
|
+
x_origin,
|
|
4140
|
+
y_origin,
|
|
4141
|
+
)
|
|
4142
|
+
body = b"".join(struct.pack("hhHH", *r) for r in rects)
|
|
4143
|
+
return header + body
|
|
4144
|
+
|
|
4145
|
+
|
|
4146
|
+
def pack_render_free_picture(opcode, picture):
|
|
4147
|
+
return struct.pack(
|
|
4148
|
+
"BBHI", opcode, RenderCommand.FreePicture, 2, int(picture)
|
|
4149
|
+
)
|
|
4150
|
+
|
|
4151
|
+
|
|
4152
|
+
def pack_render_composite(
|
|
4153
|
+
opcode,
|
|
4154
|
+
op,
|
|
4155
|
+
src,
|
|
4156
|
+
mask,
|
|
4157
|
+
dst,
|
|
4158
|
+
src_x,
|
|
4159
|
+
src_y,
|
|
4160
|
+
mask_x,
|
|
4161
|
+
mask_y,
|
|
4162
|
+
dst_x,
|
|
4163
|
+
dst_y,
|
|
4164
|
+
width,
|
|
4165
|
+
height,
|
|
4166
|
+
):
|
|
4167
|
+
return struct.pack(
|
|
4168
|
+
"BBHBBHIII6hHH",
|
|
4169
|
+
opcode,
|
|
4170
|
+
RenderCommand.Composite,
|
|
4171
|
+
9,
|
|
4172
|
+
int(op),
|
|
4173
|
+
0,
|
|
4174
|
+
0,
|
|
4175
|
+
src,
|
|
4176
|
+
mask if mask is not None else 0,
|
|
4177
|
+
dst,
|
|
4178
|
+
src_x,
|
|
4179
|
+
src_y,
|
|
4180
|
+
mask_x,
|
|
4181
|
+
mask_y,
|
|
4182
|
+
dst_x,
|
|
4183
|
+
dst_y,
|
|
4184
|
+
width,
|
|
4185
|
+
height,
|
|
4186
|
+
)
|
|
4187
|
+
|
|
4188
|
+
|
|
4189
|
+
def pack_render_fill_rectangles(opcode, op, dst, color, rects):
|
|
4190
|
+
"""color: (r,g,b,a) floats 0..1 or ints 0..0xffff; rects: (x,y,w,h)."""
|
|
4191
|
+
n = len(rects)
|
|
4192
|
+
length = 5 + n * 2 # color=8 bytes=2 units; each rect=8 bytes=2 units
|
|
4193
|
+
header = struct.pack(
|
|
4194
|
+
"BBHBBHI",
|
|
4195
|
+
opcode,
|
|
4196
|
+
RenderCommand.FillRectangles,
|
|
4197
|
+
length,
|
|
4198
|
+
op,
|
|
4199
|
+
0,
|
|
4200
|
+
0,
|
|
4201
|
+
dst,
|
|
4202
|
+
)
|
|
4203
|
+
body = pack_render_color(*color) + b"".join(
|
|
4204
|
+
struct.pack("hhHH", *r) for r in rects
|
|
4205
|
+
)
|
|
4206
|
+
return header + body
|
|
4207
|
+
|
|
4208
|
+
|
|
4209
|
+
def pack_render_set_picture_transform(opcode, picture, matrix):
|
|
4210
|
+
"""matrix: 9 Fixed values (3×3 row-major) or floats."""
|
|
4211
|
+
vals = [fixed(v) for v in matrix]
|
|
4212
|
+
if len(vals) != 9:
|
|
4213
|
+
raise ValueError("transform matrix must have 9 elements")
|
|
4214
|
+
return struct.pack(
|
|
4215
|
+
"BBHI9i",
|
|
4216
|
+
opcode,
|
|
4217
|
+
RenderCommand.SetPictureTransform,
|
|
4218
|
+
11,
|
|
4219
|
+
picture,
|
|
4220
|
+
*vals,
|
|
4221
|
+
)
|
|
4222
|
+
|
|
4223
|
+
|
|
4224
|
+
def pack_render_set_picture_filter(opcode, picture, name, values=()):
|
|
4225
|
+
name_b = name.encode("latin-1") if isinstance(name, str) else bytes(name)
|
|
4226
|
+
n = len(name_b)
|
|
4227
|
+
pad = (4 - (n % 4)) % 4
|
|
4228
|
+
nvals = len(values)
|
|
4229
|
+
length = 3 + (n + pad) // 4 + nvals
|
|
4230
|
+
header = struct.pack(
|
|
4231
|
+
"BBHIHH",
|
|
4232
|
+
opcode,
|
|
4233
|
+
RenderCommand.SetPictureFilter,
|
|
4234
|
+
length,
|
|
4235
|
+
picture,
|
|
4236
|
+
n,
|
|
4237
|
+
0,
|
|
4238
|
+
)
|
|
4239
|
+
body = name_b + b"\0" * pad
|
|
4240
|
+
body += b"".join(struct.pack("i", fixed(v)) for v in values)
|
|
4241
|
+
return header + body
|
|
4242
|
+
|
|
4243
|
+
|
|
4244
|
+
def pack_render_query_filters(opcode, drawable):
|
|
4245
|
+
return struct.pack(
|
|
4246
|
+
"BBHI", opcode, RenderCommand.QueryFilters, 2, int(drawable)
|
|
4247
|
+
)
|
|
4248
|
+
|
|
4249
|
+
|
|
4250
|
+
def unpack_render_query_filters(data, offset=0):
|
|
4251
|
+
result, offset = unpack_reply_head(data, offset)
|
|
4252
|
+
num_aliases, num_filters = struct.unpack_from("II", data, offset)
|
|
4253
|
+
offset += 8 + 16
|
|
4254
|
+
aliases = list(struct.unpack_from(f"{num_aliases}H", data, offset))
|
|
4255
|
+
offset += num_aliases * 2
|
|
4256
|
+
if num_aliases % 2:
|
|
4257
|
+
offset += 2 # pad to 32-bit
|
|
4258
|
+
filters = []
|
|
4259
|
+
for _ in range(num_filters):
|
|
4260
|
+
(nbytes,) = struct.unpack_from("B", data, offset)
|
|
4261
|
+
offset += 1
|
|
4262
|
+
name = data[offset : offset + nbytes].decode("latin-1")
|
|
4263
|
+
offset += nbytes
|
|
4264
|
+
filters.append(name)
|
|
4265
|
+
# pad remainder of reply
|
|
4266
|
+
result["aliases"] = aliases
|
|
4267
|
+
result["filters"] = filters
|
|
4268
|
+
return result, offset
|
|
4269
|
+
|
|
4270
|
+
|
|
4271
|
+
def pack_render_create_solid_fill(opcode, pid, color):
|
|
4272
|
+
return struct.pack(
|
|
4273
|
+
"BBHI",
|
|
4274
|
+
opcode,
|
|
4275
|
+
RenderCommand.CreateSolidFill,
|
|
4276
|
+
4,
|
|
4277
|
+
pid,
|
|
4278
|
+
) + pack_render_color(*color)
|
|
4279
|
+
|
|
4280
|
+
|
|
4281
|
+
def pack_render_create_linear_gradient(opcode, pid, p1, p2, stops):
|
|
4282
|
+
"""stops: sequence of (offset, (r,g,b,a)) with offset in 0..1."""
|
|
4283
|
+
n = len(stops)
|
|
4284
|
+
length = 7 + n + n * 2 # points + nStops + n Fixed + n RenderColor
|
|
4285
|
+
header = struct.pack(
|
|
4286
|
+
"BBHI4iI",
|
|
4287
|
+
opcode,
|
|
4288
|
+
RenderCommand.CreateLinearGradient,
|
|
4289
|
+
length,
|
|
4290
|
+
pid,
|
|
4291
|
+
fixed(p1[0]),
|
|
4292
|
+
fixed(p1[1]),
|
|
4293
|
+
fixed(p2[0]),
|
|
4294
|
+
fixed(p2[1]),
|
|
4295
|
+
n,
|
|
4296
|
+
)
|
|
4297
|
+
body = b"".join(struct.pack("i", fixed(s[0])) for s in stops)
|
|
4298
|
+
body += b"".join(pack_render_color(*s[1]) for s in stops)
|
|
4299
|
+
return header + body
|
|
4300
|
+
|
|
4301
|
+
|
|
4302
|
+
def pack_render_create_radial_gradient(
|
|
4303
|
+
opcode, pid, inner, outer, inner_radius, outer_radius, stops
|
|
4304
|
+
):
|
|
4305
|
+
n = len(stops)
|
|
4306
|
+
length = 9 + n + n * 2
|
|
4307
|
+
header = struct.pack(
|
|
4308
|
+
"BBHI4i2iI",
|
|
4309
|
+
opcode,
|
|
4310
|
+
RenderCommand.CreateRadialGradient,
|
|
4311
|
+
length,
|
|
4312
|
+
pid,
|
|
4313
|
+
fixed(inner[0]),
|
|
4314
|
+
fixed(inner[1]),
|
|
4315
|
+
fixed(outer[0]),
|
|
4316
|
+
fixed(outer[1]),
|
|
4317
|
+
fixed(inner_radius),
|
|
4318
|
+
fixed(outer_radius),
|
|
4319
|
+
n,
|
|
4320
|
+
)
|
|
4321
|
+
body = b"".join(struct.pack("i", fixed(s[0])) for s in stops)
|
|
4322
|
+
body += b"".join(pack_render_color(*s[1]) for s in stops)
|
|
4323
|
+
return header + body
|
|
4324
|
+
|
|
4325
|
+
|
|
4326
|
+
def pack_render_create_conical_gradient(opcode, pid, center, angle, stops):
|
|
4327
|
+
n = len(stops)
|
|
4328
|
+
length = 6 + n + n * 2
|
|
4329
|
+
header = struct.pack(
|
|
4330
|
+
"BBHI2iiI",
|
|
4331
|
+
opcode,
|
|
4332
|
+
RenderCommand.CreateConicalGradient,
|
|
4333
|
+
length,
|
|
4334
|
+
pid,
|
|
4335
|
+
fixed(center[0]),
|
|
4336
|
+
fixed(center[1]),
|
|
4337
|
+
fixed(angle),
|
|
4338
|
+
n,
|
|
4339
|
+
)
|
|
4340
|
+
body = b"".join(struct.pack("i", fixed(s[0])) for s in stops)
|
|
4341
|
+
body += b"".join(pack_render_color(*s[1]) for s in stops)
|
|
4342
|
+
return header + body
|
|
4343
|
+
|
|
4344
|
+
|
|
4345
|
+
def pack_render_trapezoids(opcode, op, src, dst, mask_format, src_x, src_y, traps):
|
|
4346
|
+
"""traps: sequence of (top, bottom, left_p1, left_p2, right_p1, right_p2)
|
|
4347
|
+
each point is (x, y); top/bottom are Fixed y values.
|
|
4348
|
+
"""
|
|
4349
|
+
n = len(traps)
|
|
4350
|
+
length = 6 + n * 10 # each trapezoid = 40 bytes = 10 units
|
|
4351
|
+
header = struct.pack(
|
|
4352
|
+
"BBHBBHIIIhh",
|
|
4353
|
+
opcode,
|
|
4354
|
+
RenderCommand.Trapezoids,
|
|
4355
|
+
length,
|
|
4356
|
+
op,
|
|
4357
|
+
0,
|
|
4358
|
+
0,
|
|
4359
|
+
src,
|
|
4360
|
+
dst,
|
|
4361
|
+
mask_format if mask_format else 0,
|
|
4362
|
+
src_x,
|
|
4363
|
+
src_y,
|
|
4364
|
+
)
|
|
4365
|
+
body = b""
|
|
4366
|
+
for top, bottom, lp1, lp2, rp1, rp2 in traps:
|
|
4367
|
+
body += struct.pack(
|
|
4368
|
+
"10i",
|
|
4369
|
+
fixed(top),
|
|
4370
|
+
fixed(bottom),
|
|
4371
|
+
fixed(lp1[0]),
|
|
4372
|
+
fixed(lp1[1]),
|
|
4373
|
+
fixed(lp2[0]),
|
|
4374
|
+
fixed(lp2[1]),
|
|
4375
|
+
fixed(rp1[0]),
|
|
4376
|
+
fixed(rp1[1]),
|
|
4377
|
+
fixed(rp2[0]),
|
|
4378
|
+
fixed(rp2[1]),
|
|
4379
|
+
)
|
|
4380
|
+
return header + body
|
|
4381
|
+
|
|
4382
|
+
|
|
4383
|
+
def pack_render_triangles(opcode, op, src, dst, mask_format, src_x, src_y, tris):
|
|
4384
|
+
"""tris: sequence of ((x1,y1),(x2,y2),(x3,y3))."""
|
|
4385
|
+
n = len(tris)
|
|
4386
|
+
length = 6 + n * 6
|
|
4387
|
+
header = struct.pack(
|
|
4388
|
+
"BBHBBHIIIhh",
|
|
4389
|
+
opcode,
|
|
4390
|
+
RenderCommand.Triangles,
|
|
4391
|
+
length,
|
|
4392
|
+
op,
|
|
4393
|
+
0,
|
|
4394
|
+
0,
|
|
4395
|
+
src,
|
|
4396
|
+
dst,
|
|
4397
|
+
mask_format if mask_format else 0,
|
|
4398
|
+
src_x,
|
|
4399
|
+
src_y,
|
|
4400
|
+
)
|
|
4401
|
+
body = b""
|
|
4402
|
+
for p1, p2, p3 in tris:
|
|
4403
|
+
body += struct.pack(
|
|
4404
|
+
"6i",
|
|
4405
|
+
fixed(p1[0]),
|
|
4406
|
+
fixed(p1[1]),
|
|
4407
|
+
fixed(p2[0]),
|
|
4408
|
+
fixed(p2[1]),
|
|
4409
|
+
fixed(p3[0]),
|
|
4410
|
+
fixed(p3[1]),
|
|
4411
|
+
)
|
|
4412
|
+
return header + body
|
|
4413
|
+
|
|
4414
|
+
|
|
4415
|
+
def pack_render_create_glyphset(opcode, gsid, format):
|
|
4416
|
+
return struct.pack(
|
|
4417
|
+
"BBHII",
|
|
4418
|
+
opcode,
|
|
4419
|
+
RenderCommand.CreateGlyphSet,
|
|
4420
|
+
3,
|
|
4421
|
+
gsid,
|
|
4422
|
+
format,
|
|
4423
|
+
)
|
|
4424
|
+
|
|
4425
|
+
|
|
4426
|
+
def pack_render_free_glyphset(opcode, gsid):
|
|
4427
|
+
return struct.pack(
|
|
4428
|
+
"BBHI", opcode, RenderCommand.FreeGlyphSet, 2, gsid
|
|
4429
|
+
)
|
|
4430
|
+
|
|
4431
|
+
|
|
4432
|
+
def pack_render_add_glyphs(opcode, gsid, glyph_ids, glyph_infos, data):
|
|
4433
|
+
"""glyph_ids: list of CARD32; glyph_infos: list of (width,height,x,y,xOff,yOff);
|
|
4434
|
+
data: concatenated glyph image bytes (padded per glyph to 32-bit).
|
|
4435
|
+
"""
|
|
4436
|
+
n = len(glyph_ids)
|
|
4437
|
+
if n != len(glyph_infos):
|
|
4438
|
+
raise ValueError("glyph_ids and glyph_infos length mismatch")
|
|
4439
|
+
info_bytes = b"".join(
|
|
4440
|
+
struct.pack("HHhh hh", *info) for info in glyph_infos
|
|
4441
|
+
)
|
|
4442
|
+
# each GlyphInfo is 12 bytes
|
|
4443
|
+
info_bytes = b"".join(
|
|
4444
|
+
struct.pack("HHhhhh", w, h, x, y, xo, yo)
|
|
4445
|
+
for (w, h, x, y, xo, yo) in glyph_infos
|
|
4446
|
+
)
|
|
4447
|
+
ids_bytes = b"".join(struct.pack("I", int(g)) for g in glyph_ids)
|
|
4448
|
+
# pad image data to 32-bit
|
|
4449
|
+
pad = (4 - (len(data) % 4)) % 4
|
|
4450
|
+
payload = ids_bytes + info_bytes + data + b"\0" * pad
|
|
4451
|
+
length = 3 + len(payload) // 4
|
|
4452
|
+
header = struct.pack(
|
|
4453
|
+
"BBHII",
|
|
4454
|
+
opcode,
|
|
4455
|
+
RenderCommand.AddGlyphs,
|
|
4456
|
+
length,
|
|
4457
|
+
gsid,
|
|
4458
|
+
n,
|
|
4459
|
+
)
|
|
4460
|
+
return header + payload
|
|
4461
|
+
|
|
4462
|
+
|
|
4463
|
+
def pack_render_free_glyphs(opcode, gsid, glyph_ids):
|
|
4464
|
+
n = len(glyph_ids)
|
|
4465
|
+
length = 2 + n
|
|
4466
|
+
header = struct.pack(
|
|
4467
|
+
"BBHI", opcode, RenderCommand.FreeGlyphs, length, int(gsid)
|
|
4468
|
+
)
|
|
4469
|
+
body = b"".join(struct.pack("I", int(g)) for g in glyph_ids)
|
|
4470
|
+
return header + body
|
|
4471
|
+
|
|
4472
|
+
|
|
4473
|
+
def pack_render_composite_glyphs8(
|
|
4474
|
+
opcode, op, src, dst, mask_format, glyphset, src_x, src_y, elements
|
|
4475
|
+
):
|
|
4476
|
+
"""elements: sequence of (delta_x, delta_y, glyphs_bytes_or_str).
|
|
4477
|
+
|
|
4478
|
+
Each element becomes an xGlyphElt: 1-byte length + deltas + glyph 8-bit ids,
|
|
4479
|
+
padded to 4 bytes.
|
|
4480
|
+
"""
|
|
4481
|
+
body = b""
|
|
4482
|
+
for dx, dy, glyphs in elements:
|
|
4483
|
+
if isinstance(glyphs, str):
|
|
4484
|
+
glyphs = glyphs.encode("latin-1")
|
|
4485
|
+
glyphs = bytes(glyphs)
|
|
4486
|
+
n = len(glyphs)
|
|
4487
|
+
if n > 252:
|
|
4488
|
+
raise ValueError("glyph elt too long (max 252)")
|
|
4489
|
+
elt = struct.pack("BBHhh", n, 0, 0, int(dx), int(dy)) + glyphs
|
|
4490
|
+
pad = (4 - (len(elt) % 4)) % 4
|
|
4491
|
+
body += elt + b"\0" * pad
|
|
4492
|
+
length = 7 + len(body) // 4
|
|
4493
|
+
header = struct.pack(
|
|
4494
|
+
"BBHBBHIIIIhh",
|
|
4495
|
+
opcode,
|
|
4496
|
+
RenderCommand.CompositeGlyphs8,
|
|
4497
|
+
length,
|
|
4498
|
+
op,
|
|
4499
|
+
0,
|
|
4500
|
+
0,
|
|
4501
|
+
src,
|
|
4502
|
+
dst,
|
|
4503
|
+
mask_format if mask_format else 0,
|
|
4504
|
+
glyphset,
|
|
4505
|
+
src_x,
|
|
4506
|
+
src_y,
|
|
4507
|
+
)
|
|
4508
|
+
return header + body
|
|
4509
|
+
|
|
4510
|
+
|
|
4511
|
+
class Render(Extension):
|
|
4512
|
+
"""X Rendering Extension (RENDER).
|
|
4513
|
+
|
|
4514
|
+
Alpha compositing, transforms, gradients, and glyph rendering.
|
|
4515
|
+
|
|
4516
|
+
Query with::
|
|
4517
|
+
|
|
4518
|
+
render = await display.query_extension("RENDER")
|
|
4519
|
+
ver = await render.query_version()
|
|
4520
|
+
formats = await render.query_pict_formats()
|
|
4521
|
+
"""
|
|
4522
|
+
|
|
4523
|
+
Commands = RenderCommand
|
|
4524
|
+
|
|
4525
|
+
BaseBadPictFormat = 0
|
|
4526
|
+
BaseBadPicture = 1
|
|
4527
|
+
BaseBadPictOp = 2
|
|
4528
|
+
BaseBadGlyphSet = 3
|
|
4529
|
+
BaseBadGlyph = 4
|
|
4530
|
+
|
|
4531
|
+
def __init__(self, display, info):
|
|
4532
|
+
super().__init__(display, info)
|
|
4533
|
+
base = info["base_error"]
|
|
4534
|
+
self.BadPictFormat = base + self.BaseBadPictFormat
|
|
4535
|
+
self.BadPicture = base + self.BaseBadPicture
|
|
4536
|
+
self.BadPictOp = base + self.BaseBadPictOp
|
|
4537
|
+
self.BadGlyphSet = base + self.BaseBadGlyphSet
|
|
4538
|
+
self.BadGlyph = base + self.BaseBadGlyph
|
|
4539
|
+
self.errors = {
|
|
4540
|
+
self.BadPictFormat: "BadPictFormat",
|
|
4541
|
+
self.BadPicture: "BadPicture",
|
|
4542
|
+
self.BadPictOp: "BadPictOp",
|
|
4543
|
+
self.BadGlyphSet: "BadGlyphSet",
|
|
4544
|
+
self.BadGlyph: "BadGlyph",
|
|
4545
|
+
}
|
|
4546
|
+
self.commands = {self.code: "Render"}
|
|
4547
|
+
self._formats = None
|
|
4548
|
+
|
|
4549
|
+
async def query_version(self, major=0, minor=11):
|
|
4550
|
+
payload = pack_render_query_version(self.code, major, minor)
|
|
4551
|
+
return await self.display.write_read(payload, unpack_render_query_version)
|
|
4552
|
+
|
|
4553
|
+
async def query_pict_formats(self):
|
|
4554
|
+
payload = pack_render_query_pict_formats(self.code)
|
|
4555
|
+
reply = await self.display.write_read(
|
|
4556
|
+
payload, unpack_render_query_pict_formats
|
|
4557
|
+
)
|
|
4558
|
+
self._formats = reply
|
|
4559
|
+
return reply
|
|
4560
|
+
|
|
4561
|
+
def find_standard_format(self, depth, alpha=True, formats=None):
|
|
4562
|
+
"""Pick a direct PictFormat id matching *depth* (and optional alpha).
|
|
4563
|
+
|
|
4564
|
+
Common choices: depth=32 (ARGB), depth=24 (RGB), depth=8 (A).
|
|
4565
|
+
"""
|
|
4566
|
+
formats = formats or (self._formats or {}).get("formats") or []
|
|
4567
|
+
best = None
|
|
4568
|
+
for f in formats:
|
|
4569
|
+
if f["type"] != PictType.Direct or f["depth"] != depth:
|
|
4570
|
+
continue
|
|
4571
|
+
d = f["direct"]
|
|
4572
|
+
has_alpha = d["alpha_mask"] != 0
|
|
4573
|
+
if alpha and not has_alpha:
|
|
4574
|
+
continue
|
|
4575
|
+
if not alpha and has_alpha and depth != 8:
|
|
4576
|
+
# prefer non-alpha when requested for 24-bit
|
|
4577
|
+
continue
|
|
4578
|
+
best = f["id"]
|
|
4579
|
+
if alpha == has_alpha:
|
|
4580
|
+
return best
|
|
4581
|
+
return best
|
|
4582
|
+
|
|
4583
|
+
async def create_picture(self, drawable, format, pid=None, **attrs):
|
|
4584
|
+
"""Create a Picture for *drawable* using PictFormat *format*."""
|
|
4585
|
+
if pid is None:
|
|
4586
|
+
pid = self.display.resources.allocate()
|
|
4587
|
+
payload = pack_render_create_picture(
|
|
4588
|
+
self.code, pid, drawable, format, **attrs
|
|
4589
|
+
)
|
|
4590
|
+
self.display.write(payload)
|
|
4591
|
+
return pid
|
|
4592
|
+
|
|
4593
|
+
async def change_picture(self, picture, **attrs):
|
|
4594
|
+
payload = pack_render_change_picture(self.code, picture, **attrs)
|
|
4595
|
+
self.display.write(payload)
|
|
4596
|
+
|
|
4597
|
+
async def set_clip_rectangles(self, picture, x_origin, y_origin, rects):
|
|
4598
|
+
payload = pack_render_set_picture_clip_rectangles(
|
|
4599
|
+
self.code, picture, x_origin, y_origin, rects
|
|
4600
|
+
)
|
|
4601
|
+
self.display.write(payload)
|
|
4602
|
+
|
|
4603
|
+
async def free_picture(self, picture):
|
|
4604
|
+
self.display.write(pack_render_free_picture(self.code, picture))
|
|
4605
|
+
|
|
4606
|
+
async def composite(
|
|
4607
|
+
self,
|
|
4608
|
+
op,
|
|
4609
|
+
src,
|
|
4610
|
+
dst,
|
|
4611
|
+
dst_x,
|
|
4612
|
+
dst_y,
|
|
4613
|
+
width,
|
|
4614
|
+
height,
|
|
4615
|
+
src_x=0,
|
|
4616
|
+
src_y=0,
|
|
4617
|
+
mask=None,
|
|
4618
|
+
mask_x=0,
|
|
4619
|
+
mask_y=0,
|
|
4620
|
+
):
|
|
4621
|
+
payload = pack_render_composite(
|
|
4622
|
+
self.code,
|
|
4623
|
+
op,
|
|
4624
|
+
src,
|
|
4625
|
+
mask,
|
|
4626
|
+
dst,
|
|
4627
|
+
src_x,
|
|
4628
|
+
src_y,
|
|
4629
|
+
mask_x,
|
|
4630
|
+
mask_y,
|
|
4631
|
+
dst_x,
|
|
4632
|
+
dst_y,
|
|
4633
|
+
width,
|
|
4634
|
+
height,
|
|
4635
|
+
)
|
|
4636
|
+
self.display.write(payload)
|
|
4637
|
+
|
|
4638
|
+
async def fill_rectangles(self, op, dst, color, rects):
|
|
4639
|
+
"""Fill *rects* on *dst* with solid *color* using operator *op*.
|
|
4640
|
+
|
|
4641
|
+
*color* is ``(r, g, b, a)`` with channels in 0..1 (float) or 0..65535.
|
|
4642
|
+
*rects* is a sequence of ``(x, y, width, height)``.
|
|
4643
|
+
"""
|
|
4644
|
+
payload = pack_render_fill_rectangles(self.code, op, dst, color, rects)
|
|
4645
|
+
self.display.write(payload)
|
|
4646
|
+
|
|
4647
|
+
async def set_transform(self, picture, matrix):
|
|
4648
|
+
"""Set a 3×3 projective transform (9 floats or Fixed)."""
|
|
4649
|
+
payload = pack_render_set_picture_transform(self.code, picture, matrix)
|
|
4650
|
+
self.display.write(payload)
|
|
4651
|
+
|
|
4652
|
+
async def set_filter(self, picture, name, values=()):
|
|
4653
|
+
"""Set filter name (e.g. ``\"bilinear\"``, ``\"nearest\"``) and params."""
|
|
4654
|
+
payload = pack_render_set_picture_filter(
|
|
4655
|
+
self.code, picture, name, values
|
|
4656
|
+
)
|
|
4657
|
+
self.display.write(payload)
|
|
4658
|
+
|
|
4659
|
+
async def query_filters(self, drawable):
|
|
4660
|
+
payload = pack_render_query_filters(self.code, drawable)
|
|
4661
|
+
return await self.display.write_read(payload, unpack_render_query_filters)
|
|
4662
|
+
|
|
4663
|
+
async def create_solid_fill(self, color, pid=None):
|
|
4664
|
+
if pid is None:
|
|
4665
|
+
pid = self.display.resources.allocate()
|
|
4666
|
+
payload = pack_render_create_solid_fill(self.code, pid, color)
|
|
4667
|
+
self.display.write(payload)
|
|
4668
|
+
return pid
|
|
4669
|
+
|
|
4670
|
+
async def create_linear_gradient(self, p1, p2, stops, pid=None):
|
|
4671
|
+
if pid is None:
|
|
4672
|
+
pid = self.display.resources.allocate()
|
|
4673
|
+
payload = pack_render_create_linear_gradient(
|
|
4674
|
+
self.code, pid, p1, p2, stops
|
|
4675
|
+
)
|
|
4676
|
+
self.display.write(payload)
|
|
4677
|
+
return pid
|
|
4678
|
+
|
|
4679
|
+
async def create_radial_gradient(
|
|
4680
|
+
self, inner, outer, inner_radius, outer_radius, stops, pid=None
|
|
4681
|
+
):
|
|
4682
|
+
if pid is None:
|
|
4683
|
+
pid = self.display.resources.allocate()
|
|
4684
|
+
payload = pack_render_create_radial_gradient(
|
|
4685
|
+
self.code, pid, inner, outer, inner_radius, outer_radius, stops
|
|
4686
|
+
)
|
|
4687
|
+
self.display.write(payload)
|
|
4688
|
+
return pid
|
|
4689
|
+
|
|
4690
|
+
async def create_conical_gradient(self, center, angle, stops, pid=None):
|
|
4691
|
+
if pid is None:
|
|
4692
|
+
pid = self.display.resources.allocate()
|
|
4693
|
+
payload = pack_render_create_conical_gradient(
|
|
4694
|
+
self.code, pid, center, angle, stops
|
|
4695
|
+
)
|
|
4696
|
+
self.display.write(payload)
|
|
4697
|
+
return pid
|
|
4698
|
+
|
|
4699
|
+
async def trapezoids(
|
|
4700
|
+
self, op, src, dst, src_x, src_y, traps, mask_format=0
|
|
4701
|
+
):
|
|
4702
|
+
payload = pack_render_trapezoids(
|
|
4703
|
+
self.code, op, src, dst, mask_format, src_x, src_y, traps
|
|
4704
|
+
)
|
|
4705
|
+
self.display.write(payload)
|
|
4706
|
+
|
|
4707
|
+
async def triangles(
|
|
4708
|
+
self, op, src, dst, src_x, src_y, tris, mask_format=0
|
|
4709
|
+
):
|
|
4710
|
+
payload = pack_render_triangles(
|
|
4711
|
+
self.code, op, src, dst, mask_format, src_x, src_y, tris
|
|
4712
|
+
)
|
|
4713
|
+
self.display.write(payload)
|
|
4714
|
+
|
|
4715
|
+
async def create_glyphset(self, format, gsid=None):
|
|
4716
|
+
if gsid is None:
|
|
4717
|
+
gsid = self.display.resources.allocate()
|
|
4718
|
+
payload = pack_render_create_glyphset(self.code, gsid, format)
|
|
4719
|
+
self.display.write(payload)
|
|
4720
|
+
return gsid
|
|
4721
|
+
|
|
4722
|
+
async def free_glyphset(self, gsid):
|
|
4723
|
+
self.display.write(pack_render_free_glyphset(self.code, gsid))
|
|
4724
|
+
|
|
4725
|
+
async def add_glyphs(self, gsid, glyph_ids, glyph_infos, data):
|
|
4726
|
+
payload = pack_render_add_glyphs(
|
|
4727
|
+
self.code, gsid, glyph_ids, glyph_infos, data
|
|
4728
|
+
)
|
|
4729
|
+
self.display.write(payload)
|
|
4730
|
+
|
|
4731
|
+
async def free_glyphs(self, gsid, glyph_ids):
|
|
4732
|
+
payload = pack_render_free_glyphs(self.code, gsid, glyph_ids)
|
|
4733
|
+
self.display.write(payload)
|
|
4734
|
+
|
|
4735
|
+
async def composite_glyphs8(
|
|
4736
|
+
self,
|
|
4737
|
+
op,
|
|
4738
|
+
src,
|
|
4739
|
+
dst,
|
|
4740
|
+
glyphset,
|
|
4741
|
+
src_x,
|
|
4742
|
+
src_y,
|
|
4743
|
+
elements,
|
|
4744
|
+
mask_format=0,
|
|
4745
|
+
):
|
|
4746
|
+
payload = pack_render_composite_glyphs8(
|
|
4747
|
+
self.code,
|
|
4748
|
+
op,
|
|
4749
|
+
src,
|
|
4750
|
+
dst,
|
|
4751
|
+
mask_format,
|
|
4752
|
+
glyphset,
|
|
4753
|
+
src_x,
|
|
4754
|
+
src_y,
|
|
4755
|
+
elements,
|
|
4756
|
+
)
|
|
4757
|
+
self.display.write(payload)
|
|
4758
|
+
|
|
4759
|
+
|
|
3774
4760
|
EXTENSIONS = {
|
|
3775
4761
|
"MIT-SHM": SharedMemory,
|
|
3776
4762
|
"DOUBLE-BUFFER": DoubleBuffer,
|
|
@@ -3778,6 +4764,7 @@ EXTENSIONS = {
|
|
|
3778
4764
|
"GLX": GLX,
|
|
3779
4765
|
"DRI3": DRI3,
|
|
3780
4766
|
"Present": Present,
|
|
4767
|
+
"RENDER": Render,
|
|
3781
4768
|
}
|
|
3782
4769
|
|
|
3783
4770
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|