Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/client/scaling_parser.py : 21%
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# This file is part of Xpra.
2# Copyright (C) 2018 Antoine Martin <antoine@xpra.org>
3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
4# later version. See the file COPYING for details.
6from xpra.log import Logger
7from xpra.scripts.config import TRUE_OPTIONS
9log = Logger("scaling")
12def parse_scaling(desktop_scaling, root_w, root_h, min_scaling=0.1, max_scaling=8):
13 log("parse_scaling(%s)", (desktop_scaling, root_w, root_h, min_scaling, max_scaling))
14 if desktop_scaling in TRUE_OPTIONS:
15 return 1, 1
16 if desktop_scaling.startswith("auto"):
17 #figure out if the command line includes settings to use for auto mode:
18 #here are our defaults:
19 limits = ((3960, 2160, 1, 1), #100% no auto scaling up to 4k
20 (7680, 4320, 1.25, 1.25), #125%
21 (8192, 8192, 1.5, 1.5), #150%
22 (16384, 16384, 5.0/3, 5.0/3), #166%
23 (32768, 32768, 2, 2),
24 (65536, 65536, 4, 4),
25 ) #200% if higher (who has this anyway?)
26 if desktop_scaling=="auto":
27 pass
28 elif desktop_scaling.startswith("auto:"):
29 limstr = desktop_scaling[5:] #ie: '1920x1080:1,2560x1600:1.5,...
30 limp = limstr.split(",")
31 limits = []
32 for l in limp:
33 try:
34 ldef = l.split(":")
35 assert len(ldef)==2, "could not find 2 parts separated by ':' in '%s'" % ldef
36 dims = ldef[0].split("x")
37 assert len(dims)==2, "could not find 2 dimensions separated by 'x' in '%s'" % ldef[0]
38 x, y = int(dims[0]), int(dims[1])
39 scaleparts = ldef[1].replace("*", "x").replace("/", "x").split("x")
40 assert len(scaleparts)<=2, "found more than 2 scaling dimensions!"
41 if len(scaleparts)==1:
42 sx = sy = float(scaleparts[0])
43 else:
44 sx = float(scaleparts[0])
45 sy = float(scaleparts[1])
46 limits.append((x, y, sx, sy))
47 log("parsed desktop-scaling auto limits: %s", limits)
48 except Exception as e:
49 log.warn("Warning: failed to parse limit string '%s':", l)
50 log.warn(" %s", e)
51 log.warn(" should use the format WIDTHxHEIGTH:SCALINGVALUE")
52 else:
53 log.warn("Warning: invalid auto attributes '%s'", desktop_scaling[5:])
54 sx, sy = 1, 1
55 matched = False
56 for mx, my, tsx, tsy in limits:
57 if root_w*root_h<=mx*my:
58 sx, sy = tsx, tsy
59 matched = True
60 break
61 log("matched=%s : %sx%s with limits %s: %sx%s", matched, root_w, root_h, limits, sx, sy)
62 return sx,sy
63 def parse_item(v):
64 div = 1
65 try:
66 if v.endswith("%"):
67 div = 100
68 v = v[:-1]
69 except ValueError:
70 pass
71 if div==1:
72 try:
73 return int(v) #ie: desktop-scaling=2
74 except ValueError:
75 pass
76 try:
77 return float(v)/div #ie: desktop-scaling=1.5
78 except (ValueError, ZeroDivisionError):
79 pass
80 #ie: desktop-scaling=3/2, or desktop-scaling=3:2
81 pair = v.replace(":", "/").split("/", 1)
82 try:
83 return float(pair[0])/float(pair[1])
84 except (ValueError, ZeroDivisionError):
85 pass
86 log.warn("Warning: failed to parse scaling value '%s'", v)
87 return None
88 if desktop_scaling.find("x")>0 and desktop_scaling.find(":")>0:
89 log.warn("Warning: found both 'x' and ':' in desktop-scaling fixed value")
90 log.warn(" maybe the 'auto:' prefix is missing?")
91 return 1, 1
92 #split if we have two dimensions: "1600x1200" -> ["1600", "1200"], if not: "2" -> ["2"]
93 values = desktop_scaling.replace(",", "x").split("x", 1)
94 x = parse_item(values[0])
95 if x is None:
96 return 1, 1
97 if len(values)==1:
98 #just one value: use the same for X and Y
99 y = x
100 else:
101 y = parse_item(values[1])
102 if y is None:
103 return 1, 1
104 log("parse_scaling(%s) parsed items=%s", desktop_scaling, (x, y))
105 #normalize absolute values into floats:
106 if x>max_scaling or y>max_scaling:
107 log(" normalizing dimensions to a ratio of %ix%i", root_w, root_h)
108 x = float(x) / root_w
109 y = float(y) / root_h
110 if x<min_scaling or y<min_scaling or x>max_scaling or y>max_scaling:
111 log.warn("Warning: scaling values %sx%s are out of range", x, y)
112 return 1, 1
113 log("parse_scaling(%s)=%s", desktop_scaling, (x, y))
114 return x, y