Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: remoting/host/linux/linux_me2me_host.py

Issue 1954623005: Add Xorg+dummy as alternative for Xvfb (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address final comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/host/curtain_mode_linux.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # Virtual Me2Me implementation. This script runs and manages the processes 6 # Virtual Me2Me implementation. This script runs and manages the processes
7 # required for a Virtual Me2Me desktop, which are: X server, X desktop 7 # required for a Virtual Me2Me desktop, which are: X server, X desktop
8 # session, and Host process. 8 # session, and Host process.
9 # This script is intended to run continuously as a background daemon 9 # This script is intended to run continuously as a background daemon
10 # process, running under an ordinary (non-root) user account. 10 # process, running under an ordinary (non-root) user account.
(...skipping 24 matching lines...) Expand all
35 import time 35 import time
36 import uuid 36 import uuid
37 37
38 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" 38 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE"
39 39
40 # This script has a sensible default for the initial and maximum desktop size, 40 # This script has a sensible default for the initial and maximum desktop size,
41 # which can be overridden either on the command-line, or via a comma-separated 41 # which can be overridden either on the command-line, or via a comma-separated
42 # list of sizes in this environment variable. 42 # list of sizes in this environment variable.
43 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES" 43 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES"
44 44
45 # By default, this script launches Xvfb as the virtual X display. When this
46 # environment variable is set, the script will instead launch an instance of
47 # Xorg using the dummy display driver and void input device. In order for this
48 # to work, both the dummy display driver and void input device need to be
49 # installed:
50 #
51 # sudo apt-get install xserver-xorg-video-dummy
52 # sudo apt-get install xserver-xorg-input-void
53 #
54 # TODO(rkjnsn): Add xserver-xorg-video-dummy and xserver-xorg-input-void as
55 # package dependencies at the same time we switch the default to Xorg
56 USE_XORG_ENV_VAR = "CHROME_REMOTE_DESKTOP_USE_XORG"
57
58 # The amount of video RAM the dummy driver should claim to have, which limits
59 # the maximum possible resolution.
60 # 1048576 KiB = 1 GiB, which is the amount of video RAM needed to have a
61 # 16384x16384 pixel frame buffer (the maximum size supported by VP8) with 32
62 # bits per pixel.
63 XORG_DUMMY_VIDEO_RAM = 1048576 # KiB
64
45 # By default, provide a maximum size that is large enough to support clients 65 # By default, provide a maximum size that is large enough to support clients
46 # with large or multiple monitors. This is a comma-separated list of 66 # with large or multiple monitors. This is a comma-separated list of
47 # resolutions that will be made available if the X server supports RANDR. These 67 # resolutions that will be made available if the X server supports RANDR. These
48 # defaults can be overridden in ~/.profile. 68 # defaults can be overridden in ~/.profile.
49 DEFAULT_SIZES = "1600x1200,3840x2560" 69 DEFAULT_SIZES = "1600x1200,3840x2560"
50 70
51 # If RANDR is not available, use a smaller default size. Only a single 71 # If RANDR is not available, use a smaller default size. Only a single
52 # resolution is supported in this case. 72 # resolution is supported in this case.
53 DEFAULT_SIZE_NO_RANDR = "1600x1200" 73 DEFAULT_SIZE_NO_RANDR = "1600x1200"
54 74
(...skipping 27 matching lines...) Expand all
82 102
83 # Thresholds for switching from fast- to slow-restart and for giving up 103 # Thresholds for switching from fast- to slow-restart and for giving up
84 # trying to restart entirely. 104 # trying to restart entirely.
85 SHORT_BACKOFF_THRESHOLD = 5 105 SHORT_BACKOFF_THRESHOLD = 5
86 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10 106 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10
87 107
88 # Globals needed by the atexit cleanup() handler. 108 # Globals needed by the atexit cleanup() handler.
89 g_desktops = [] 109 g_desktops = []
90 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest() 110 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest()
91 111
112 def gen_xorg_config(sizes):
113 return (
114 # This causes X to load the default GLX module, even if a proprietary one
115 # is installed in a different directory.
116 'Section "Files"\n'
117 ' ModulePath "/usr/lib/xorg/modules"\n'
118 'EndSection\n'
119 '\n'
120 # Suppress device probing, which happens by default.
121 'Section "ServerFlags"\n'
122 ' Option "AutoAddDevices" "false"\n'
123 ' Option "AutoEnableDevices" "false"\n'
124 ' Option "DontVTSwitch" "true"\n'
125 ' Option "PciForceNone" "true"\n'
126 'EndSection\n'
127 '\n'
128 'Section "InputDevice"\n'
129 # The host looks for this name to check whether it's running in a virtual
130 # session
131 ' Identifier "Chrome Remote Desktop Input"\n'
132 # While the xorg.conf man page specifies that both of these options are
133 # deprecated synonyms for `Option "Floating" "false"`, it turns out that
134 # if both aren't specified, the Xorg server will automatically attempt to
135 # add additional devices.
136 ' Option "CoreKeyboard" "true"\n'
137 ' Option "CorePointer" "true"\n'
138 ' Driver "void"\n'
139 'EndSection\n'
140 '\n'
141 'Section "Device"\n'
142 ' Identifier "Chrome Remote Desktop Videocard"\n'
143 ' Driver "dummy"\n'
144 ' VideoRam {video_ram}\n'
145 'EndSection\n'
146 '\n'
147 'Section "Monitor"\n'
148 ' Identifier "Chrome Remote Desktop Monitor"\n'
149 # The horizontal sync rate was calculated from the vertical refresh rate
150 # and the modline template:
151 # (33000 (vert total) * 0.1 Hz = 3.3 kHz)
152 ' HorizSync 3.3\n' # kHz
153 # The vertical refresh rate was chosen both to be low enough to have an
154 # acceptable dot clock at high resolutions, and then bumped down a little
155 # more so that in the unlikely event that a low refresh rate would break
156 # something, it would break obviously.
157 ' VertRefresh 0.1\n' # Hz
158 '{modelines}'
159 'EndSection\n'
160 '\n'
161 'Section "Screen"\n'
162 ' Identifier "Chrome Remote Desktop Screen"\n'
163 ' Device "Chrome Remote Desktop Videocard"\n'
164 ' Monitor "Chrome Remote Desktop Monitor"\n'
165 ' DefaultDepth 24\n'
166 ' SubSection "Display"\n'
167 ' Viewport 0 0\n'
168 ' Depth 24\n'
169 ' Modes {modes}\n'
170 ' EndSubSection\n'
171 'EndSection\n'
172 '\n'
173 'Section "ServerLayout"\n'
174 ' Identifier "Chrome Remote Desktop Layout"\n'
175 ' Screen "Chrome Remote Desktop Screen"\n'
176 ' InputDevice "Chrome Remote Desktop Input"\n'
177 'EndSection\n'.format(
178 # This Modeline template allows resolutions up to the dummy driver's
179 # max supported resolution of 32767x32767 without additional
180 # calculation while meeting the driver's dot clock requirements. Note
181 # that VP8 (and thus the amount of video RAM chosen) only support a
182 # maximum resolution of 16384x16384.
183 # 32767x32767 should be possible if we switch fully to VP9 and
184 # increase the video RAM to 4GiB.
185 # The dot clock was calculated to match the VirtRefresh chosen above.
186 # (33000 * 33000 * 0.1 Hz = 108.9 MHz)
187 # Changes this line require matching changes to HorizSync and
188 # VertRefresh.
189 modelines="".join(
190 ' Modeline "{0}x{1}" 108.9 {0} 32998 32999 33000 '
191 '{1} 32998 32999 33000\n'.format(w, h) for w, h in sizes),
192 modes=" ".join('"{0}x{1}"'.format(w, h) for w, h in sizes),
193 video_ram=XORG_DUMMY_VIDEO_RAM))
194
92 195
93 def is_supported_platform(): 196 def is_supported_platform():
94 # Always assume that the system is supported if the config directory or 197 # Always assume that the system is supported if the config directory or
95 # session file exist. 198 # session file exist.
96 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or 199 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or
97 os.path.isfile(SYSTEM_SESSION_FILE_PATH)): 200 os.path.isfile(SYSTEM_SESSION_FILE_PATH)):
98 return True 201 return True
99 202
100 # The host has been tested only on Ubuntu. 203 # The host has been tested only on Ubuntu.
101 distribution = platform.linux_distribution() 204 distribution = platform.linux_distribution()
102 return (distribution[0]).lower() == 'ubuntu' 205 return (distribution[0]).lower() == 'ubuntu'
103 206
104 207
105 def get_randr_supporting_x_server(): 208 def locate_xvfb_randr():
106 """Returns a path to an X server that supports the RANDR extension, if this 209 """Returns a path to our RANDR-supporting Xvfb server, if it is found on the
107 is found on the system. Otherwise returns None.""" 210 system. Otherwise returns None."""
108 211
109 xvfb = "/usr/bin/Xvfb-randr" 212 xvfb = "/usr/bin/Xvfb-randr"
110 if os.path.exists(xvfb): 213 if os.path.exists(xvfb):
111 return xvfb 214 return xvfb
112 215
113 xvfb = os.path.join(SCRIPT_DIR, "Xvfb-randr") 216 xvfb = os.path.join(SCRIPT_DIR, "Xvfb-randr")
114 if os.path.exists(xvfb): 217 if os.path.exists(xvfb):
115 return xvfb 218 return xvfb
116 219
117 return None 220 return None
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 334
232 class Desktop: 335 class Desktop:
233 """Manage a single virtual desktop""" 336 """Manage a single virtual desktop"""
234 337
235 def __init__(self, sizes): 338 def __init__(self, sizes):
236 self.x_proc = None 339 self.x_proc = None
237 self.session_proc = None 340 self.session_proc = None
238 self.host_proc = None 341 self.host_proc = None
239 self.child_env = None 342 self.child_env = None
240 self.sizes = sizes 343 self.sizes = sizes
344 self.xorg_conf = None
241 self.pulseaudio_pipe = None 345 self.pulseaudio_pipe = None
242 self.server_supports_exact_resize = False 346 self.server_supports_exact_resize = False
243 self.host_ready = False 347 self.host_ready = False
244 self.ssh_auth_sockname = None 348 self.ssh_auth_sockname = None
245 g_desktops.append(self) 349 g_desktops.append(self)
246 350
247 @staticmethod 351 @staticmethod
248 def get_unused_display_number(): 352 def get_unused_display_number():
249 """Return a candidate display number for which there is currently no 353 """Return a candidate display number for which there is currently no
250 X Server lock file""" 354 X Server lock file"""
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 self.child_env["PULSE_STATE_PATH"] = pulse_path 453 self.child_env["PULSE_STATE_PATH"] = pulse_path
350 self.child_env["PULSE_SINK"] = sink_name 454 self.child_env["PULSE_SINK"] = sink_name
351 self.pulseaudio_pipe = pipe_name 455 self.pulseaudio_pipe = pipe_name
352 456
353 return True 457 return True
354 458
355 def _setup_gnubby(self): 459 def _setup_gnubby(self):
356 self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" % 460 self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" %
357 os.environ["USER"]) 461 os.environ["USER"])
358 462
463 def _launch_xvfb(self, display, x_auth_file, extra_x_args):
464 max_width = max([width for width, height in self.sizes])
465 max_height = max([height for width, height in self.sizes])
466
467 xvfb = locate_xvfb_randr()
468 if xvfb:
469 self.server_supports_exact_resize = True
470 else:
471 xvfb = "Xvfb"
472 self.server_supports_exact_resize = False
473
474 logging.info("Starting %s on display :%d" % (xvfb, display))
475 screen_option = "%dx%dx24" % (max_width, max_height)
476 self.x_proc = subprocess.Popen(
477 [xvfb, ":%d" % display,
478 "-auth", x_auth_file,
479 "-nolisten", "tcp",
480 "-noreset",
481 "-screen", "0", screen_option
482 ] + extra_x_args)
483 if not self.x_proc.pid:
484 raise Exception("Could not start Xvfb.")
485
486 def _launch_xorg(self, display, x_auth_file, extra_x_args):
487 with tempfile.NamedTemporaryFile(
488 prefix="chrome_remote_desktop_",
489 suffix=".conf", delete=False) as config_file:
490 config_file.write(gen_xorg_config(self.sizes))
491
492 # For now, we don't support exact resize with Xorg+dummy
493 self.server_supports_exact_resize = False
494 self.xorg_conf = config_file.name
495
496 logging.info("Starting Xorg on display :%d" % display)
497 # We use the child environment so the Xorg server picks up the Mesa libGL
498 # instead of any proprietary versions that may be installed, thanks to
499 # LD_LIBRARY_PATH.
500 # Note: This prevents any environment variable the user has set from
501 # affecting the Xorg server.
502 self.x_proc = subprocess.Popen(
503 ["Xorg", ":%d" % display,
504 "-auth", x_auth_file,
505 "-nolisten", "tcp",
506 "-noreset",
507 # Disable logging to a file and instead bump up the stderr verbosity
508 # so the equivalent information gets logged in our main log file.
509 "-logfile", "/dev/null",
510 "-verbose", "3",
511 "-config", config_file.name
512 ] + extra_x_args, env=self.child_env)
513 if not self.x_proc.pid:
514 raise Exception("Could not start Xorg.")
515
359 def _launch_x_server(self, extra_x_args): 516 def _launch_x_server(self, extra_x_args):
360 x_auth_file = os.path.expanduser("~/.Xauthority") 517 x_auth_file = os.path.expanduser("~/.Xauthority")
361 self.child_env["XAUTHORITY"] = x_auth_file 518 self.child_env["XAUTHORITY"] = x_auth_file
362 devnull = open(os.devnull, "r+") 519 devnull = open(os.devnull, "r+")
363 display = self.get_unused_display_number() 520 display = self.get_unused_display_number()
364 521
365 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY 522 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY
366 # file which will be used for the X session. 523 # file which will be used for the X session.
367 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, 524 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display,
368 env=self.child_env, shell=True) 525 env=self.child_env, shell=True)
369 if ret_code != 0: 526 if ret_code != 0:
370 raise Exception("xauth failed with code %d" % ret_code) 527 raise Exception("xauth failed with code %d" % ret_code)
371 528
372 max_width = max([width for width, height in self.sizes])
373 max_height = max([height for width, height in self.sizes])
374
375 xvfb = get_randr_supporting_x_server()
376 if xvfb:
377 self.server_supports_exact_resize = True
378 else:
379 xvfb = "Xvfb"
380 self.server_supports_exact_resize = False
381
382 # Disable the Composite extension iff the X session is the default 529 # Disable the Composite extension iff the X session is the default
383 # Unity-2D, since it uses Metacity which fails to generate DAMAGE 530 # Unity-2D, since it uses Metacity which fails to generate DAMAGE
384 # notifications correctly. See crbug.com/166468. 531 # notifications correctly. See crbug.com/166468.
385 x_session = choose_x_session() 532 x_session = choose_x_session()
386 if (len(x_session) == 2 and 533 if (len(x_session) == 2 and
387 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"): 534 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"):
388 extra_x_args.extend(["-extension", "Composite"]) 535 extra_x_args.extend(["-extension", "Composite"])
389 536
390 logging.info("Starting %s on display :%d" % (xvfb, display)) 537 if USE_XORG_ENV_VAR in os.environ:
391 screen_option = "%dx%dx24" % (max_width, max_height) 538 self._launch_xorg(display, x_auth_file, extra_x_args)
392 self.x_proc = subprocess.Popen( 539 else:
393 [xvfb, ":%d" % display, 540 self._launch_xvfb(display, x_auth_file, extra_x_args)
394 "-auth", x_auth_file,
395 "-nolisten", "tcp",
396 "-noreset",
397 "-screen", "0", screen_option
398 ] + extra_x_args)
399 if not self.x_proc.pid:
400 raise Exception("Could not start Xvfb.")
401 541
402 self.child_env["DISPLAY"] = ":%d" % display 542 self.child_env["DISPLAY"] = ":%d" % display
403 self.child_env["CHROME_REMOTE_DESKTOP_SESSION"] = "1" 543 self.child_env["CHROME_REMOTE_DESKTOP_SESSION"] = "1"
404 544
405 # Use a separate profile for any instances of Chrome that are started in 545 # Use a separate profile for any instances of Chrome that are started in
406 # the virtual session. Chrome doesn't support sharing a profile between 546 # the virtual session. Chrome doesn't support sharing a profile between
407 # multiple DISPLAYs, but Chrome Sync allows for a reasonable compromise. 547 # multiple DISPLAYs, but Chrome Sync allows for a reasonable compromise.
408 chrome_profile = os.path.join(CONFIG_DIR, "chrome-profile") 548 chrome_profile = os.path.join(CONFIG_DIR, "chrome-profile")
409 self.child_env["CHROME_USER_DATA_DIR"] = chrome_profile 549 self.child_env["CHROME_USER_DATA_DIR"] = chrome_profile
410 550
411 # Set SSH_AUTH_SOCK to the file name to listen on. 551 # Set SSH_AUTH_SOCK to the file name to listen on.
412 if self.ssh_auth_sockname: 552 if self.ssh_auth_sockname:
413 self.child_env["SSH_AUTH_SOCK"] = self.ssh_auth_sockname 553 self.child_env["SSH_AUTH_SOCK"] = self.ssh_auth_sockname
414 554
415 # Wait for X to be active. 555 # Wait for X to be active.
416 for _test in range(20): 556 for _test in range(20):
417 retcode = subprocess.call("xdpyinfo", env=self.child_env, stdout=devnull) 557 retcode = subprocess.call("xdpyinfo", env=self.child_env, stdout=devnull)
418 if retcode == 0: 558 if retcode == 0:
419 break 559 break
420 time.sleep(0.5) 560 time.sleep(0.5)
421 if retcode != 0: 561 if retcode != 0:
422 raise Exception("Could not connect to Xvfb.") 562 raise Exception("Could not connect to X server.")
423 else: 563 else:
424 logging.info("Xvfb is active.") 564 logging.info("X server is active.")
425 565
426 # The remoting host expects the server to use "evdev" keycodes, but Xvfb 566 # The remoting host expects the server to use "evdev" keycodes, but Xvfb
427 # starts configured to use the "base" ruleset, resulting in XKB configuring 567 # starts configured to use the "base" ruleset, resulting in XKB configuring
428 # for "xfree86" keycodes, and screwing up some keys. See crbug.com/119013. 568 # for "xfree86" keycodes, and screwing up some keys. See crbug.com/119013.
429 # Reconfigure the X server to use "evdev" keymap rules. The X server must 569 # Reconfigure the X server to use "evdev" keymap rules. The X server must
430 # be started with -noreset otherwise it'll reset as soon as the command 570 # be started with -noreset otherwise it'll reset as soon as the command
431 # completes, since there are no other X clients running yet. 571 # completes, since there are no other X clients running yet.
432 retcode = subprocess.call("setxkbmap -rules evdev", env=self.child_env, 572 retcode = subprocess.call("setxkbmap -rules evdev", env=self.child_env,
433 shell=True) 573 shell=True)
434 if retcode != 0: 574 if retcode != 0:
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 # Close the temporary file-descriptors. 964 # Close the temporary file-descriptors.
825 os.close(devnull_fd) 965 os.close(devnull_fd)
826 os.close(log_fd) 966 os.close(log_fd)
827 967
828 968
829 def cleanup(): 969 def cleanup():
830 logging.info("Cleanup.") 970 logging.info("Cleanup.")
831 971
832 global g_desktops 972 global g_desktops
833 for desktop in g_desktops: 973 for desktop in g_desktops:
834 for proc, name in [(desktop.x_proc, "Xvfb"), 974 for proc, name in [(desktop.x_proc, "X server"),
835 (desktop.session_proc, "session"), 975 (desktop.session_proc, "session"),
836 (desktop.host_proc, "host")]: 976 (desktop.host_proc, "host")]:
837 if proc is not None: 977 if proc is not None:
838 logging.info("Terminating " + name) 978 logging.info("Terminating " + name)
839 try: 979 try:
840 psutil_proc = psutil.Process(proc.pid) 980 psutil_proc = psutil.Process(proc.pid)
841 psutil_proc.terminate() 981 psutil_proc.terminate()
842 982
843 # Use a short timeout, to avoid delaying service shutdown if the 983 # Use a short timeout, to avoid delaying service shutdown if the
844 # process refuses to die for some reason. 984 # process refuses to die for some reason.
845 psutil_proc.wait(timeout=10) 985 psutil_proc.wait(timeout=10)
846 except psutil.TimeoutExpired: 986 except psutil.TimeoutExpired:
847 logging.error("Timed out - sending SIGKILL") 987 logging.error("Timed out - sending SIGKILL")
848 psutil_proc.kill() 988 psutil_proc.kill()
849 except psutil.Error: 989 except psutil.Error:
850 logging.error("Error terminating process") 990 logging.error("Error terminating process")
991 if desktop.xorg_conf is not None:
992 os.remove(desktop.xorg_conf)
851 993
852 g_desktops = [] 994 g_desktops = []
853 if ParentProcessLogger.instance(): 995 if ParentProcessLogger.instance():
854 ParentProcessLogger.instance().release_parent(False) 996 ParentProcessLogger.instance().release_parent(False)
855 997
856 class SignalHandler: 998 class SignalHandler:
857 """Reload the config file on SIGHUP. Since we pass the configuration to the 999 """Reload the config file on SIGHUP. Since we pass the configuration to the
858 host processes via stdin, they can't reload it, so terminate them. They will 1000 host processes via stdin, they can't reload it, so terminate them. They will
859 be relaunched automatically with the new config.""" 1001 be relaunched automatically with the new config."""
860 1002
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 def main(): 1183 def main():
1042 EPILOG = """This script is not intended for use by end-users. To configure 1184 EPILOG = """This script is not intended for use by end-users. To configure
1043 Chrome Remote Desktop, please install the app from the Chrome 1185 Chrome Remote Desktop, please install the app from the Chrome
1044 Web Store: https://chrome.google.com/remotedesktop""" 1186 Web Store: https://chrome.google.com/remotedesktop"""
1045 parser = optparse.OptionParser( 1187 parser = optparse.OptionParser(
1046 usage="Usage: %prog [options] [ -- [ X server options ] ]", 1188 usage="Usage: %prog [options] [ -- [ X server options ] ]",
1047 epilog=EPILOG) 1189 epilog=EPILOG)
1048 parser.add_option("-s", "--size", dest="size", action="append", 1190 parser.add_option("-s", "--size", dest="size", action="append",
1049 help="Dimensions of virtual desktop. This can be specified " 1191 help="Dimensions of virtual desktop. This can be specified "
1050 "multiple times to make multiple screen resolutions " 1192 "multiple times to make multiple screen resolutions "
1051 "available (if the Xvfb server supports this).") 1193 "available (if the X server supports this).")
1052 parser.add_option("-f", "--foreground", dest="foreground", default=False, 1194 parser.add_option("-f", "--foreground", dest="foreground", default=False,
1053 action="store_true", 1195 action="store_true",
1054 help="Don't run as a background daemon.") 1196 help="Don't run as a background daemon.")
1055 parser.add_option("", "--start", dest="start", default=False, 1197 parser.add_option("", "--start", dest="start", default=False,
1056 action="store_true", 1198 action="store_true",
1057 help="Start the host.") 1199 help="Start the host.")
1058 parser.add_option("-k", "--stop", dest="stop", default=False, 1200 parser.add_option("-k", "--stop", dest="stop", default=False,
1059 action="store_true", 1201 action="store_true",
1060 help="Stop the daemon currently running.") 1202 help="Stop the daemon currently running.")
1061 parser.add_option("", "--get-status", dest="get_status", default=False, 1203 parser.add_option("", "--get-status", dest="get_status", default=False,
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 watch_for_resolution_changes(options.watch_resolution) 1317 watch_for_resolution_changes(options.watch_resolution)
1176 return 0 1318 return 0
1177 1319
1178 if not options.start: 1320 if not options.start:
1179 # If no modal command-line options specified, print an error and exit. 1321 # If no modal command-line options specified, print an error and exit.
1180 print(EPILOG, file=sys.stderr) 1322 print(EPILOG, file=sys.stderr)
1181 return 1 1323 return 1
1182 1324
1183 # If a RANDR-supporting Xvfb is not available, limit the default size to 1325 # If a RANDR-supporting Xvfb is not available, limit the default size to
1184 # something more sensible. 1326 # something more sensible.
1185 if get_randr_supporting_x_server(): 1327 if USE_XORG_ENV_VAR not in os.environ and locate_xvfb_randr():
1186 default_sizes = DEFAULT_SIZES 1328 default_sizes = DEFAULT_SIZES
1187 else: 1329 else:
1188 default_sizes = DEFAULT_SIZE_NO_RANDR 1330 default_sizes = DEFAULT_SIZE_NO_RANDR
1189 1331
1190 # Collate the list of sizes that XRANDR should support. 1332 # Collate the list of sizes that XRANDR should support.
1191 if not options.size: 1333 if not options.size:
1192 if DEFAULT_SIZES_ENV_VAR in os.environ: 1334 if DEFAULT_SIZES_ENV_VAR in os.environ:
1193 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR] 1335 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR]
1194 options.size = default_sizes.split(",") 1336 options.size = default_sizes.split(",")
1195 1337
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 else: 1518 else:
1377 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) 1519 logging.info("Host exited with status %s." % os.WEXITSTATUS(status))
1378 elif os.WIFSIGNALED(status): 1520 elif os.WIFSIGNALED(status):
1379 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) 1521 logging.info("Host terminated by signal %s." % os.WTERMSIG(status))
1380 1522
1381 1523
1382 if __name__ == "__main__": 1524 if __name__ == "__main__":
1383 logging.basicConfig(level=logging.DEBUG, 1525 logging.basicConfig(level=logging.DEBUG,
1384 format="%(asctime)s:%(levelname)s:%(message)s") 1526 format="%(asctime)s:%(levelname)s:%(message)s")
1385 sys.exit(main()) 1527 sys.exit(main())
OLDNEW
« no previous file with comments | « remoting/host/curtain_mode_linux.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698