Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/server/dbus/dbus_server.py : 94%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python
2# This file is part of Xpra.
3# Copyright (C) 2015-2019 Antoine Martin <antoine@xpra.org>
4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
5# later version. See the file COPYING for details.
7from collections import namedtuple
8import dbus.service
10from xpra.dbus.helper import dbus_to_native, native_to_dbus
11from xpra.dbus.common import init_session_bus
12from xpra.server.dbus.dbus_server_base import DBUS_Server_Base, INTERFACE, BUS_NAME
13from xpra.util import parse_scaling_value, from0to100, DETACH_REQUEST
14from xpra.log import (
15 Logger,
16 add_debug_category, remove_debug_category,
17 disable_debug_for, enable_debug_for,
18 )
19log = Logger("dbus", "server")
22Rectangle = namedtuple("Workarea", "x,y,width,height")
25def n(*args):
26 return dbus_to_native(*args)
27def ni(*args):
28 return int(n(*args))
29def ns(*args):
30 return str(n(*args))
31def nb(*args):
32 return bool(n(*args))
35class DBUS_Server(DBUS_Server_Base):
37 def __init__(self, server=None, extra=""):
38 bus = init_session_bus()
39 name = BUS_NAME
40 if extra:
41 name += extra.replace(".", "_").replace(":", "_")
42 super().__init__(bus, server, name)
43 self._properties.update({
44 "idle-timeout" : ("idle_timeout", ni),
45 "server-idle-timeout" : ("server_idle_timeout", ni),
46 "name" : ("session_name", ns),
47 })
50 @dbus.service.method(INTERFACE, in_signature='i')
51 def Focus(self, wid):
52 wid = ni(wid)
53 self.log(".Focus(%i)", wid)
54 self.server.control_command_focus(wid)
56 @dbus.service.method(INTERFACE, in_signature='')
57 def Suspend(self):
58 self.log(".Suspend()")
59 self.server.control_command_suspend()
61 @dbus.service.method(INTERFACE, in_signature='')
62 def Resume(self):
63 self.log(".Resume()")
64 self.server.control_command_resume()
66 @dbus.service.method(INTERFACE, in_signature='')
67 def Ungrab(self):
68 self.log(".Ungrab()")
69 self.server.control_command_resume()
72 @dbus.service.method(INTERFACE, in_signature='s')
73 def Start(self, command):
74 c = ns(command)
75 self.log(".Start(%s)", c)
76 self.server.do_control_command_start(True, c)
78 @dbus.service.method(INTERFACE, in_signature='s')
79 def StartChild(self, command):
80 c = ns(command)
81 self.log(".StartChild(%s)", c)
82 self.server.do_control_command_start(False, c)
84 @dbus.service.method(INTERFACE, in_signature='sb')
85 def ToggleFeature(self, feature, state):
86 f, s = ns(feature), ns(state)
87 self.log(".ToggleFeature(%s, %s)", f, s)
88 self.server.control_command_toggle_feature(f, s)
91 @dbus.service.method(INTERFACE, in_signature='i')
92 def KeyPress(self, keycode):
93 k = ni(keycode)
94 self.log(".KeyPress(%i)", k)
95 self.server.control_command_key(str(k), press=True)
97 @dbus.service.method(INTERFACE, in_signature='i')
98 def KeyRelease(self, keycode):
99 k = ni(keycode)
100 self.log(".KeyRelease(%i)", k)
101 self.server.control_command_key(str(k), press=False)
103 @dbus.service.method(INTERFACE, in_signature='')
104 def ClearKeysPressed(self):
105 self.log(".ClearKeysPressed()")
106 self.server.clear_keys_pressed()
108 @dbus.service.method(INTERFACE, in_signature='ii')
109 def SetKeyboardRepeat(self, repeat_delay, repeat_interval):
110 d, i = ni(repeat_delay), ni(repeat_interval)
111 self.log(".SetKeyboardRepeat(%i, %i)", d, i)
112 self.server.set_keyboard_repeat(d, i)
115 @dbus.service.method(INTERFACE, in_signature='iii')
116 def MovePointer(self, wid, x, y):
117 wid, x, y = ni(wid), ni(x), ni(y)
118 self.log(".MovePointer(%i, %i, %i)", wid, x, y)
119 self.server._move_pointer(ni(wid), (ni(x), ni(y)))
121 @dbus.service.method(INTERFACE, in_signature='ib')
122 def MouseClick(self, button, pressed):
123 button, pressed = ni(button), nb(pressed)
124 self.log(".MouseClick%s", (button, pressed))
125 device_id = -1
126 self.server.button_action(None, button, pressed, device_id)
129 @dbus.service.method(INTERFACE, in_signature='iiii')
130 def SetWorkarea(self, x, y, w, h):
131 x, y, w, h = ni(x), ni(y), ni(w), ni(h)
132 self.log(".SetWorkarea%s", (x, y, w, h))
133 workarea = Rectangle(x=x, y=y, width=w, height=h)
134 self.server.set_workarea(workarea)
137 @dbus.service.method(INTERFACE, in_signature='iiiii')
138 def SetVideoRegion(self, wid, x, y, w, h):
139 wid, x, y, w, h = ni(wid), ni(x), ni(y), ni(w), ni(h)
140 self.log(".SetVideoRegion%s", (wid, x, y, w, h))
141 self.server.control_command_video_region(wid, x, y, w, h)
143 @dbus.service.method(INTERFACE, in_signature='ib')
144 def SetVideoRegionEnabled(self, wid, enabled):
145 wid, enabled = ni(wid), nb(enabled)
146 self.log(".SetVideoRegionEnabled(%i, %s)", wid, enabled)
147 self.server.control_command_video_region_enabled(wid, enabled)
149 @dbus.service.method(INTERFACE, in_signature='ib')
150 def SetVideoRegionDetection(self, wid, detection):
151 wid, detection = ni(wid), nb(detection)
152 self.log(".SetVideoRegionDetection(%i, %s)", wid, detection)
153 self.server.control_command_video_region_detection(wid, detection)
155 @dbus.service.method(INTERFACE, in_signature='iaai')
156 def SetVideoRegionExclusionZones(self, wid, zones):
157 wid = ni(wid)
158 nzones = []
159 for zone in zones:
160 nzones.append([ni(x) for x in zone])
161 log("SetVideoRegionExclusionZones(%i, %s)", wid, nzones)
162 self.server.control_command_video_region_exclusion_zones(wid, nzones)
164 @dbus.service.method(INTERFACE, in_signature='i')
165 def ResetVideoRegion(self, wid):
166 wid = ni(wid)
167 self.log(".ResetVideoRegion(%i)", wid)
168 self.server.control_command_reset_video_region(wid)
172 @dbus.service.method(INTERFACE, in_signature='ii')
173 def LockBatchDelay(self, wid, delay):
174 wid, delay = ni(wid), ni(delay)
175 self.log(".LockBatchDelay(%i, %i)", wid, delay)
176 self.server.control_command_lock_batch_delay(wid, delay)
178 @dbus.service.method(INTERFACE, in_signature='i')
179 def UnlockBatchDelay(self, wid):
180 wid = ni(wid)
181 self.log(".UnlockBatchDelay(%i)", wid)
182 self.server.control_command_unlock_batch_delay(wid)
185 @dbus.service.method(INTERFACE, in_signature='', out_signature='a{is}')
186 def ListWindows(self):
187 d = {}
188 for wid, window in self.server._id_to_window.items():
189 try:
190 d[wid] = window.get_property("title")
191 except Exception: # pragma: no cover
192 d[wid] = str(window)
193 self.log(".ListWindows()=%s", d)
194 return d
197 @dbus.service.method(INTERFACE, in_signature='s')
198 def SetLock(self, lock):
199 s = ns(lock)
200 self.log(".SetLock(%s)", s)
201 self.server.control_command_set_lock(s)
203 @dbus.service.method(INTERFACE, in_signature='s')
204 def SetSharing(self, sharing):
205 s = ns(sharing)
206 self.log(".SetSharing(%s)", s)
207 self.server.control_command_set_sharing(s)
210 @dbus.service.method(INTERFACE, in_signature='s')
211 def SetUIDriver(self, uuid):
212 s = ns(uuid)
213 self.log(".SetUIDriver(%s)", s)
214 self.server.control_command_set_ui_driver(s)
217 @dbus.service.method(INTERFACE, in_signature='i')
218 def SetIdleTimeout(self, value):
219 nvalue = ni(value)
220 self.log(".SetIdleTimeout(%s)", nvalue)
221 self.server.control_command_idle_timeout(nvalue)
224 @dbus.service.method(INTERFACE, in_signature='ii')
225 def MoveWindowToWorkspace(self, wid, workspace):
226 wid, workspace = ni(wid), ni(workspace)
227 self.log(".MoveWindowToWorkspace(%i, %i)", wid, workspace)
228 self.server.control_command_workspace(wid, workspace)
230 @dbus.service.method(INTERFACE, in_signature='is')
231 def SetWindowScaling(self, wid, scaling):
232 wid, scaling = ni(wid), ns(scaling)
233 self.log(".SetWindowScaling(%i, %s)", wid, scaling)
234 s = parse_scaling_value(scaling)
235 self.server.control_command_scaling(s, wid)
237 @dbus.service.method(INTERFACE, in_signature='is')
238 def SetWindowScalingControl(self, wid, scaling_control):
239 wid = ni(wid)
240 self.log(".SetWindowScalingControl(%i, %s)", wid, scaling_control)
241 if scaling_control.lower() in ("auto", "on"):
242 sc = None
243 else:
244 sc = from0to100(int(ns(scaling_control)))
245 self.server.control_command_scaling_control(sc, wid)
247 @dbus.service.method(INTERFACE, in_signature='is')
248 def SetWindowEncoding(self, wid, encoding):
249 wid, encoding = ni(wid), ns(encoding)
250 self.log(".SetWindowEncoding(%i, %s)", wid, encoding)
251 self.server.control_command_encoding(encoding, wid)
253 @dbus.service.method(INTERFACE, in_signature='i')
254 def RefreshWindow(self, wid):
255 wid = ni(wid)
256 self.log(".RefreshWindow(%i)", wid)
257 self.server.control_command_refresh(wid)
260 @dbus.service.method(INTERFACE, in_signature='ai')
261 def RefreshWindows(self, window_ids):
262 wids = [ni(x) for x in window_ids]
263 self.log(".RefreshWindows(%s)", wids)
264 self.server.control_command_refresh(*wids)
266 @dbus.service.method(INTERFACE, in_signature='')
267 def RefreshAllWindows(self):
268 self.log(".RefreshAllWindows()")
269 self.server.control_command_refresh(*self.server._id_to_window.keys())
272 @dbus.service.method(INTERFACE, in_signature='')
273 def ResetWindowFilters(self):
274 self.log(".ResetWindowFilters()")
275 self.server.reset_window_filters()
278 @dbus.service.method(INTERFACE, in_signature='s')
279 def EnableDebug(self, category):
280 c = ns(category)
281 self.log(".EnableDebug(%s)", c)
282 add_debug_category(c)
283 enable_debug_for(c)
285 @dbus.service.method(INTERFACE, in_signature='s')
286 def DisableDebug(self, category):
287 c = ns(category)
288 self.log(".DisableDebug(%s)", c)
289 remove_debug_category(c)
290 disable_debug_for(c)
293 @dbus.service.method(INTERFACE, in_signature='isss')
294 def SendNotification(self, nid, title, message, uuids):
295 nid, title, message, uuids = ni(nid), ns(title), ns(message), ns(uuids)
296 self.log(".SendNotification%s", (nid, title, message, uuids))
297 self.server.control_command_send_notification(nid, title, message, uuids)
299 @dbus.service.method(INTERFACE, in_signature='is')
300 def CloseNotification(self, nid, uuids):
301 nid, uuids = ni(nid), ns(uuids)
302 self.log(".CloseNotification%s", (nid, uuids))
303 self.server.control_command_close_notification(nid, uuids)
306 @dbus.service.method(INTERFACE, in_signature='sii')
307 def SetClipboardProperties(self, direction, max_copyin, max_copyout):
308 #keep direction unchanged if not specified
309 max_copyin, max_copyout = ni(max_copyin), ni(max_copyout)
310 direction = ns(direction) or self.server.clipboard_direction
311 self.log(".SetClipboardProperties%s", (direction, max_copyin, max_copyout))
312 self.server.control_command_clipboard_direction(direction, max_copyin, max_copyout)
315 @dbus.service.method(INTERFACE, in_signature='', out_signature='a{ss}')
316 def ListClients(self):
317 d = {}
318 for p, source in self.server._server_sources.items():
319 try:
320 d[source.uuid] = str(p)
321 except KeyError:
322 d[str(source)] = str(p)
323 self.log(".ListClients()=%s", d)
324 return d
326 @dbus.service.method(INTERFACE, in_signature='s')
327 def DetachClient(self, uuid):
328 s = ns(uuid)
329 self.log(".DetachClient(%s)", s)
330 for p, source in self.server._server_sources.items():
331 if source.uuid==s:
332 self.log("matched %s", source)
333 self.server.disconnect_client(p, DETACH_REQUEST)
335 @dbus.service.method(INTERFACE)
336 def DetachAllClients(self):
337 self.log(".DetachAllClients() will detach: %s", self.server._server_sources)
338 for p in self.server._server_sources.keys():
339 self.server.disconnect_client(p, DETACH_REQUEST)
342 @dbus.service.method(INTERFACE, in_signature='as')
343 def SendUIClientCommand(self, args):
344 nargs = n(args)
345 log("SendUIClientCommand(%s)", nargs)
346 for src in self.server._server_sources.values():
347 if src.ui_client:
348 src.send_client_command(*nargs)
351 @dbus.service.method(INTERFACE, in_signature='', out_signature='a{sv}', async_callbacks=("callback", "errback"))
352 def GetAllInfo(self, callback, errback):
353 self.log(".GetAllInfo()")
354 def gotinfo(_proto, info):
355 try:
356 v = dbus.types.Dictionary((str(k), native_to_dbus(v)) for k,v in info.items())
357 #v = native_to_dbus(info)
358 log("native_to_dbus(..)=%s", v)
359 callback(v)
360 except Exception as e: # pragma: no cover
361 log("GetAllInfo:gotinfo", exc_info=True)
362 errback(str(e))
363 v = self.server.get_all_info(gotinfo)
364 self.log(".GetAllInfo()=%s", v)
365 return v
367 @dbus.service.method(INTERFACE, in_signature='s', out_signature='a{sv}', async_callbacks=("callback", "errback"))
368 def GetInfo(self, subsystem, callback, errback):
369 self.log(".GetInfo(%s)", subsystem)
370 def gotinfo(_proto, info):
371 sub = info.get(subsystem)
372 try:
373 v = dbus.types.Dictionary((str(k), native_to_dbus(v)) for k,v in sub.items())
374 log("native_to_dbus(..)=%s", v)
375 callback(v)
376 except Exception as e: # pragma: no cover
377 log("GetInfo:gotinfo", exc_info=True)
378 errback(str(e))
379 v = self.server.get_all_info(gotinfo)
380 self.log(".GetInfo(%s)=%s", subsystem, v)
381 return v