Skip to content

Commit c9d2428

Browse files
CyberShadowvasily-v-ryabov
authored andcommitted
Add screensaver extension
1 parent bb8685a commit c9d2428

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

Xlib/ext/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
('DAMAGE', 'damage'),
4141
('DPMS', 'dpms'),
4242
('X-Resource', 'res'),
43+
('MIT-SCREEN-SAVER', 'screensaver'),
4344
]
4445

4546
__all__ = map(lambda x: x[1], __extensions__)

Xlib/ext/screensaver.py

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Xlib.ext.screensaver -- X ScreenSaver extension module
2+
#
3+
# Copyright (C) 2022 Vladimir Panteleev <git@cy.md>
4+
#
5+
# This library is free software; you can redistribute it and/or
6+
# modify it under the terms of the GNU Lesser General Public License
7+
# as published by the Free Software Foundation; either version 2.1
8+
# of the License, or (at your option) any later version.
9+
#
10+
# This library is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13+
# See the GNU Lesser General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Lesser General Public
16+
# License along with this library; if not, write to the
17+
# Free Software Foundation, Inc.,
18+
# 51 Franklin Street,
19+
# Fifth Floor,
20+
# Boston, MA 02110-1301 USA
21+
22+
"""This extension allows registering the client as an X screensaver,
23+
or query information about the current screensaver.
24+
25+
For detailed description see any of the following documents.
26+
Protocol specification:
27+
https://www.x.org/releases/X11R7.7/doc/scrnsaverproto/saver.html
28+
XCB Protocol specification:
29+
https://cgit.freedesktop.org/xcb/proto/tree/src/screensaver.xml
30+
31+
"""
32+
33+
from Xlib import X
34+
from Xlib.protocol import rq, structs
35+
36+
extname = 'MIT-SCREEN-SAVER'
37+
38+
# Event members
39+
NotifyMask = 1
40+
CycleMask = 2
41+
42+
# Notify state
43+
StateOff = 0
44+
StateOn = 1
45+
StateCycle = 2
46+
47+
# Notify kind
48+
KindBlanked = 0
49+
KindInternal = 1
50+
KindExternal = 2
51+
52+
class QueryVersion(rq.ReplyRequest):
53+
_request = rq.Struct(
54+
rq.Card8('opcode'),
55+
rq.Opcode(0),
56+
rq.RequestLength(),
57+
rq.Card8('major_version'),
58+
rq.Card8('minor_version'),
59+
rq.Pad(2),
60+
)
61+
62+
_reply = rq.Struct(
63+
rq.ReplyCode(),
64+
rq.Pad(1),
65+
rq.Card16('sequence_number'),
66+
rq.ReplyLength(),
67+
rq.Card8('major_version'),
68+
rq.Card8('minor_version'),
69+
rq.Pad(22),
70+
)
71+
72+
def query_version(self):
73+
return QueryVersion(display=self.display,
74+
opcode=self.display.get_extension_major(extname),
75+
major_version=1,
76+
minor_version=0)
77+
78+
79+
class QueryInfo(rq.ReplyRequest):
80+
_request = rq.Struct(
81+
rq.Card8('opcode'),
82+
rq.Opcode(1),
83+
rq.RequestLength(),
84+
rq.Drawable('drawable'),
85+
)
86+
87+
_reply = rq.Struct(
88+
rq.ReplyCode(),
89+
rq.Card8('state'),
90+
rq.Card16('sequence_number'),
91+
rq.ReplyLength(),
92+
rq.Window('saver_window'),
93+
rq.Card32('til_or_since'),
94+
rq.Card32('idle'),
95+
rq.Card32('event_mask'), # rq.Set('event_mask', 4, (NotifyMask, CycleMask)),
96+
rq.Card8('kind'),
97+
rq.Pad(10),
98+
)
99+
100+
def query_info(self):
101+
return QueryInfo(display=self.display,
102+
opcode=self.display.get_extension_major(extname),
103+
drawable=self,
104+
)
105+
106+
107+
class SelectInput(rq.Request):
108+
_request = rq.Struct(
109+
rq.Card8('opcode'),
110+
rq.Opcode(2),
111+
rq.RequestLength(),
112+
rq.Drawable('drawable'),
113+
rq.Card32('event_mask'), # rq.Set('event_mask', 4, (NotifyMask, CycleMask)),
114+
)
115+
116+
def select_input(self, mask):
117+
return SelectInput(display=self.display,
118+
opcode=self.display.get_extension_major(extname),
119+
drawable=self,
120+
event_mask=mask,
121+
)
122+
123+
124+
class SetAttributes(rq.Request):
125+
_request = rq.Struct(
126+
rq.Card8('opcode'),
127+
rq.Opcode(3),
128+
rq.RequestLength(),
129+
rq.Drawable('drawable'),
130+
rq.Int16('x'),
131+
rq.Int16('y'),
132+
rq.Card16('width'),
133+
rq.Card16('height'),
134+
rq.Card16('border_width'),
135+
rq.Set('window_class', 1, (X.CopyFromParent, X.InputOutput, X.InputOnly)),
136+
rq.Card8('depth'),
137+
rq.Card32('visual'),
138+
structs.WindowValues('attrs'),
139+
)
140+
141+
def set_attributes(self, x, y, width, height, border_width,
142+
window_class = X.CopyFromParent,
143+
depth = X.CopyFromParent,
144+
visual = X.CopyFromParent,
145+
onerror = None,
146+
**keys):
147+
return SetAttributes(display=self.display,
148+
onerror = onerror,
149+
opcode=self.display.get_extension_major(extname),
150+
drawable=self,
151+
x = x,
152+
y = y,
153+
width = width,
154+
height = height,
155+
border_width = border_width,
156+
window_class = window_class,
157+
depth = depth,
158+
visual = visual,
159+
attrs = keys)
160+
161+
162+
class UnsetAttributes(rq.Request):
163+
_request = rq.Struct(
164+
rq.Card8('opcode'),
165+
rq.Opcode(4),
166+
rq.RequestLength(),
167+
rq.Drawable('drawable'),
168+
)
169+
170+
def unset_attributes(self, onerror = None):
171+
return UnsetAttributes(display=self.display,
172+
onerror = onerror,
173+
opcode=self.display.get_extension_major(extname),
174+
drawable=self)
175+
176+
177+
class Notify(rq.Event):
178+
_code = None
179+
_fields = rq.Struct(
180+
rq.Card8('type'),
181+
rq.Set('state', 1, (StateOff, StateOn, StateCycle)),
182+
rq.Card16('sequence_number'),
183+
rq.Card32('timestamp'),
184+
rq.Window('root'),
185+
rq.Window('window'),
186+
rq.Set('kind', 1, (KindBlanked, KindInternal, KindExternal)),
187+
rq.Bool('forced'),
188+
rq.Pad(14),
189+
)
190+
191+
def init(disp, info):
192+
disp.extension_add_method('display', 'screensaver_query_version', query_version)
193+
disp.extension_add_method('drawable', 'screensaver_query_info', query_info)
194+
disp.extension_add_method('drawable', 'screensaver_select_input', select_input)
195+
disp.extension_add_method('drawable', 'screensaver_set_attributes', set_attributes)
196+
disp.extension_add_method('drawable', 'screensaver_unset_attributes', unset_attributes)
197+
198+
disp.extension_add_event(info.first_event + 0, Notify)

0 commit comments

Comments
 (0)