Hide keyboard shortcuts

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. 

6 

7import dbus.service 

8 

9from xpra.dbus.helper import dbus_to_native 

10from xpra.dbus.common import init_session_bus 

11from xpra.util import AtomicInteger, DETACH_REQUEST 

12from xpra.log import Logger 

13 

14log = Logger("dbus", "server") 

15 

16BUS_NAME = "org.xpra.Server" 

17INTERFACE = "org.xpra.Client" 

18PATH = "/org/xpra/Client" 

19 

20def n(*args): 

21 return dbus_to_native(*args) 

22def ni(*args): 

23 return int(n(*args)) 

24def nb(*args): 

25 return bool(n(*args)) 

26def ns(*args): 

27 return str(n(*args)) 

28 

29 

30sequence = AtomicInteger() 

31 

32class DBUS_Source(dbus.service.Object): 

33 SUPPORTS_MULTIPLE_OBJECT_PATHS = True 

34 

35 def __init__(self, source=None, extra=""): 

36 self.source = source 

37 session_bus = init_session_bus() 

38 name = BUS_NAME 

39 self.path = PATH + str(sequence.increase()) 

40 if extra: 

41 name += extra.replace(".", "_").replace(":", "_") 

42 bus_name = dbus.service.BusName(name, session_bus) 

43 super().__init__(bus_name, self.path) 

44 self.log("(%s)", source) 

45 self._properties = {"bell" : ("send_bell", ni), 

46 "cursors" : ("send_cursors", ni), 

47 "notifications" : ("send_notifications", ni), 

48 } 

49 

50 def __str__(self): 

51 return "DBUS_Source(%s:%s)" % (BUS_NAME, self.path) 

52 

53 

54 def cleanup(self): 

55 try: 

56 log("calling %s", self.remove_from_connection) 

57 self.remove_from_connection() 

58 except Exception as e: 

59 log.error("Error removing the source's DBUS server:") 

60 log.error(" %s", e) 

61 

62 

63 def log(self, fmt, *args): 

64 log("%s"+fmt, INTERFACE, *args) 

65 

66 

67 @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='s', out_signature='v') 

68 def Get(self, property_name): 

69 conv = self._properties.get(property_name) 

70 if conv is None: 

71 raise dbus.exceptions.DBusException("invalid property") 

72 server_property_name, _ = conv 

73 v = getattr(self.source, server_property_name) 

74 self.log(".Get(%s)=%s", property_name, v) 

75 return v 

76 

77 @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='', out_signature='a{sv}') 

78 def GetAll(self, interface_name): 

79 if interface_name==INTERFACE: 

80 v = dict((x, self.Get(x)) for x in self._properties.keys()) 

81 else: 

82 v = {} 

83 self.log(".GetAll(%s)=%s", interface_name, v) 

84 return v 

85 

86 @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ssv') 

87 def Set(self, interface_name, property_name, new_value): 

88 self.log(".Set(%s, %s, %s)", interface_name, property_name, new_value) 

89 conv = self._properties.get(property_name) 

90 if conv is None: 

91 raise dbus.exceptions.DBusException("invalid property") 

92 server_property_name, validator = conv 

93 assert hasattr(self.source, server_property_name) 

94 setattr(self.source, server_property_name, validator(new_value)) 

95 

96 @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as') 

97 def PropertiesChanged(self, interface_name, changed_properties, invalidated_properties): 

98 pass 

99 

100 

101 @dbus.service.method(INTERFACE, in_signature='b') 

102 def ShowDesktop(self, show): 

103 show = nb(show) 

104 self.log(".ShowDesktop(%s)", show) 

105 self.source.show_desktop(show) 

106 

107 @dbus.service.method(INTERFACE, in_signature='i') 

108 def RaiseWindow(self, wid): 

109 wid = ni(wid) 

110 self.log(".RaiseWindow(%s)", wid) 

111 self.source.raise_window(wid) 

112 

113 @dbus.service.method(INTERFACE, in_signature='') 

114 def ResetWindowFilters(self): 

115 self.log(".ResetWindowFilters()") 

116 self.source.reset_window_filters() 

117 

118 @dbus.service.method(INTERFACE, in_signature='sssv') 

119 def AddWindowFilter(self, object_name, property_name, operator, value): 

120 self.log(".AddWindowFilter%s", (object_name, property_name, operator, value)) 

121 self.source.add_window_filter(ns(object_name), ns(property_name), ns(operator), n(value)) 

122 

123 @dbus.service.method(INTERFACE, out_signature='as') 

124 def GetAllWindowFilters(self): 

125 v = [str(x) for x in self.source.get_all_window_filters()] 

126 self.log(".GetAllWindowFilters()=%s", v) 

127 return v 

128 

129 

130 @dbus.service.method(INTERFACE, in_signature='') 

131 def SetDefaultKeymap(self): 

132 self.log(".SetDefaultKeymap()") 

133 self.source.set_default_keymap() 

134 

135 

136 @dbus.service.method(INTERFACE, in_signature='') 

137 def Suspend(self): 

138 self.log(".Suspend()") 

139 self.source.go_idle() 

140 

141 @dbus.service.method(INTERFACE, in_signature='') 

142 def Resume(self): 

143 self.log(".Resume()") 

144 self.source.no_idle() 

145 

146 

147 @dbus.service.method(INTERFACE, in_signature='s') 

148 def StartSpeaker(self, codec): 

149 codec = ns(codec) 

150 self.log(".StartSpeaker(%s)", codec) 

151 self.source.start_sending_sound(codec) 

152 

153 @dbus.service.method(INTERFACE, in_signature='') 

154 def StopSpeaker(self): 

155 self.log(".StopSpeaker()") 

156 self.source.stop_sending_sound() 

157 

158 

159 @dbus.service.method(INTERFACE, in_signature='i') 

160 def SetAVSyncDelay(self, delay): 

161 d = ni(delay) 

162 self.log(".SetAVSyncDelay(%i)", d) 

163 self.source.set_av_sync_delay(d) 

164 

165 

166 @dbus.service.method(INTERFACE, in_signature='as') 

167 def SendClientCommand(self, args): 

168 cmd = n(args) 

169 self.log(".SendClientCommand(%s)", cmd) 

170 self.source.send_client_command(*cmd) 

171 

172 

173 @dbus.service.method(INTERFACE, in_signature='s') 

174 def Detach(self, reason): 

175 proto = self.source.proto 

176 rs = ns(reason) 

177 self.log(".SendClientCommand(%s) protocol=%s", rs, proto) 

178 assert proto, "no connection" 

179 proto.send_disconnect(DETACH_REQUEST, rs)