Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/server/source/clientdisplay_mixin.py : 66%
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# -*- coding: utf-8 -*-
2# This file is part of Xpra.
3# Copyright (C) 2010-2020 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 xpra.os_util import strtobytes
8from xpra.util import get_screen_info, envint, first_time, iround, typedict
9from xpra.server.source.stub_source_mixin import StubSourceMixin
10from xpra.log import Logger
12log = Logger("av-sync")
15"""
16Store information and manage events related to the client's display
17"""
18class ClientDisplayMixin(StubSourceMixin):
20 def cleanup(self):
21 self.init_state()
23 def init_state(self):
24 self.icc = {}
25 self.display_icc = {}
26 self.randr_notify = False
27 self.desktop_size = None
28 self.desktop_mode_size = None
29 self.desktop_size_unscaled = None
30 self.desktop_size_server = None
31 self.screen_sizes = ()
32 self.screen_resize_bigger = True
33 self.desktops = 1
34 self.desktop_names = ()
35 self.show_desktop_allowed = False
36 self.opengl_props = {}
38 def get_info(self) -> dict:
39 info = {
40 "desktop_size" : self.desktop_size or "",
41 "desktops" : self.desktops,
42 "desktop_names" : self.desktop_names,
43 "randr_notify" : self.randr_notify,
44 "opengl" : self.opengl_props,
45 }
46 info.update(get_screen_info(self.screen_sizes))
47 if self.desktop_mode_size:
48 info["desktop_mode_size"] = self.desktop_mode_size
49 if self.desktop_size_unscaled:
50 info["desktop_size"] = {"unscaled" : self.desktop_size_unscaled}
51 return info
53 def parse_client_caps(self, c : typedict):
54 self.randr_notify = c.boolget("randr_notify")
55 self.desktop_size = c.intpair("desktop_size")
56 if self.desktop_size is not None:
57 w, h = self.desktop_size
58 if w<=0 or h<=0 or w>=32768 or h>=32768:
59 log.warn("ignoring invalid desktop dimensions: %sx%s", w, h)
60 self.desktop_size = None
61 self.desktop_mode_size = c.intpair("desktop_mode_size")
62 self.desktop_size_unscaled = c.intpair("desktop_size.unscaled")
63 self.screen_resize_bigger = c.boolget("screen-resize-bigger", True)
64 self.set_screen_sizes(c.tupleget("screen_sizes"))
65 self.set_desktops(c.intget("desktops", 1), c.strtupleget("desktop.names"))
66 self.show_desktop_allowed = c.boolget("show-desktop")
67 self.icc = c.dictget("icc", {})
68 self.display_icc = c.dictget("display-icc", {})
69 self.opengl_props = c.dictget("opengl", {})
72 def set_screen_sizes(self, screen_sizes):
73 log("set_screen_sizes(%s)", screen_sizes)
74 self.screen_sizes = list(screen_sizes)
75 #validate dpi / screen size in mm
76 #(ticket 2480: GTK3 on macos can return bogus values)
77 MIN_DPI = envint("XPRA_MIN_DPI", 10)
78 MAX_DPI = envint("XPRA_MIN_DPI", 500)
79 def dpi(size_pixels, size_mm):
80 if size_mm==0:
81 return 0
82 return int(size_pixels * 254 / size_mm / 10)
83 for i,screen in enumerate(list(screen_sizes)):
84 if len(screen)<10:
85 continue
86 sw, sh, wmm, hmm, monitors = screen[1:6]
87 xdpi = dpi(sw, wmm)
88 ydpi = dpi(sh, hmm)
89 if xdpi<MIN_DPI or xdpi>MAX_DPI or ydpi<MIN_DPI or ydpi>MAX_DPI:
90 warn = first_time("invalid-screen-size-%ix%i" % (wmm, hmm))
91 if warn:
92 log.warn("Warning: ignoring invalid screen size %ix%i mm", wmm, hmm)
93 if monitors:
94 #[plug_name, xs(geom.x), ys(geom.y), xs(geom.width), ys(geom.height), wmm, hmm]
95 wmm = sum(monitor[5] for monitor in monitors)
96 hmm = sum(monitor[6] for monitor in monitors)
97 xdpi = dpi(sw, wmm)
98 ydpi = dpi(sh, hmm)
99 if xdpi<MIN_DPI or xdpi>MAX_DPI or ydpi<MIN_DPI or ydpi>MAX_DPI:
100 #still invalid, generate one from DPI=96
101 wmm = iround(sw*25.4/96)
102 hmm = iround(sh*25.4/96)
103 if warn:
104 log.warn(" using %ix%i mm", wmm, hmm)
105 screen = list(screen)
106 screen[3] = wmm
107 screen[4] = hmm
108 self.screen_sizes[i] = tuple(screen)
109 log("client validated screen sizes: %s", self.screen_sizes)
111 def set_desktops(self, desktops, desktop_names):
112 self.desktops = desktops or 1
113 #older clients send strings,
114 #newer clients send bytes...
115 def b(v):
116 try :
117 return strtobytes(v).decode("utf8")
118 except UnicodeDecodeError:
119 return v
120 if desktop_names:
121 self.desktop_names = [b(d) for d in desktop_names]
122 else:
123 self.desktop_names = []
125 def updated_desktop_size(self, root_w, root_h, max_w, max_h):
126 log("updated_desktop_size%s randr_notify=%s, desktop_size=%s",
127 (root_w, root_h, max_w, max_h), self.randr_notify, self.desktop_size)
128 if not self.hello_sent:
129 return False
130 if self.randr_notify and (not self.desktop_size_server or tuple(self.desktop_size_server)!=(root_w, root_h)):
131 self.desktop_size_server = root_w, root_h
132 self.send("desktop_size", root_w, root_h, max_w, max_h)
133 return True
134 return False
136 def show_desktop(self, show):
137 if self.show_desktop_allowed and self.hello_sent:
138 self.send_async("show-desktop", show)