From 67287efb3c7308c9dafefe189f88962159843266 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 13 Nov 2014 18:31:14 -0800 Subject: [PATCH 001/377] chroot-etc/xserverrc-x11-freon Should probably be merged into xserverrc-x11, and the right approach selected at runtime. --- chroot-etc/xserverrc-x11-freon | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 chroot-etc/xserverrc-x11-freon diff --git a/chroot-etc/xserverrc-x11-freon b/chroot-etc/xserverrc-x11-freon new file mode 100644 index 000000000..73117bca9 --- /dev/null +++ b/chroot-etc/xserverrc-x11-freon @@ -0,0 +1,21 @@ +#!/bin/sh -e +# Copyright (c) 2014 The crouton Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Disable framebuffer compression when displaying natively. +# TODO: test FBC with SNA enabled on Haswell to regain power savings +fbc='/sys/module/i915/parameters/i915_enable_fbc' +if [ -w "$fbc" ]; then + echo 0 > "$fbc" +fi + +XMETHOD='x11' +XARGS='-nolisten tcp' +XARGS="$XARGS -logfile /tmp/Xorg.1234.log" +if [ -f /etc/crouton/xserverrc-local ]; then + . /etc/crouton/xserverrc-local +fi + +export LD_PRELOAD=/usr/local/lib/crouton_freon.so +exec /usr/bin/Xorg $XARGS "$@" From fe5bfb2e6a618e96a128363d846804a8ed792166 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 13 Nov 2014 18:43:28 -0800 Subject: [PATCH 002/377] freon.c: Dark magic LD_PRELOAD hack to make X11 happy in freon A simple pkill -USR1 Xorg switches display. Neat. --- Makefile | 3 + chroot-etc/xserverrc-x11-freon | 2 +- src/freon.c | 117 +++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/freon.c diff --git a/Makefile b/Makefile index 9a3eb63a1..d16b848d5 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,9 @@ $(EXTTARGET): $(EXTSOURCES) Makefile $(SRCTARGETS): src/$(patsubst crouton%,src/%.c,$@) $($@_DEPS) Makefile gcc $(CFLAGS) $(patsubst crouton%,src/%.c,$@) $($@_LIBS) -o $@ +croutonfreon.so: src/freon.c Makefile + gcc -g -Wall -Werror -shared -fPIC -ldl src/freon.c -o croutonfreon.so + extension: $(EXTTARGET) $(CONTRIBUTORS): $(GITHEAD) $(CONTRIBUTORSSED) diff --git a/chroot-etc/xserverrc-x11-freon b/chroot-etc/xserverrc-x11-freon index 73117bca9..0335f356b 100644 --- a/chroot-etc/xserverrc-x11-freon +++ b/chroot-etc/xserverrc-x11-freon @@ -17,5 +17,5 @@ if [ -f /etc/crouton/xserverrc-local ]; then . /etc/crouton/xserverrc-local fi -export LD_PRELOAD=/usr/local/lib/crouton_freon.so +export LD_PRELOAD=/usr/local/lib/croutonfreon.so exec /usr/bin/Xorg $XARGS "$@" diff --git a/src/freon.c b/src/freon.c new file mode 100644 index 000000000..fb6b6038f --- /dev/null +++ b/src/freon.c @@ -0,0 +1,117 @@ +/* Copyright (c) 2014 The crouton Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * LD_PRELOAD hack to make Xorg happy in a system without VT-switching. + * gcc -shared -fPIC -ldl -Wall -O2 freon.c -o croutonfreon.so + * + * Powered by black magic. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int tty0fd = -1; +static int tty7fd = -1; + +static int (*orig_ioctl)(int d, int request, void* data); +static int (*orig_open)(const char *pathname, int flags, mode_t mode); +static int (*orig_close)(int fd); + +static void preload_init() { + orig_ioctl = dlsym(RTLD_NEXT, "ioctl"); + orig_open = dlsym(RTLD_NEXT, "open"); + orig_close = dlsym(RTLD_NEXT, "close"); +} + +int ioctl(int fd, unsigned long int request, ...) { + if (!orig_ioctl) preload_init(); + + int ret = 0; + va_list argp; + + va_start(argp, request); + + void* data = va_arg(argp, void*); + + if (fd == tty0fd) { + fprintf(stderr, "ioctl tty0 %d %lx %p\n", fd, request, data); + switch (request) { + case VT_OPENQRY: { + fprintf(stderr, "OPEN\n"); + *(int*)data = 7; + break; + } + } + ret = 0; + } else if (fd == tty7fd) { + fprintf(stderr, "ioctl tty7 %d %lx %p\n", fd, request, data); + if (request == VT_GETSTATE) { + fprintf(stderr, "STATE\n"); + struct vt_stat* stat = data; + stat->v_active = 0; + } + + if ((request == VT_RELDISP && (long)data == 1) || + (request == VT_ACTIVATE && (long)data == 0)) { + fprintf(stderr, "Telling Chromium OS to regain control\n"); + system("host-dbus dbus-send --system --dest=org.chromium.LibCrosService --type=method_call /org/chromium/LibCrosService org.chromium.LibCrosServiceInterface.TakeDisplayOwnership"); + } else if ((request == VT_RELDISP && (long)data == 2) || + (request == VT_ACTIVATE && (long)data == 7)) { + fprintf(stderr, "Telling Chromium OS to drop control\n"); + system("host-dbus dbus-send --system --dest=org.chromium.LibCrosService --type=method_call /org/chromium/LibCrosService org.chromium.LibCrosServiceInterface.ReleaseDisplayOwnership"); + } + ret = 0; + } else { + if (request == EVIOCGRAB) { + fprintf(stderr, "ioctl GRAB %d %lx %p\n", fd, request, data); + /* Driver requested a grab: assume we have it already and report + * success */ + ret = 0; + } else { + ret = orig_ioctl(fd, request, data); + } + } + va_end(argp); + return ret; +} + +int open(const char *pathname, int flags, mode_t mode) { + if (!orig_open) preload_init(); + + fprintf(stderr, "open %s\n", pathname); + if (!strcmp(pathname, "/dev/tty0")) { + tty0fd = orig_open("/dev/null", flags, mode); + return tty0fd; + } else if (!strcmp(pathname, "/dev/tty7")) { + tty7fd = orig_open("/dev/null", flags, mode); + return tty7fd; + } else { + const char* event = "/dev/input/event"; + int fd = orig_open(pathname, flags, mode); + fprintf(stderr, "open %s %d\n", pathname, fd); + if (!strncmp(pathname, event, strlen(event))) { + fprintf(stderr, "GRAB\n"); + orig_ioctl(fd, EVIOCGRAB, (void *) 1); + } + return fd; + } +} + +int close(int fd) { + if (!orig_close) preload_init(); + + fprintf(stderr, "close %d\n", fd); + + if (fd == tty0fd) tty0fd = -1; + if (fd == tty7fd) tty7fd = -1; + return orig_close(fd); +} From 3a9a1f2aa0f26203fddd830809c3283fd982ab99 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 15 Jan 2015 07:57:22 -0800 Subject: [PATCH 003/377] Add support for Xorg on K1 (after 6689). Explicitly installing xorg on K1 is allowed (x11 target will use xephyr by default until 6689) so that people who know what they're doing can test things. --- targets/x11 | 6 +++++- targets/xorg | 22 +++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/targets/x11 b/targets/x11 index 4ddea7e79..32c26ba29 100644 --- a/targets/x11 +++ b/targets/x11 @@ -4,7 +4,11 @@ # found in the LICENSE file. if [ -f /sbin/frecon ]; then REQUIRES='xiwi' -elif [ "${ARCH#arm}" != "$ARCH" ]; then +elif grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo || \ + ([ "${ARCH#arm}" = "$ARCH" ] && \ + awk -F= '/_RELEASE_VERSION=/ { exit int($2) < 6689 }' \ + '/etc/lsb-release'); then + # Xorg won't work on Samsung ARM devices or K1 on release less than 6689 REQUIRES='xephyr' else REQUIRES='xorg' diff --git a/targets/xorg b/targets/xorg index 78c10ad84..340aa9aa2 100644 --- a/targets/xorg +++ b/targets/xorg @@ -5,8 +5,8 @@ if [ "${TARGETNOINSTALL:-c}" = 'c' ]; then if [ -f /sbin/frecon ]; then error 1 'xorg target does not yet work with Freon.' - elif [ "${ARCH#arm}" != "$ARCH" ]; then - error 1 'xorg target does not work on ARM.' + elif grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo; then + error 1 'xorg target does not work on Samsung ARM devices.' fi fi REQUIRES='audio' @@ -23,13 +23,14 @@ XMETHOD="${XMETHOD:-xorg}" rm -f '/etc/crouton/xserverrc-x11' ltspackages='' -# On precise, install lts-trusty xorg server to support newer hardware if kernel -# version != 3.4 (lts-trusty mesa requires version >=3.6) -if release -eq precise && ! uname -r | grep -q "^3.4."; then +# On non-ARM precise, install lts-trusty xorg server to support newer hardware +# if kernel version != 3.4 (lts-trusty mesa requires version >=3.6) +if [ "${ARCH#arm}" = "$ARCH" ] && release -eq precise \ + && ! uname -r | grep -q "^3.4."; then # We still install xorg later to pull in its dependencies - install --minimal xserver-xorg-lts-trusty libgl1-mesa-glx-lts-trusty \ - xserver-xorg-input-synaptics-lts-trusty ltspackages='-lts-trusty' + install --minimal "xserver-xorg$ltspackages" "libgl1-mesa-glx$ltspackages" \ + "xserver-xorg-input-synaptics$ltspackages" fi # On saucy onwards, if kernel version is 3.4, manually pin down old mesa @@ -100,8 +101,11 @@ END apt-get -y --force-yes --no-install-recommends dist-upgrade -f fi -install xorg dmz-cursor-theme \ - xserver-xorg-video-fbdev$ltspackages xserver-xorg-video-intel$ltspackages +install xorg dmz-cursor-theme xserver-xorg-video-fbdev$ltspackages +if [ "${ARCH#arm}" = "$ARCH" ]; then + install xserver-xorg-video-intel$ltspackages +fi + # Fix launching X11 from inside crosh (user doesn't own a TTY) sed -i 's/allowed_users=.*/allowed_users=anybody/' '/etc/X11/Xwrapper.config' From 52aaa436c6b74339609bd4ed175a2a7146673c94 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 6 Feb 2015 20:07:54 -0800 Subject: [PATCH 004/377] Dedup makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d16b848d5..f73ebba2f 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ $(SRCTARGETS): src/$(patsubst crouton%,src/%.c,$@) $($@_DEPS) Makefile gcc $(CFLAGS) $(patsubst crouton%,src/%.c,$@) $($@_LIBS) -o $@ croutonfreon.so: src/freon.c Makefile - gcc -g -Wall -Werror -shared -fPIC -ldl src/freon.c -o croutonfreon.so + gcc $(CFLAGS) -shared -fPIC -ldl src/freon.c -o croutonfreon.so extension: $(EXTTARGET) From 2c1cd34140e11db38f2ff93c8d76223348ec7189 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 6 Feb 2015 20:40:55 -0800 Subject: [PATCH 005/377] Compile and install croutonfreon.so --- installer/prepare.sh | 14 ++++++++++---- targets/xorg | 5 +++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/installer/prepare.sh b/installer/prepare.sh index 18d1f1de3..a8c06fde4 100755 --- a/installer/prepare.sh +++ b/installer/prepare.sh @@ -176,19 +176,25 @@ fixkeyboardmode() { # stdin to the specified output and strips it. Finally, removes whatever it # installed. This allows targets to provide on-demand binaries without # increasing the size of the chroot after install. -# $1: name; target is /usr/local/bin/crouton$1 +# $1: name; target is /usr/local/(bin|lib)/crouton$1[.so] # $2: linker flags, quoted together +# [$3]: if 'so', compiles as a shared object and installs it into lib # $3+: any package dependencies other than gcc and libc-dev, crouton-style. compile() { - local out="/usr/local/bin/crouton$1" linker="$2" - echo "Installing dependencies for $out..." 1>&2 + local out="/usr/local/bin/crouton$1" linker="$2" cflags='-xc -Os' + if [ "$3" = 'so' ]; then + out="/usr/local/lib/crouton$1.so" + cflags="$cflags -shared -fPIC" + shift 1 + fi shift 2 + echo "Installing dependencies for $out..." 1>&2 local pkgs="gcc libc6-dev $*" install --minimal --asdeps $pkgs &2 local tmp="`mktemp crouton.XXXXXX --tmpdir=/tmp`" addtrap "rm -f '$tmp'" - gcc -xc -Os - $linker -o "$tmp" + gcc $cflags - $linker -o "$tmp" /usr/bin/install -sDT "$tmp" "$out" } diff --git a/targets/xorg b/targets/xorg index 340aa9aa2..4c77b64dd 100644 --- a/targets/xorg +++ b/targets/xorg @@ -22,6 +22,11 @@ XMETHOD="${XMETHOD:-xorg}" # Migration from ambiguous XMETHOD rm -f '/etc/crouton/xserverrc-x11' +# On Freon, we need crazy xorg hacks +if [ ! -f "/sys/class/tty/tty0/active" ]; then + compile freon '-ldl' so +fi + ltspackages='' # On non-ARM precise, install lts-trusty xorg server to support newer hardware # if kernel version != 3.4 (lts-trusty mesa requires version >=3.6) From 5d9d41ae9bff2f4ec24f03cc520c9285c5fbef2b Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 6 Feb 2015 21:54:47 -0800 Subject: [PATCH 006/377] Fix compile warnings and clean up dbus calls --- src/freon.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/freon.c b/src/freon.c index fb6b6038f..03c8ae9c3 100644 --- a/src/freon.c +++ b/src/freon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 The crouton Authors. All rights reserved. +/* Copyright (c) 2015 The crouton Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -19,6 +19,11 @@ #include #include +#define FREON_DBUS_METHOD_CALL(function) \ + system("host-dbus dbus-send --system --dest=org.chromium.LibCrosService " \ + "--type=method_call --print-reply /org/chromium/LibCrosService " \ + "org.chromium.LibCrosServiceInterface." #function) + static int tty0fd = -1; static int tty7fd = -1; @@ -63,13 +68,14 @@ int ioctl(int fd, unsigned long int request, ...) { if ((request == VT_RELDISP && (long)data == 1) || (request == VT_ACTIVATE && (long)data == 0)) { fprintf(stderr, "Telling Chromium OS to regain control\n"); - system("host-dbus dbus-send --system --dest=org.chromium.LibCrosService --type=method_call /org/chromium/LibCrosService org.chromium.LibCrosServiceInterface.TakeDisplayOwnership"); + ret = FREON_DBUS_METHOD_CALL(TakeDisplayOwnership); } else if ((request == VT_RELDISP && (long)data == 2) || (request == VT_ACTIVATE && (long)data == 7)) { fprintf(stderr, "Telling Chromium OS to drop control\n"); - system("host-dbus dbus-send --system --dest=org.chromium.LibCrosService --type=method_call /org/chromium/LibCrosService org.chromium.LibCrosServiceInterface.ReleaseDisplayOwnership"); + ret = FREON_DBUS_METHOD_CALL(ReleaseDisplayOwnership); + } else { + ret = 0; } - ret = 0; } else { if (request == EVIOCGRAB) { fprintf(stderr, "ioctl GRAB %d %lx %p\n", fd, request, data); From 93f2408c8c38a8d12118984610f1c972a7f2a320 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 6 Feb 2015 20:13:33 -0800 Subject: [PATCH 007/377] Support Freon in xserverrc-xorg --- chroot-etc/xserverrc-x11-freon | 21 --------------------- chroot-etc/xserverrc-xorg | 11 ++++++++++- targets/post-common | 2 +- targets/x11 | 4 +--- targets/xorg | 4 +--- test/tests/35-xorg | 4 +--- 6 files changed, 14 insertions(+), 32 deletions(-) delete mode 100644 chroot-etc/xserverrc-x11-freon diff --git a/chroot-etc/xserverrc-x11-freon b/chroot-etc/xserverrc-x11-freon deleted file mode 100644 index 0335f356b..000000000 --- a/chroot-etc/xserverrc-x11-freon +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -e -# Copyright (c) 2014 The crouton Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Disable framebuffer compression when displaying natively. -# TODO: test FBC with SNA enabled on Haswell to regain power savings -fbc='/sys/module/i915/parameters/i915_enable_fbc' -if [ -w "$fbc" ]; then - echo 0 > "$fbc" -fi - -XMETHOD='x11' -XARGS='-nolisten tcp' -XARGS="$XARGS -logfile /tmp/Xorg.1234.log" -if [ -f /etc/crouton/xserverrc-local ]; then - . /etc/crouton/xserverrc-local -fi - -export LD_PRELOAD=/usr/local/lib/croutonfreon.so -exec /usr/bin/Xorg $XARGS "$@" diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index d5fb6f234..c516ca5c4 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -16,4 +16,13 @@ if [ -f /etc/crouton/xserverrc-local ]; then . /etc/crouton/xserverrc-local fi -exec /usr/bin/X $XARGS "$@" +X=/usr/bin/X + +# Freon needs the preload hack for X to coexist +if [ ! -f "/sys/class/tty/tty0/active" ]; then + X=/usr/bin/Xorg + XARGS="-logfile /tmp/Xorg.$$.log $XARGS" + export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" +fi + +exec "$X" $XARGS "$@" diff --git a/targets/post-common b/targets/post-common index 09f261b10..a9a8dfc15 100644 --- a/targets/post-common +++ b/targets/post-common @@ -35,7 +35,7 @@ if [ "${DISTROAKA:-"$DISTRO"}" = 'debian' ]; then fi # Add the primary user -groups='audio,video,sudo,plugdev' +groups='audio,input,video,sudo,plugdev' if ! grep -q ':1000:' /etc/passwd; then while ! echo "$username" | grep -q '^[a-z][-a-z0-9_]*$'; do if [ -n "$username" ]; then diff --git a/targets/x11 b/targets/x11 index 32c26ba29..da76368da 100644 --- a/targets/x11 +++ b/targets/x11 @@ -2,9 +2,7 @@ # Copyright (c) 2014 The crouton Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -if [ -f /sbin/frecon ]; then - REQUIRES='xiwi' -elif grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo || \ +if grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo || \ ([ "${ARCH#arm}" = "$ARCH" ] && \ awk -F= '/_RELEASE_VERSION=/ { exit int($2) < 6689 }' \ '/etc/lsb-release'); then diff --git a/targets/xorg b/targets/xorg index 4c77b64dd..7785887d5 100644 --- a/targets/xorg +++ b/targets/xorg @@ -3,9 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. if [ "${TARGETNOINSTALL:-c}" = 'c' ]; then - if [ -f /sbin/frecon ]; then - error 1 'xorg target does not yet work with Freon.' - elif grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo; then + if grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo; then error 1 'xorg target does not work on Samsung ARM devices.' fi fi diff --git a/test/tests/35-xorg b/test/tests/35-xorg index 28e7980ac..33afbe7c0 100644 --- a/test/tests/35-xorg +++ b/test/tests/35-xorg @@ -5,9 +5,7 @@ # All supported releases should be able to launch an xorg server if [ -z "$release" ]; then - if [ -f /sbin/frecon ]; then - log "xorg is not available on Freon. Skipping test." - elif uname -m | grep -q 'arm'; then + if uname -m | grep -q 'arm'; then log "xorg is not available on ARM. Skipping test." else echo "all" From c1515890999c2c41b0d84fd496cf18b1c721f0e2 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sun, 8 Feb 2015 22:12:52 -0800 Subject: [PATCH 008/377] Add display lock file to coordinate active display Also, silence tracing --- Makefile | 2 +- src/freon.c | 113 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 89 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index f73ebba2f..65e954941 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ $(SRCTARGETS): src/$(patsubst crouton%,src/%.c,$@) $($@_DEPS) Makefile gcc $(CFLAGS) $(patsubst crouton%,src/%.c,$@) $($@_LIBS) -o $@ croutonfreon.so: src/freon.c Makefile - gcc $(CFLAGS) -shared -fPIC -ldl src/freon.c -o croutonfreon.so + gcc $(CFLAGS) -shared -fPIC src/freon.c -ldl -o croutonfreon.so extension: $(EXTTARGET) diff --git a/src/freon.c b/src/freon.c index 03c8ae9c3..bd4fc38a7 100644 --- a/src/freon.c +++ b/src/freon.c @@ -11,30 +11,81 @@ #define _GNU_SOURCE #include #include +#include #include #include #include #include #include +#include #include #include +#define LOCK_FILE_DIR "/tmp/crouton-lock" +#define DISPLAY_LOCK_FILE LOCK_FILE_DIR "/display" #define FREON_DBUS_METHOD_CALL(function) \ system("host-dbus dbus-send --system --dest=org.chromium.LibCrosService " \ "--type=method_call --print-reply /org/chromium/LibCrosService " \ "org.chromium.LibCrosServiceInterface." #function) +// #define TRACE(...) fprintf(stderr, __VA_ARGS__) +#define TRACE(...) +#define ERROR(...) fprintf(stderr, __VA_ARGS__) + static int tty0fd = -1; static int tty7fd = -1; +static int lockfd = -1; static int (*orig_ioctl)(int d, int request, void* data); static int (*orig_open)(const char *pathname, int flags, mode_t mode); static int (*orig_close)(int fd); static void preload_init() { - orig_ioctl = dlsym(RTLD_NEXT, "ioctl"); - orig_open = dlsym(RTLD_NEXT, "open"); - orig_close = dlsym(RTLD_NEXT, "close"); + orig_ioctl = dlsym(RTLD_NEXT, "ioctl"); + orig_open = dlsym(RTLD_NEXT, "open"); + orig_close = dlsym(RTLD_NEXT, "close"); +} + +static int set_display_lock(unsigned int pid) { + if (lockfd == -1) { + if (!pid) { + ERROR("No display lock to release.\n"); + return 0; + } + (void) mkdir(LOCK_FILE_DIR, 0777); + lockfd = orig_open(DISPLAY_LOCK_FILE, O_CREAT | O_WRONLY, 0666); + if (lockfd == -1) { + ERROR("Unable to open display lock file.\n"); + return -1; + } + if (flock(lockfd, LOCK_EX) == -1) { + ERROR("Unable to lock display lock file.\n"); + return -1; + } + } + if (ftruncate(lockfd, 0) == -1) { + ERROR("Unable to truncate display lock file.\n"); + return -1; + } + char buf[11]; + int len; + if ((len = snprintf(buf, sizeof(buf), "%d\n", pid)) < 0) { + ERROR("pid sprintf failed.\n"); + return -1; + } + if (write(lockfd, buf, len) == -1) { + ERROR("Unable to write to display lock file.\n"); + return -1; + } + if (!pid) { + int ret = orig_close(lockfd); + lockfd = -1; + if (ret == -1) { + ERROR("Failure when closing display lock file.\n"); + } + return ret; + } + return 0; } int ioctl(int fd, unsigned long int request, ...) { @@ -42,43 +93,48 @@ int ioctl(int fd, unsigned long int request, ...) { int ret = 0; va_list argp; - va_start(argp, request); - void* data = va_arg(argp, void*); if (fd == tty0fd) { - fprintf(stderr, "ioctl tty0 %d %lx %p\n", fd, request, data); - switch (request) { - case VT_OPENQRY: { - fprintf(stderr, "OPEN\n"); + TRACE("ioctl tty0 %d %lx %p\n", fd, request, data); + if (request == VT_OPENQRY) { + TRACE("OPEN\n"); *(int*)data = 7; - break; - } } ret = 0; } else if (fd == tty7fd) { - fprintf(stderr, "ioctl tty7 %d %lx %p\n", fd, request, data); + TRACE("ioctl tty7 %d %lx %p\n", fd, request, data); if (request == VT_GETSTATE) { - fprintf(stderr, "STATE\n"); + TRACE("STATE\n"); struct vt_stat* stat = data; stat->v_active = 0; } if ((request == VT_RELDISP && (long)data == 1) || (request == VT_ACTIVATE && (long)data == 0)) { - fprintf(stderr, "Telling Chromium OS to regain control\n"); - ret = FREON_DBUS_METHOD_CALL(TakeDisplayOwnership); + if (lockfd != -1) { + TRACE("Telling Chromium OS to regain control\n"); + ret = FREON_DBUS_METHOD_CALL(TakeDisplayOwnership); + if (set_display_lock(0)) { + ERROR("Failed to release display lock\n"); + } + } } else if ((request == VT_RELDISP && (long)data == 2) || (request == VT_ACTIVATE && (long)data == 7)) { - fprintf(stderr, "Telling Chromium OS to drop control\n"); - ret = FREON_DBUS_METHOD_CALL(ReleaseDisplayOwnership); + if (!set_display_lock(getpid())) { + TRACE("Telling Chromium OS to drop control\n"); + ret = FREON_DBUS_METHOD_CALL(ReleaseDisplayOwnership); + } else { + ERROR("Unable to claim display lock\n"); + ret = -1; + } } else { ret = 0; } } else { if (request == EVIOCGRAB) { - fprintf(stderr, "ioctl GRAB %d %lx %p\n", fd, request, data); + TRACE("ioctl GRAB %d %lx %p\n", fd, request, data); /* Driver requested a grab: assume we have it already and report * success */ ret = 0; @@ -90,10 +146,14 @@ int ioctl(int fd, unsigned long int request, ...) { return ret; } -int open(const char *pathname, int flags, mode_t mode) { +int open(const char *pathname, int flags, ...) { if (!orig_open) preload_init(); - fprintf(stderr, "open %s\n", pathname); + va_list argp; + va_start(argp, flags); + int mode = va_arg(argp, int); + + TRACE("open %s\n", pathname); if (!strcmp(pathname, "/dev/tty0")) { tty0fd = orig_open("/dev/null", flags, mode); return tty0fd; @@ -103,9 +163,9 @@ int open(const char *pathname, int flags, mode_t mode) { } else { const char* event = "/dev/input/event"; int fd = orig_open(pathname, flags, mode); - fprintf(stderr, "open %s %d\n", pathname, fd); + TRACE("open %s %d\n", pathname, fd); if (!strncmp(pathname, event, strlen(event))) { - fprintf(stderr, "GRAB\n"); + TRACE("GRAB\n"); orig_ioctl(fd, EVIOCGRAB, (void *) 1); } return fd; @@ -115,9 +175,12 @@ int open(const char *pathname, int flags, mode_t mode) { int close(int fd) { if (!orig_close) preload_init(); - fprintf(stderr, "close %d\n", fd); + TRACE("close %d\n", fd); - if (fd == tty0fd) tty0fd = -1; - if (fd == tty7fd) tty7fd = -1; + if (fd == tty0fd) { + tty0fd = -1; + } else if (fd == tty7fd) { + tty7fd = -1; + } return orig_close(fd); } From 6b77a8a9cb3b4546b3d7f36e724bc58203a42050 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Mon, 9 Feb 2015 00:30:12 -0800 Subject: [PATCH 009/377] Add freon support to croutoncycle --- chroot-bin/croutoncycle | 57 ++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/chroot-bin/croutoncycle b/chroot-bin/croutoncycle index 1d1c152c1..e1f8c518a 100755 --- a/chroot-bin/croutoncycle +++ b/chroot-bin/croutoncycle @@ -76,9 +76,6 @@ export XAUTHORITY='' # Set to y if there is any xiwi instance running xiwiactive='' -# Set to y if aura is running without a X server -noaurax='' - # Prepare display list for easier looping displist='' for disp in /tmp/.X*-lock; do @@ -97,27 +94,30 @@ for disp in /tmp/.X*-lock; do fi done -# host-x11 fails if no Chromium OS server exist -if host-x11 true 2>/dev/null; then +# Set to the freon display owner if freon is used +freonowner='' +if [ ! -f "/sys/class/tty/tty0/active" ]; then + if [ -f "/tmp/crouton-lock/display" ]; then + read freonowner < "/tmp/crouton-lock/display" + fi + freonowner="${freonowner:-0}" + winlist="aura*" + aurawin="aura" + tty='' +else # List windows on :0. Includes aura winlist="`host-x11 croutonwmtools list nim | \ sort | awk '{ printf $NF " " }'`" aurawin="`host-x11 croutonwmtools list ni | \ awk '$1 == "aura_root_0" { print $NF; exit }'`" tty="`cat '/sys/class/tty/tty0/active'`" -else - # No X11 server - noaurax='y' - winlist="aura*" - aurawin="aura" - tty="tty1" fi # Combine the two fulllist="$winlist$displist" fulllist="${fulllist% }" -if [ "$tty" = 'tty1' ]; then +if [ "$freonowner" = 0 -o "$tty" = 'tty1' ]; then # Either in Chromium OS, xephyr/xiwi chroot, or window. # Active window is starred. for disp in $winlist; do @@ -133,7 +133,7 @@ if [ "$tty" = 'tty1' ]; then break fi done -else +elif [ -z "$freonowner" ]; then # Poll the displays to figure out which one owns this VT curdisp="$tty" for disp in $displist; do @@ -143,6 +143,14 @@ else break fi done +else + # Match the pid to the current freon owner + for lockfile in /tmp/.X*-lock; do + if grep -q "\\<$freonowner$" "$lockfile"; then + curdisp="${lockfile#*X}" + curdisp=":${curdisp%%-*}" + fi + done fi # List the displays if requested @@ -153,7 +161,7 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then '/var/host/lsb-release'`" fi ( - if [ -z "$noaurax" ]; then + if [ -z "$freonowner" ]; then host-x11 croutonwmtools list nim else echo "aura_root_0 aura*" @@ -261,7 +269,7 @@ if [ "$destdisp" = "$curdisp" -a -z "$force" ]; then fi # Make sure tap-to-click is enabled -if [ -z "$noaurax" ] && hash xinput 2>/dev/null; then +if [ -z "$freonowner" ] && hash xinput 2>/dev/null; then for id in `host-x11 xinput --list --id-only`; do host-x11 xinput set-prop "$id" 'Tap Paused' 0 2>/dev/null || true done @@ -269,7 +277,7 @@ fi # Determine if the target display is on a VT if [ "${destdisp#:}" = "$destdisp" ]; then - if [ -z "$noaurax" ]; then + if [ -z "$freonowner" ]; then eval "`host-x11`" # Raise the right window after chvting, so that it can update if [ "$tty" != 'tty1' ]; then @@ -277,6 +285,8 @@ if [ "${destdisp#:}" = "$destdisp" ]; then sleep .1 fi croutonwmtools raise "${destdisp%"*"}" + elif [ "${freonowner:-0}" != 0 ]; then + kill -USR1 "$freonowner" fi if [ -n "$xiwiactive" -a "${destdisp%"*"}" = "$aurawin" ]; then @@ -288,15 +298,17 @@ if [ "${destdisp#:}" = "$destdisp" ]; then else export DISPLAY="$destdisp" if xprop -root 'CROUTON_XMETHOD' 2>/dev/null | grep -q '= "xiwi"$'; then - if [ -z "$noaurax" -a "$tty" != 'tty1' ]; then + if [ -z "$freonowner" -a "$tty" != 'tty1' ]; then sudo -n chvt 1 sleep .1 + elif [ "${freonowner:-0}" != 0 ]; then + kill -USR1 "$freonowner" fi STATUS="`echo -n "X${destdisp}" | websocketcommand`" if [ "$STATUS" != 'XOK' ]; then error 1 "${STATUS#?}" fi - else + elif [ -z "$freonowner" ]; then dest="`xprop -root 'XFree86_VT' 2>/dev/null`" dest="${dest##* }" if [ "${dest#[1-9]}" = "$dest" ]; then @@ -307,6 +319,15 @@ else # display will be stuck on the old vt. sudo -n chvt 2 sudo -n chvt "$dest" + else + dest="/tmp/.X${destdisp#:}-lock" + if [ -f "$dest" ]; then + # Trigger the target before releasing the current owner + kill -USR1 `cat /tmp/.X${destdisp#:}-lock` + fi + if [ "${freonowner:-0}" != 0 ]; then + kill -USR1 "$freonowner" + fi fi fi From bbc34f48943e2bfacd3f19a1aaf23c5d2d380c9d Mon Sep 17 00:00:00 2001 From: David Schneider Date: Mon, 9 Feb 2015 17:05:16 -0800 Subject: [PATCH 010/377] Use SNA+TearFree if FBC is present. Saves power on Haswell and works better with Freon. Fixes #520 and hopefully doesn't break any platforms. --- chroot-bin/croutonxinitrc-wrapper | 9 --------- chroot-etc/xorg-intel-sna.conf | 12 ++++++++++++ chroot-etc/xserverrc-xorg | 7 ------- host-bin/enter-chroot | 8 -------- targets/xorg | 12 +++++++++++- 5 files changed, 23 insertions(+), 25 deletions(-) create mode 100644 chroot-etc/xorg-intel-sna.conf diff --git a/chroot-bin/croutonxinitrc-wrapper b/chroot-bin/croutonxinitrc-wrapper index d4eb93b63..b2a27cd7a 100755 --- a/chroot-bin/croutonxinitrc-wrapper +++ b/chroot-bin/croutonxinitrc-wrapper @@ -180,13 +180,4 @@ fi echo "Running exit commands..." 1>&2 -# Restore framebuffer compression if there are no other non-Chromium X servers -fbc='/sys/module/i915/parameters/i915_enable_fbc' -if [ -w "$fbc" ]; then - # There is at least 2 servers running (the current one and Chromium OS) - if [ "`ps -CX -CXorg -CXephyr -opid= | wc -l`" -le 2 ]; then - echo 1 > "$fbc" - fi -fi - exit "$ret" diff --git a/chroot-etc/xorg-intel-sna.conf b/chroot-etc/xorg-intel-sna.conf new file mode 100644 index 000000000..3f2b369b9 --- /dev/null +++ b/chroot-etc/xorg-intel-sna.conf @@ -0,0 +1,12 @@ +# Copyright (c) 2015 The crouton Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# On Intel platforms with FBC enabled, in order to see anything we need to use +# the SNA driver with the TearFree option. +Section "Device" + Identifier "Intel Graphics SNA+TearFree" + Driver "intel" + Option "AccelMethod" "sna" + Option "TearFree" "true" +EndSection diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index c516ca5c4..679c644b6 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -3,13 +3,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# Disable framebuffer compression when displaying natively. -# TODO: test FBC with SNA enabled on Haswell to regain power savings -fbc='/sys/module/i915/parameters/i915_enable_fbc' -if [ -w "$fbc" ]; then - echo 0 > "$fbc" -fi - export XMETHOD='xorg' XARGS='-nolisten tcp' if [ -f /etc/crouton/xserverrc-local ]; then diff --git a/host-bin/enter-chroot b/host-bin/enter-chroot index 74ab05f95..2b5662cc8 100755 --- a/host-bin/enter-chroot +++ b/host-bin/enter-chroot @@ -146,14 +146,6 @@ fi # Avoid kernel panics due to slow I/O disablehungtask -# Enable control of framebuffer compression (if used) by video users -for fbc in '/sys/kernel/debug/dri/0/'*fbc*; do :; done -if [ -f "$fbc" ] && ! grep -q 'disabled per module param' "$fbc"; then - fbc='/sys/module/i915/parameters/i915_enable_fbc' - chgrp video "$fbc" - chmod g+w "$fbc" -fi - # Allow X server running as normal user to set/drop DRM master drm_relax_file="/sys/kernel/debug/dri/drm_master_relax" if [ -f "$drm_relax_file" ]; then diff --git a/targets/xorg b/targets/xorg index 7785887d5..e902e85e0 100644 --- a/targets/xorg +++ b/targets/xorg @@ -11,7 +11,7 @@ REQUIRES='audio' PROVIDES='x11' DESCRIPTION='X.Org X11 backend. Enables GPU acceleration on supported platforms.' CHROOTBIN='croutoncycle croutonxinitrc-wrapper setres xinit' -CHROOTETC='xbindkeysrc.scm xserverrc xserverrc-xorg xserverrc-local.example' +CHROOTETC='xbindkeysrc.scm xorg-intel-sna.conf xserverrc xserverrc-xorg xserverrc-local.example' . "${TARGETSDIR:="$PWD"}/common" ### Append to prepare.sh: @@ -109,6 +109,16 @@ if [ "${ARCH#arm}" = "$ARCH" ]; then install xserver-xorg-video-intel$ltspackages fi +# This is a system with framebuffer compression, so we need SNA+tearfree +xorgconf='/usr/share/X11/xorg.conf.d/20-crouton-intel-sna.conf' +if grep -q 1 '/sys/module/i915/parameters/i915_enable_fbc' 2>/dev/null; then + mkdir -p "${xorgconf%/*}" + ln -sfT /etc/crouton/xorg-intel-sna.conf "$xorgconf" +else + # In case this got moved to a different system, delete the config + rm -f "$xorgconf" +fi + # Fix launching X11 from inside crosh (user doesn't own a TTY) sed -i 's/allowed_users=.*/allowed_users=anybody/' '/etc/X11/Xwrapper.config' From e78267c4e54598ccb1febbba284416dcaa89bfb2 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 11 Feb 2015 16:41:18 -0800 Subject: [PATCH 011/377] Fix target display switching and xiwi switching with Xephyr --- chroot-bin/croutoncycle | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/chroot-bin/croutoncycle b/chroot-bin/croutoncycle index e1f8c518a..18847ea99 100755 --- a/chroot-bin/croutoncycle +++ b/chroot-bin/croutoncycle @@ -224,6 +224,12 @@ fi if [ -n "${cmd#[pn]}" ]; then if [ "${cmd#:}" != "$cmd" ]; then destdisp="$cmd" + # Resolve a xephyr display into its ID + if DISPLAY="$destdisp" xprop -root 'CROUTON_XMETHOD' 2>/dev/null \ + | grep -q '= "xephyr"$'; then + destdisp="`host-x11 croutonwmtools list ni | \ + awk "/^Xephyr on $destdisp\.0/"' { print $NF; exit }'`" + fi else i=0 destdisp='' @@ -304,6 +310,9 @@ else elif [ "${freonowner:-0}" != 0 ]; then kill -USR1 "$freonowner" fi + if [ -z "$freonowner" ]; then + host-x11 croutonwmtools raise "$aurawin" + fi STATUS="`echo -n "X${destdisp}" | websocketcommand`" if [ "$STATUS" != 'XOK' ]; then error 1 "${STATUS#?}" From 63faaa51a4d9478dcc311f35629c4d4e12387b16 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 13 Feb 2015 18:42:25 -0800 Subject: [PATCH 012/377] Add triggerhappy as the system-wide keyboard daemon --- chroot-bin/croutonxinitrc-wrapper | 47 +++++++++++++++++++++++-------- chroot-etc/xbindkeysrc.scm | 12 ++++++-- targets/x11-common | 4 +-- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/chroot-bin/croutonxinitrc-wrapper b/chroot-bin/croutonxinitrc-wrapper index b2a27cd7a..9b1d3db44 100755 --- a/chroot-bin/croutonxinitrc-wrapper +++ b/chroot-bin/croutonxinitrc-wrapper @@ -78,7 +78,42 @@ if [ "$XMETHOD" = 'xephyr' ]; then croutonwheel $CROUTON_WHEEL_PARAMS & fi -# xbindkeys and other input-related apps are not needed for kiwi +# Launch system-wide triggerhappy if it isn't running +mkdir -m 775 -p /tmp/crouton-lock +{ + # Only let one instance *really* run at a time + flock 3 + cmdprev='/usr/local/bin/croutoncycle p' + cmdnext='/usr/local/bin/croutoncycle n' + echo "# +# Ctrl+Alt+Shift+F1 = previous. Require full key release to avoid stuck keys. +KEY_F1+KEY_LEFTSHIFT+KEY_LEFTCTRL+KEY_LEFTALT@ 1 @p +KEY_F1@p 0 $cmdprev +KEY_LEFTSHIFT@p 0 $cmdprev +KEY_LEFTCTRL@p 0 $cmdprev +KEY_LEFTALT@p 0 $cmdprev +KEY_F1@p 0 @ +KEY_LEFTSHIFT@p 0 @ +KEY_LEFTCTRL@p 0 @ +KEY_LEFTALT@p 0 @ +# +# Ctrl+Alt+Shift+F2 = next Require full key release to avoid stuck keys. +KEY_F2+KEY_LEFTSHIFT+KEY_LEFTCTRL+KEY_LEFTALT@ 1 @n +KEY_F2@n 0 $cmdnext +KEY_LEFTSHIFT@n 0 $cmdnext +KEY_LEFTCTRL@n 0 $cmdnext +KEY_LEFTALT@n 0 $cmdnext +KEY_F2@n 0 @ +KEY_LEFTSHIFT@n 0 @ +KEY_LEFTCTRL@n 0 @ +KEY_LEFTALT@n 0 @ +#" | /usr/sbin/thd --triggers /dev/stdin \ + --socket /tmp/crouton-lock/thd.socket /dev/input/event* >/dev/null & + trap "kill '$!' 2>/dev/null" HUP INT TERM + wait "$!" || true +} 3>/tmp/crouton-lock/xbindkeys & + +# Input-related stuff is not needed for kiwi if [ "$XMETHOD" != "xiwi" ]; then # Apply the Chromebook keyboard map if installed. if [ -f '/usr/share/X11/xkb/compat/chromebook' ]; then @@ -88,16 +123,6 @@ if [ "$XMETHOD" != "xiwi" ]; then # Launch key binding daemon xbindkeys -fg /etc/crouton/xbindkeysrc.scm - # Launch xbindkeys for the Chromium OS X server if it isn't running - mkdir -m 775 -p /tmp/crouton-lock - { - # Only let one instance *really* run at a time - flock 3 - XMETHOD='' host-x11 xbindkeys -n -fg /etc/crouton/xbindkeysrc.scm & - trap "kill '$!' 2>/dev/null" HUP INT TERM - wait "$!" || true - } 3>/tmp/crouton-lock/xbindkeys & - # Launch touchegg if it is requested. toucheggconf='/etc/touchegg.conf' if [ -f "$toucheggconf" ]; then diff --git a/chroot-etc/xbindkeysrc.scm b/chroot-etc/xbindkeysrc.scm index ad06b55f1..1fa69ff4b 100644 --- a/chroot-etc/xbindkeysrc.scm +++ b/chroot-etc/xbindkeysrc.scm @@ -4,9 +4,15 @@ ;; Run xbindkeys -dg for some example configuration file with explanation -; Cycle chroots -(xbindkey '(control shift alt F1) "xte 'keyup F1'; croutoncycle prev") -(xbindkey '(control shift alt F2) "xte 'keyup F2'; croutoncycle next") +; Cycle chroots. On most systems, this is handled by the triggerhappy daemon. +; On freon, we have to do it ourselves since we currently grab the event device. +(if (access? "/sys/class/tty/tty0/active" F_OK) (begin + (xbindkey '(control shift alt F1) "") + (xbindkey '(control shift alt F2) "") +) (begin + (xbindkey '(control shift alt F1) "xte 'keyup F1'; croutoncycle prev") + (xbindkey '(control shift alt F2) "xte 'keyup F2'; croutoncycle next") +)) ; Extra bindings that must only be activated in chroot X11/Xephyr (if (not (string-null? (getenv "XMETHOD"))) diff --git a/targets/x11-common b/targets/x11-common index d646c3189..ee0098ce7 100644 --- a/targets/x11-common +++ b/targets/x11-common @@ -20,8 +20,8 @@ install --minimal dbus xdg-utils ln -sf croutonpowerd /usr/local/bin/gnome-screensaver-command ln -sf croutonpowerd /usr/local/bin/xscreensaver-command -# Install xbindkeys and xautomation for key shortcuts and kbd for chvt -install --minimal xbindkeys xautomation kbd +# Install triggerhappy, xbindkeys and xautomation for shortcuts; kbd for chvt +install --minimal triggerhappy xbindkeys xautomation kbd # Allow users to run sudo chvt without password, so we don't need to run # croutoncycle as root echo '%sudo ALL = NOPASSWD:/bin/chvt' > /etc/sudoers.d/chvt From 2646a9f4e3009152ffddc6696315abba4ab0e444 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 11 Feb 2015 18:35:41 -0800 Subject: [PATCH 013/377] Disallow launching Xorg from frecon --- chroot-etc/xserverrc-xorg | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index 679c644b6..145953363 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -11,8 +11,19 @@ fi X=/usr/bin/X -# Freon needs the preload hack for X to coexist +# Handle Freon systems if [ ! -f "/sys/class/tty/tty0/active" ]; then + # We won't be able to launch properly if running from frecon + ppid="$$" + while [ -n "$ppid" -a "$ppid" -ne 1 ]; do + ppid="`ps -p "$ppid" -o 'ppid=' 2>/dev/null | sed 's/ //g'`" + if ps -p "$ppid" -o 'comm=' | grep -q '^frecon$'; then + echo 'Xorg X11 servers cannot be launched from Frecon.' 1>&2 + echo 'Return to Chromium OS and use crosh to launch X.' 1>&2 + exit 2 + fi + done + # Freon necessitates the preload hack for X to coexist X=/usr/bin/Xorg XARGS="-logfile /tmp/Xorg.$$.log $XARGS" export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" From f11169f4cdb4f6502ef8d023713543b937e80f71 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sat, 14 Feb 2015 18:09:13 -0800 Subject: [PATCH 014/377] Kill frecon on launching xorg to workaround crbug.com/457075 --- chroot-etc/xserverrc-xorg | 5 +++++ host-bin/enter-chroot | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index 145953363..36acb66d6 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -23,6 +23,11 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then exit 2 fi done + # Use the daemon to kill frecon. + # FIXME: remove when crbug.com/457075 is resolved + if [ -w '/tmp/crouton-lock/frecon' ]; then + echo >> '/tmp/crouton-lock/frecon' + fi # Freon necessitates the preload hack for X to coexist X=/usr/bin/Xorg XARGS="-logfile /tmp/Xorg.$$.log $XARGS" diff --git a/host-bin/enter-chroot b/host-bin/enter-chroot index 2b5662cc8..d16419ff1 100755 --- a/host-bin/enter-chroot +++ b/host-bin/enter-chroot @@ -646,6 +646,27 @@ if [ ! "$NOLOGIN" = 1 ] && grep -q '^root:' "$passwd" 2>/dev/null; then # systemd-logind doesn't fork chrootcmd "/lib/systemd/systemd-logind >/dev/null 2>&1 /dev/null 2>&1 > '$CROUTONLOCKDIR/frecon') & :" + fi fi # Start the chroot and any specified command From 89ebac8dad743e5a174babb05c92f0c67238d755 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 19 Feb 2015 18:46:25 -0800 Subject: [PATCH 015/377] Replace triggerhappy with croutontriggerd. Doesn't pull in any dependencies. Monitors for new keyboards. Can be used for other event-file-based triggering in the future. --- chroot-bin/croutontriggerd | 88 +++++++++++++++++++++++++++++++ chroot-bin/croutonxinitrc-wrapper | 38 ++----------- targets/x11-common | 4 +- targets/xephyr | 2 +- targets/xiwi | 2 +- targets/xorg | 2 +- 6 files changed, 96 insertions(+), 40 deletions(-) create mode 100755 chroot-bin/croutontriggerd diff --git a/chroot-bin/croutontriggerd b/chroot-bin/croutontriggerd new file mode 100755 index 000000000..811f7092b --- /dev/null +++ b/chroot-bin/croutontriggerd @@ -0,0 +1,88 @@ +#!/bin/sh -e +# Copyright (c) 2015 The crouton Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Monitors keyboard events for the crouton switch command. + +. "`dirname "$0"`/../installer/functions" + +# hexdump output format variables +SECONDS_LO='$1' +SECONDS_HI='$2' +USECONDS_LO='$3' +USECONDS_HI='$4' +TYPE='$5' +KEY='$6' +STATE='$7' + +# constants +TYPE_EV_KEY=1 +STATE_DOWN=1 +STATE_UP=0 +KEY_LEFTCTRL=29 +KEY_LEFTALT=56 +KEY_LEFTSHIFT=42 +KEY_F1=59 +KEY_F2=60 + +EVENT_DEV_POLL=15 + +# Only one at a time. xbindkeys lockfile is for legacy compatibility +mkdir -m 775 -p "$CROUTONLOCKDIR" +exec 3>>"$CROUTONLOCKDIR/xbindkeys" +if ! flock -n 3; then + echo "Another instance of ${0##*/} running, waiting..." + flock 3 +fi + +# Reset event variables to handle strange environments +unset `set | grep -o '^event[0-9]*'` 2>/dev/null || true + +# Poll for new event files and dump the output +while :; do + # Clean up old hexdumps and start new ones + for event in `set | grep -o '^event[0-9]*'` /dev/input/event*; do + # Check if the event file is already monitored + eval "pid=\"\${${event##*/}:-0}\"" + if [ "$pid" != 0 ]; then + # Check if it's still running + if kill -0 "$pid" 2>/dev/null; then + continue + fi + wait "$pid" || true + fi + # Clean up old variables + if [ "${event#/}" = "$event" ]; then + unset "$event" + else + # Read in the event files and split into input_event fields + stdbuf -oL hexdump -e '4/4 "%u " " " 2/2 "%u " " " 1/4 "%u " "\n"' \ + "$event" & + eval "${event##*/}='$!'" + fi + done + # Avoid picking up the event variable + unset event + # Kill all event daemons + pids="`set | sed -n 's/^event[0-9]*=.\(.*\).$/\1/p' | tr '\n' ' '`" + settrap "kill $pids 2>/dev/null;" + # Wait for next poll + sleep "$EVENT_DEV_POLL" +done | unbuffered_awk " + function update() { + if (!cmd && c && s && a && p) { + cmd = \"p\" + } else if (!cmd && c && s && a && n) { + cmd = \"n\" + } else if (cmd && !c && !s && !a && !p && !n) { + system(\"/usr/local/bin/croutoncycle \" cmd) + cmd = \"\" + } + } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTCTRL { c = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTSHIFT { s = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTALT { a = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_F1 { p = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_F2 { n = $STATE; update() } +" diff --git a/chroot-bin/croutonxinitrc-wrapper b/chroot-bin/croutonxinitrc-wrapper index 9b1d3db44..88cc4c1c6 100755 --- a/chroot-bin/croutonxinitrc-wrapper +++ b/chroot-bin/croutonxinitrc-wrapper @@ -78,40 +78,8 @@ if [ "$XMETHOD" = 'xephyr' ]; then croutonwheel $CROUTON_WHEEL_PARAMS & fi -# Launch system-wide triggerhappy if it isn't running -mkdir -m 775 -p /tmp/crouton-lock -{ - # Only let one instance *really* run at a time - flock 3 - cmdprev='/usr/local/bin/croutoncycle p' - cmdnext='/usr/local/bin/croutoncycle n' - echo "# -# Ctrl+Alt+Shift+F1 = previous. Require full key release to avoid stuck keys. -KEY_F1+KEY_LEFTSHIFT+KEY_LEFTCTRL+KEY_LEFTALT@ 1 @p -KEY_F1@p 0 $cmdprev -KEY_LEFTSHIFT@p 0 $cmdprev -KEY_LEFTCTRL@p 0 $cmdprev -KEY_LEFTALT@p 0 $cmdprev -KEY_F1@p 0 @ -KEY_LEFTSHIFT@p 0 @ -KEY_LEFTCTRL@p 0 @ -KEY_LEFTALT@p 0 @ -# -# Ctrl+Alt+Shift+F2 = next Require full key release to avoid stuck keys. -KEY_F2+KEY_LEFTSHIFT+KEY_LEFTCTRL+KEY_LEFTALT@ 1 @n -KEY_F2@n 0 $cmdnext -KEY_LEFTSHIFT@n 0 $cmdnext -KEY_LEFTCTRL@n 0 $cmdnext -KEY_LEFTALT@n 0 $cmdnext -KEY_F2@n 0 @ -KEY_LEFTSHIFT@n 0 @ -KEY_LEFTCTRL@n 0 @ -KEY_LEFTALT@n 0 @ -#" | /usr/sbin/thd --triggers /dev/stdin \ - --socket /tmp/crouton-lock/thd.socket /dev/input/event* >/dev/null & - trap "kill '$!' 2>/dev/null" HUP INT TERM - wait "$!" || true -} 3>/tmp/crouton-lock/xbindkeys & +# Launch system-wide trigger daemon +croutontriggerd & # Input-related stuff is not needed for kiwi if [ "$XMETHOD" != "xiwi" ]; then @@ -120,7 +88,7 @@ if [ "$XMETHOD" != "xiwi" ]; then setxkbmap -model chromebook fi - # Launch key binding daemon + # Launch X-server-local key binding daemon xbindkeys -fg /etc/crouton/xbindkeysrc.scm # Launch touchegg if it is requested. diff --git a/targets/x11-common b/targets/x11-common index ee0098ce7..b05b4193f 100644 --- a/targets/x11-common +++ b/targets/x11-common @@ -20,8 +20,8 @@ install --minimal dbus xdg-utils ln -sf croutonpowerd /usr/local/bin/gnome-screensaver-command ln -sf croutonpowerd /usr/local/bin/xscreensaver-command -# Install triggerhappy, xbindkeys and xautomation for shortcuts; kbd for chvt -install --minimal triggerhappy xbindkeys xautomation kbd +# Install xbindkeys and xautomation for shortcuts; kbd for chvt +install --minimal xbindkeys xautomation kbd # Allow users to run sudo chvt without password, so we don't need to run # croutoncycle as root echo '%sudo ALL = NOPASSWD:/bin/chvt' > /etc/sudoers.d/chvt diff --git a/targets/xephyr b/targets/xephyr index 3a8b18af6..3fbfbf87b 100644 --- a/targets/xephyr +++ b/targets/xephyr @@ -8,7 +8,7 @@ fi REQUIRES='audio' PROVIDES='x11' DESCRIPTION='Nested X11 backend. Improves compatibility but lacks GPU accel.' -CHROOTBIN='croutoncycle croutonwheel croutonxinitrc-wrapper xinit' +CHROOTBIN='croutoncycle croutontriggerd croutonwheel croutonxinitrc-wrapper xinit' CHROOTETC='xbindkeysrc.scm xserverrc xserverrc-xephyr xserverrc-local.example' . "${TARGETSDIR:="$PWD"}/common" diff --git a/targets/xiwi b/targets/xiwi index 8dbc61e67..ea250fa22 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -5,7 +5,7 @@ REQUIRES='audio extension' PROVIDES='x11' DESCRIPTION='X.org X11 backend running unaccelerated in a Chromium OS window.' -CHROOTBIN='croutoncycle croutonfindnacl croutonxinitrc-wrapper setres xinit' +CHROOTBIN='croutoncycle croutonfindnacl croutontriggerd croutonxinitrc-wrapper setres xinit' CHROOTETC='xbindkeysrc.scm xorg-dummy.conf xserverrc xserverrc-xiwi xserverrc-local.example' . "${TARGETSDIR:="$PWD"}/common" diff --git a/targets/xorg b/targets/xorg index e902e85e0..d9d169b95 100644 --- a/targets/xorg +++ b/targets/xorg @@ -10,7 +10,7 @@ fi REQUIRES='audio' PROVIDES='x11' DESCRIPTION='X.Org X11 backend. Enables GPU acceleration on supported platforms.' -CHROOTBIN='croutoncycle croutonxinitrc-wrapper setres xinit' +CHROOTBIN='croutoncycle croutontriggerd croutonxinitrc-wrapper setres xinit' CHROOTETC='xbindkeysrc.scm xorg-intel-sna.conf xserverrc xserverrc-xorg xserverrc-local.example' . "${TARGETSDIR:="$PWD"}/common" From 5559e432db980f6d6ae4fa7bbdf12442af67c9f9 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 19 Feb 2015 18:53:56 -0800 Subject: [PATCH 016/377] Style improvements. --- chroot-bin/croutoncycle | 2 +- host-bin/enter-chroot | 2 +- installer/prepare.sh | 4 +++- src/freon.c | 18 ++++++++++++------ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/chroot-bin/croutoncycle b/chroot-bin/croutoncycle index 18847ea99..d8b100e51 100755 --- a/chroot-bin/croutoncycle +++ b/chroot-bin/croutoncycle @@ -98,7 +98,7 @@ done freonowner='' if [ ! -f "/sys/class/tty/tty0/active" ]; then if [ -f "/tmp/crouton-lock/display" ]; then - read freonowner < "/tmp/crouton-lock/display" + read -r freonowner < "/tmp/crouton-lock/display" fi freonowner="${freonowner:-0}" winlist="aura*" diff --git a/host-bin/enter-chroot b/host-bin/enter-chroot index d16419ff1..da26b45a0 100755 --- a/host-bin/enter-chroot +++ b/host-bin/enter-chroot @@ -657,7 +657,7 @@ if [ ! "$NOLOGIN" = 1 ] && grep -q '^root:' "$passwd" 2>/dev/null; then chmod 622 "$CROUTONLOCKDIR/frecon" fi chrootcmd "(exec >/dev/null 2>&1 Date: Sat, 21 Feb 2015 01:01:53 -0800 Subject: [PATCH 017/377] Test xorg on K1 as well --- test/tests/35-xorg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tests/35-xorg b/test/tests/35-xorg index 33afbe7c0..3d52ace5a 100644 --- a/test/tests/35-xorg +++ b/test/tests/35-xorg @@ -5,8 +5,8 @@ # All supported releases should be able to launch an xorg server if [ -z "$release" ]; then - if uname -m | grep -q 'arm'; then - log "xorg is not available on ARM. Skipping test." + if grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo; then + log "xorg is not available on Samsung ARM. Skipping test." else echo "all" fi From 3d324109d5cbc4491a914c3e992e2f39bc9911a8 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sun, 22 Feb 2015 21:12:28 -0800 Subject: [PATCH 018/377] Need bsdmainutils for hexdump --- targets/x11-common | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/x11-common b/targets/x11-common index b05b4193f..aa3b4aed7 100644 --- a/targets/x11-common +++ b/targets/x11-common @@ -20,8 +20,8 @@ install --minimal dbus xdg-utils ln -sf croutonpowerd /usr/local/bin/gnome-screensaver-command ln -sf croutonpowerd /usr/local/bin/xscreensaver-command -# Install xbindkeys and xautomation for shortcuts; kbd for chvt -install --minimal xbindkeys xautomation kbd +# Install bsdmainutils, xbindkeys and xautomation for shortcuts; kbd for chvt +install --minimal bsdmainutils xbindkeys xautomation kbd # Allow users to run sudo chvt without password, so we don't need to run # croutoncycle as root echo '%sudo ALL = NOPASSWD:/bin/chvt' > /etc/sudoers.d/chvt From 0a03d84e908271553b79bc32b7678dd441b8a30d Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sun, 22 Feb 2015 21:36:05 -0800 Subject: [PATCH 019/377] Fix croutontriggerd on 32-bit systems --- chroot-bin/croutontriggerd | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/chroot-bin/croutontriggerd b/chroot-bin/croutontriggerd index 811f7092b..bdd424acd 100755 --- a/chroot-bin/croutontriggerd +++ b/chroot-bin/croutontriggerd @@ -8,6 +8,11 @@ . "`dirname "$0"`/../installer/functions" # hexdump output format variables +if getconf LONG_BIT | grep -q 32; then + HEXDUMP_FMT='2/4 "%u 0 " " " 2/2 "%u " " " 1/4 "%u " "\n"' +else + HEXDUMP_FMT='4/4 "%u " " " 2/2 "%u " " " 1/4 "%u " "\n"' +fi SECONDS_LO='$1' SECONDS_HI='$2' USECONDS_LO='$3' @@ -57,8 +62,7 @@ while :; do unset "$event" else # Read in the event files and split into input_event fields - stdbuf -oL hexdump -e '4/4 "%u " " " 2/2 "%u " " " 1/4 "%u " "\n"' \ - "$event" & + stdbuf -oL hexdump -e "$HEXDUMP_FMT" "$event" & eval "${event##*/}='$!'" fi done From 295d91f125a68de6523884cdd536a7e58a355155 Mon Sep 17 00:00:00 2001 From: DennisL Date: Mon, 23 Feb 2015 20:49:11 -0500 Subject: [PATCH 020/377] log invalid signatures Log 'Invalid signature...' output instead of throwing errors. --- src/fbserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fbserver.c b/src/fbserver.c index 8f5b4615b..cd0898af1 100644 --- a/src/fbserver.c +++ b/src/fbserver.c @@ -243,7 +243,7 @@ struct cache_entry* find_shm(uint64_t paddr, uint64_t sig, size_t length) { if (*((uint64_t*)entry->map) == sig) return entry; - error("Invalid signature, fetching new shm!"); + log(1, "Invalid signature, fetching new shm!"); close_mmap(entry); } From 230a1afa6b27d13f35764974822f27f3558a7438 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Feb 2015 18:12:35 -0800 Subject: [PATCH 021/377] Fix X11 backend selection --- targets/x11 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/x11 b/targets/x11 index da76368da..5951d67cb 100644 --- a/targets/x11 +++ b/targets/x11 @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. if grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo || \ - ([ "${ARCH#arm}" = "$ARCH" ] && \ + ([ "${ARCH#arm}" != "$ARCH" ] && \ awk -F= '/_RELEASE_VERSION=/ { exit int($2) < 6689 }' \ '/etc/lsb-release'); then # Xorg won't work on Samsung ARM devices or K1 on release less than 6689 From 1a7e5f815cfc329557ab806f003ff7868f519ad1 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Feb 2015 17:54:16 -0800 Subject: [PATCH 022/377] Prevent X11 from touching the vgem device, which is broken in stock Xorg Fixes #1443 for xorg. More needs to be done for xiwi. Why Xorg thought it was a good idea to probe devices regardless of settings (including ones that explicitly say not to probe) is beyond me. --- chroot-etc/xorg-dummy.conf | 1 + src/freon.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/chroot-etc/xorg-dummy.conf b/chroot-etc/xorg-dummy.conf index d3199324f..83faefc5b 100644 --- a/chroot-etc/xorg-dummy.conf +++ b/chroot-etc/xorg-dummy.conf @@ -33,6 +33,7 @@ EndSection Section "ServerFlags" Option "AutoAddDevices" "false" + Option "AutoAddGPU" "false" Option "DontVTSwitch" "true" Option "AllowMouseOpenFail" "true" Option "PciForceNone" "true" diff --git a/src/freon.c b/src/freon.c index f60a5897a..f985b8bf9 100644 --- a/src/freon.c +++ b/src/freon.c @@ -38,11 +38,13 @@ static int lockfd = -1; static int (*orig_ioctl)(int d, int request, void* data); static int (*orig_open)(const char *pathname, int flags, mode_t mode); static int (*orig_close)(int fd); +static int (*orig_udev_sysname)(void *udev_enumerate, const char *sysname); static void preload_init() { orig_ioctl = dlsym(RTLD_NEXT, "ioctl"); orig_open = dlsym(RTLD_NEXT, "open"); orig_close = dlsym(RTLD_NEXT, "close"); + orig_udev_sysname = dlsym(RTLD_NEXT, "udev_enumerate_add_match_sysname"); } /* Grabs the system-wide lockfile that arbitrates which chroot is using the GPU. @@ -190,3 +192,11 @@ int close(int fd) { } return orig_close(fd); } + +int udev_enumerate_add_match_sysname(void *udev_enum, const char *sysname) { + if (!orig_udev_sysname) preload_init(); + if (sysname && !strcmp(sysname, "card[0-9]*")) { + sysname = "card0"; + } + return orig_udev_sysname(udev_enum, sysname); +} From 24fa73b344ad99a58360d738875621b0d1d824fd Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Feb 2015 17:55:22 -0800 Subject: [PATCH 023/377] Use the display number in the log filename for freon. --- chroot-etc/xserverrc-xorg | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index 36acb66d6..4aeb99a7b 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -30,7 +30,14 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then fi # Freon necessitates the preload hack for X to coexist X=/usr/bin/Xorg - XARGS="-logfile /tmp/Xorg.$$.log $XARGS" + logfile="/tmp/Xorg.crouton.$$.log" + for arg in "$@"; do + disp="`echo "$arg" | sed -n 's/^\:\([0-9]*\)$/\1/p'`" + if [ -n "$disp" ]; then + logfile="/tmp/Xorg.crouton.$disp.log" + fi + done + XARGS="-logfile $logfile" export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" fi From b207e733b9672200a476fa987d43b9f5ff60df48 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Feb 2015 18:50:35 -0800 Subject: [PATCH 024/377] Use croutonfreon.so for xiwi too. Fixes #1443 and shouldn't have any ill side-effects. --- chroot-etc/xserverrc-xiwi | 5 +++++ targets/xiwi | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/chroot-etc/xserverrc-xiwi b/chroot-etc/xserverrc-xiwi index 5bdb64c17..fc3f4ca45 100644 --- a/chroot-etc/xserverrc-xiwi +++ b/chroot-etc/xserverrc-xiwi @@ -17,4 +17,9 @@ if [ -f /etc/crouton/xserverrc-local ]; then . /etc/crouton/xserverrc-local fi +# Handle Freon systems +if [ ! -f "/sys/class/tty/tty0/active" ]; then + export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" +fi + exec /usr/bin/Xorg $XARGS "$@" diff --git a/targets/xiwi b/targets/xiwi index ea250fa22..c9a1f5ab5 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -12,6 +12,11 @@ CHROOTETC='xbindkeysrc.scm xorg-dummy.conf xserverrc xserverrc-xiwi xserverrc-lo ### Append to prepare.sh: XMETHOD="${XMETHOD:-xiwi}" +# On Freon, we need crazy xorg hacks +if [ ! -f "/sys/class/tty/tty0/active" ]; then + compile freon '-ldl' so +fi + # Unhold xserver-xorg-video-dummy to make sure deps are pulled in if [ "${DISTROAKA:-"$DISTRO"}" = 'debian' ]; then apt-mark unhold xserver-xorg-video-dummy || true 2>/dev/null From 302d2ef11bf4c5e9c3c53e6ede688c3ac9e7da8e Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Feb 2015 19:20:44 -0800 Subject: [PATCH 025/377] Fix xorg+xiwi on precise. Fixes #1294 --- targets/xiwi | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/targets/xiwi b/targets/xiwi index c9a1f5ab5..d30dc815e 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -17,12 +17,22 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then compile freon '-ldl' so fi +ltspackages='' +# On non-ARM precise, install lts-trusty xorg server for compatibility with xorg +# if kernel version != 3.4 (lts-trusty mesa requires version >=3.6) +if [ "${ARCH#arm}" = "$ARCH" ] && release -eq precise \ + && ! uname -r | grep -q "^3.4."; then + # We still install xorg later to pull in its dependencies + ltspackages='-lts-trusty' + install --minimal "xserver-xorg$ltspackages" "libgl1-mesa-glx$ltspackages" +fi + # Unhold xserver-xorg-video-dummy to make sure deps are pulled in if [ "${DISTROAKA:-"$DISTRO"}" = 'debian' ]; then - apt-mark unhold xserver-xorg-video-dummy || true 2>/dev/null + apt-mark unhold xserver-xorg-video-dummy$ltspackages || true 2>/dev/null fi -install xorg xserver-xorg-video-dummy +install xorg xserver-xorg-video-dummy$ltspackages # Compile croutonfbserver compile fbserver '-lX11 -lXfixes -lXdamage -lXext -lXtst' \ @@ -45,7 +55,7 @@ echo "Download Xorg dummy driver..." 1>&2 wget -O "$DUMMYBUILDTMP/dummy.tar.gz" "$urlbase/xf86-video-dummy-0.3.7.tar.gz" install --minimal --asdeps patch gcc libc-dev pkg-config \ - xserver-xorg-dev x11proto-xf86dga-dev + xserver-xorg-dev$ltspackages x11proto-xf86dga-dev ( cd "$DUMMYBUILDTMP" @@ -388,7 +398,7 @@ EOF if [ "${DISTROAKA:-"$DISTRO"}" = 'debian' ]; then # Hold xserver-xorg-video-dummy to make sure the driver does not get erased - apt-mark hold xserver-xorg-video-dummy + apt-mark hold xserver-xorg-video-dummy$ltspackages fi TIPS="$TIPS"' From 841ff620ccd45ff57c7ca723007874d14fdc8930 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Feb 2015 19:46:56 -0800 Subject: [PATCH 026/377] Install dmz-cursor-theme in x11-common --- targets/x11-common | 3 +++ targets/xephyr | 2 +- targets/xorg | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/targets/x11-common b/targets/x11-common index aa3b4aed7..3e625faf5 100644 --- a/targets/x11-common +++ b/targets/x11-common @@ -20,6 +20,9 @@ install --minimal dbus xdg-utils ln -sf croutonpowerd /usr/local/bin/gnome-screensaver-command ln -sf croutonpowerd /usr/local/bin/xscreensaver-command +# Install nicer cursors +install --minimal dmz-cursor-theme + # Install bsdmainutils, xbindkeys and xautomation for shortcuts; kbd for chvt install --minimal bsdmainutils xbindkeys xautomation kbd # Allow users to run sudo chvt without password, so we don't need to run diff --git a/targets/xephyr b/targets/xephyr index 3fbfbf87b..aaaa0c5d4 100644 --- a/targets/xephyr +++ b/targets/xephyr @@ -32,7 +32,7 @@ fi # xserver-xephyr won't auto replace the manually-downloaded version. install --minimal \ - xserver-xephyr xinit dmz-cursor-theme libgl1-mesa-dri \ + xserver-xephyr xinit libgl1-mesa-dri \ x11-utils x11-xserver-utils xinput xterm # Compile croutoncursor diff --git a/targets/xorg b/targets/xorg index d9d169b95..7df83c6e9 100644 --- a/targets/xorg +++ b/targets/xorg @@ -104,7 +104,7 @@ END apt-get -y --force-yes --no-install-recommends dist-upgrade -f fi -install xorg dmz-cursor-theme xserver-xorg-video-fbdev$ltspackages +install xorg xserver-xorg-video-fbdev$ltspackages if [ "${ARCH#arm}" = "$ARCH" ]; then install xserver-xorg-video-intel$ltspackages fi From 2331c99d1b420281fcc8705785e3ca8a837023ef Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 27 Feb 2015 14:27:43 -0800 Subject: [PATCH 027/377] Move vgem workaround to its own .so and use on all platforms Fixes #1450 --- Makefile | 3 +++ chroot-etc/xserverrc-xiwi | 2 ++ chroot-etc/xserverrc-xorg | 2 ++ src/freon.c | 10 ---------- src/xorg.c | 28 ++++++++++++++++++++++++++++ targets/xiwi | 3 +++ targets/xorg | 3 +++ 7 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 src/xorg.c diff --git a/Makefile b/Makefile index 65e954941..db13ce369 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,9 @@ $(SRCTARGETS): src/$(patsubst crouton%,src/%.c,$@) $($@_DEPS) Makefile croutonfreon.so: src/freon.c Makefile gcc $(CFLAGS) -shared -fPIC src/freon.c -ldl -o croutonfreon.so +croutonxorg.so: src/xorg.c Makefile + gcc $(CFLAGS) -shared -fPIC src/xorg.c -ldl -o croutonxorg.so + extension: $(EXTTARGET) $(CONTRIBUTORS): $(GITHEAD) $(CONTRIBUTORSSED) diff --git a/chroot-etc/xserverrc-xiwi b/chroot-etc/xserverrc-xiwi index fc3f4ca45..90b8645c5 100644 --- a/chroot-etc/xserverrc-xiwi +++ b/chroot-etc/xserverrc-xiwi @@ -22,4 +22,6 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" fi +export LD_PRELOAD="/usr/local/lib/croutonxorg.so:$LD_PRELOAD" + exec /usr/bin/Xorg $XARGS "$@" diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index 4aeb99a7b..d2e2c4e00 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -41,4 +41,6 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" fi +export LD_PRELOAD="/usr/local/lib/croutonxorg.so:$LD_PRELOAD" + exec "$X" $XARGS "$@" diff --git a/src/freon.c b/src/freon.c index f985b8bf9..f60a5897a 100644 --- a/src/freon.c +++ b/src/freon.c @@ -38,13 +38,11 @@ static int lockfd = -1; static int (*orig_ioctl)(int d, int request, void* data); static int (*orig_open)(const char *pathname, int flags, mode_t mode); static int (*orig_close)(int fd); -static int (*orig_udev_sysname)(void *udev_enumerate, const char *sysname); static void preload_init() { orig_ioctl = dlsym(RTLD_NEXT, "ioctl"); orig_open = dlsym(RTLD_NEXT, "open"); orig_close = dlsym(RTLD_NEXT, "close"); - orig_udev_sysname = dlsym(RTLD_NEXT, "udev_enumerate_add_match_sysname"); } /* Grabs the system-wide lockfile that arbitrates which chroot is using the GPU. @@ -192,11 +190,3 @@ int close(int fd) { } return orig_close(fd); } - -int udev_enumerate_add_match_sysname(void *udev_enum, const char *sysname) { - if (!orig_udev_sysname) preload_init(); - if (sysname && !strcmp(sysname, "card[0-9]*")) { - sysname = "card0"; - } - return orig_udev_sysname(udev_enum, sysname); -} diff --git a/src/xorg.c b/src/xorg.c new file mode 100644 index 000000000..ab4b12793 --- /dev/null +++ b/src/xorg.c @@ -0,0 +1,28 @@ +/* Copyright (c) 2015 The crouton Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * LD_PRELOAD hack to make Xorg happy in a system with the vgem device enabled. + * gcc -shared -fPIC -ldl -Wall -O2 xorg.c -o croutonxorg.so + */ + +#define _GNU_SOURCE +#include +#include + +#define TRACE(...) /* fprintf(stderr, __VA_ARGS__) */ + +static int (*orig_udev_sysname)(void *udev_enumerate, const char *sysname); + +static void preload_init() { + orig_udev_sysname = dlsym(RTLD_NEXT, "udev_enumerate_add_match_sysname"); +} + +int udev_enumerate_add_match_sysname(void *udev_enum, const char *sysname) { + if (!orig_udev_sysname) preload_init(); + TRACE("udev_enumerate_add_match_sysname '%s'\n", sysname); + if (sysname && !strcmp(sysname, "card[0-9]*")) { + sysname = "card0"; + } + return orig_udev_sysname(udev_enum, sysname); +} diff --git a/targets/xiwi b/targets/xiwi index d30dc815e..e9d2acd42 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -17,6 +17,9 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then compile freon '-ldl' so fi +# We need xorg workarounds on all platforms +compile xorg '-ldl' so + ltspackages='' # On non-ARM precise, install lts-trusty xorg server for compatibility with xorg # if kernel version != 3.4 (lts-trusty mesa requires version >=3.6) diff --git a/targets/xorg b/targets/xorg index 7df83c6e9..371565b52 100644 --- a/targets/xorg +++ b/targets/xorg @@ -25,6 +25,9 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then compile freon '-ldl' so fi +# We need xorg workarounds on all platforms +compile xorg '-ldl' so + ltspackages='' # On non-ARM precise, install lts-trusty xorg server to support newer hardware # if kernel version != 3.4 (lts-trusty mesa requires version >=3.6) From 3811e6a59d9f7ff387b2d4ab1c5357d646cea49b Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sat, 28 Feb 2015 22:21:50 -0800 Subject: [PATCH 028/377] Fix edit-chroot move filesystem check. Fixes 1441 --- host-bin/edit-chroot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host-bin/edit-chroot b/host-bin/edit-chroot index 86fbf99ac..dbeebdc55 100755 --- a/host-bin/edit-chroot +++ b/host-bin/edit-chroot @@ -163,7 +163,7 @@ elif [ $# -gt 1 -a -f "$TARBALL" ]; then fi # Don't allow moving to non-ext filesystems (but don't check if just renaming) -if [ -n "$MOVE" -a "${MOVE#*/}" = "$MOVE" ] && \ +if [ -n "$MOVE" -a "${MOVE#*/}" != "$MOVE" ] && \ df -T "`getmountpoint "$MOVE"`" | awk '$2~"^ext"{exit 1}'; then error 2 "Chroots can only be moved to ext filesystems." fi From 942fcc6cd30a3d82e7ca9f4a46c1da759c8f7811 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sat, 28 Feb 2015 22:42:07 -0800 Subject: [PATCH 029/377] Print out all of the pids stopping unmount-chroot, not just one --- host-bin/unmount-chroot | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/host-bin/unmount-chroot b/host-bin/unmount-chroot index 424e48e3e..b2fc4dd1a 100755 --- a/host-bin/unmount-chroot +++ b/host-bin/unmount-chroot @@ -86,7 +86,7 @@ checkusage() { if [ -n "$FORCE" ]; then return 0 fi - local b="${1%/}/" pid ppid proot prootdir root rootdir + local b="${1%/}/" pid ppid proot prootdir root rootdir pids='' for root in /proc/*/root; do if [ ! -r "$root" ]; then continue @@ -110,10 +110,15 @@ checkusage() { fi fi if [ -n "$PRINT" ]; then - ps -p "$pid" -o pid= -o cmd= || true + pids="$pids $pid" + continue fi return 1 done + if [ -n "$PRINT" -a -n "$pids" ]; then + ps -p "${pids# }" -o pid= -o cmd= || true + return 1 + fi return 0 } From f551e0a6f99db551729823de57e038b6c286e41d Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sat, 28 Feb 2015 23:08:53 -0800 Subject: [PATCH 030/377] Ignore processes that session_manager has inherited. Fixes #1456 --- host-bin/unmount-chroot | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/host-bin/unmount-chroot b/host-bin/unmount-chroot index b2fc4dd1a..c123592c8 100755 --- a/host-bin/unmount-chroot +++ b/host-bin/unmount-chroot @@ -78,8 +78,8 @@ fi # appropriate commands by checking if the command's parent root is not equal # to the pid's root. This avoids not unmounting due to a lazy-quitting # background application within the chroot. We also don't consider processes -# that have a parent PID of 1 (which would mean an orphaned process in this -# case), as enter-chroot never orphans its children. +# that have a parent PID of 1 or that of session_manager's (which would mean an +# orphaned process in this case), as enter-chroot never orphans its children. # $1: $base; the canonicalized base path of the chroot # Returns: non-zero if the chroot is in use. checkusage() { @@ -87,6 +87,7 @@ checkusage() { return 0 fi local b="${1%/}/" pid ppid proot prootdir root rootdir pids='' + local smgrpid="`pgrep -o -u 0 -x session_manager || echo 1`" for root in /proc/*/root; do if [ ! -r "$root" ]; then continue @@ -99,7 +100,7 @@ checkusage() { pid="${root#/proc/}" pid="${pid%/root}" ppid="`ps -p "$pid" -o ppid= 2>/dev/null | sed 's/ //g'`" - if [ -z "$ppid" ] || [ "$ppid" -eq 1 ]; then + if [ -z "$ppid" ] || [ "$ppid" -eq 1 -o "$ppid" -eq "$smgrpid" ]; then continue fi proot="/proc/$ppid/root" From 500c8825717008712ded2276c995c7c95af85469 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 25 Nov 2014 17:50:25 -0800 Subject: [PATCH 031/377] Initial hack of a "xiwi" application that runs an app in its own cros window --- chroot-bin/xiwi | 24 ++++++++++++++++++++++++ targets/xiwi | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100755 chroot-bin/xiwi diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi new file mode 100755 index 000000000..97509ea9d --- /dev/null +++ b/chroot-bin/xiwi @@ -0,0 +1,24 @@ +#!/bin/sh -e +# Copyright (c) 2014 The crouton Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Runs the specified X11 application in its own X server in Chromium OS. + +if [ "$#" = 0 ]; then + echo "Usage: $0 cmd params" 1>&2 + exit 2 +elif [ "$1" = '/' ]; then + shift 1 + "$@" & + exec /usr/bin/ratpoison -f /dev/stdin </dev/null fi -install xorg xserver-xorg-video-dummy$ltspackages +install xorg xserver-xorg-video-dummy$ltspackages ratpoison # Compile croutonfbserver compile fbserver '-lX11 -lXfixes -lXdamage -lXext -lXtst' \ From b794af1214eaa03256a4e168721d862798291c5a Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 08:43:14 -0800 Subject: [PATCH 032/377] It's a window, not a tab. --- chroot-bin/croutonxinitrc-wrapper | 2 +- host-ext/crouton/background.js | 4 ++-- host-ext/crouton/window.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/chroot-bin/croutonxinitrc-wrapper b/chroot-bin/croutonxinitrc-wrapper index 88cc4c1c6..6cdcc4193 100755 --- a/chroot-bin/croutonxinitrc-wrapper +++ b/chroot-bin/croutonxinitrc-wrapper @@ -146,7 +146,7 @@ and enabled, and up to date. (download from http://goo.gl/OVQOEt)" 1>&2 try="$((try+1))" done if [ "$ret" -eq 0 ]; then - echo "Connected to extension, launched crouton in a tab window." 1>&2 + echo "Connected to extension, launched crouton in a window." 1>&2 fi fi diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index 126ad72fe..010649179 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -486,7 +486,7 @@ function websocketMessage(evt) { } refreshUI(); break; - case 'X': /* Ask to open a crouton-in-a-tab window */ + case 'X': /* Ask to open a crouton window */ display = payload match = display.match(/^:([0-9]+)$/) displaynum = match ? match[1] : null @@ -530,7 +530,7 @@ function websocketMessage(evt) { kiwi_win_[display].window = null; win = windows_.filter(function(x){ return x.display == display })[0] - name = win ? win.name : "crouton in a tab"; + name = win ? win.name : "crouton in a window"; chrome.windows.create({ 'url': "window.html?display=" + displaynum + "&debug=" + (debug_ ? 1 : 0) + diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index d97790ad9..8489b5f93 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -16,7 +16,7 @@ var errordiv_ = null; /* error div */ var debug_ = 0; /* Debuging level, passed to NaCl module */ var hidpi_ = 0; /* HiDPI mode */ var display_ = null; /* Display number to use */ -var title_ = "crouton in a tab"; /* window title */ +var title_ = "crouton in a window"; /* window title */ var connected_ = false; var closing_ = false; /* Disconnected, and waiting for the window to close */ var error_ = false; /* An error has occured */ @@ -95,7 +95,7 @@ function setHiDPI(hidpi) { } function setTitle(title) { - document.title = "crouton in a tab: " + title + " (" + display_ + ")"; + document.title = "crouton (" + display_ + "): " + title; } /* Set status message */ From 10128f2fbf23b360c7ed1eb8a63146db9abf2a62 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 09:52:37 -0800 Subject: [PATCH 033/377] Generate kiwi window title based off of active window --- chroot-bin/xiwi | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 97509ea9d..32ff2203e 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -10,14 +10,20 @@ if [ "$#" = 0 ]; then exit 2 elif [ "$1" = '/' ]; then shift 1 + genwindowname="`cat /etc/crouton/name`/$1: \`\ + ratpoison -c 'windows %s%t' | sed -n '/^\*/s/^.//p'\`" "$@" & exec /usr/bin/ratpoison -f /dev/stdin < Date: Tue, 17 Feb 2015 14:31:47 -0800 Subject: [PATCH 034/377] extension: Always send confirmation when receiving a windowlist Old websockets will harmlessly print out the croutoncycle usage message. New websockets can push windowlist updates and get an OK. --- host-ext/crouton/background.js | 3 +++ src/websocket.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index 010649179..16263d777 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -483,6 +483,9 @@ function websocketMessage(evt) { kiwi_win_[k.display].window.setTitle(k.name); } }) + + lastwindowlistupdate_ = new Date().getTime(); + websocket_.send("COK"); } refreshUI(); break; diff --git a/src/websocket.c b/src/websocket.c index a113313d3..7ff241b40 100644 --- a/src/websocket.c +++ b/src/websocket.c @@ -378,6 +378,9 @@ static int socket_client_handle_unrequested(const char* buffer, return -1; } replylength += n; + } else if (param[0] == 'O') { + /* Extra OK response from a C back-and-forth. Disregard. */ + break; } else { /* Launch command in background (this is necessary as croutoncycle may send a websocket command, leaving us From 232e557ec7622c3b3cdeb52646540af58fc029d7 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 14:34:00 -0800 Subject: [PATCH 035/377] Push windowlist updates on window switch TODO: Need to push updates on titlebar changes too. --- chroot-bin/xiwi | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 32ff2203e..39b5ef996 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -5,26 +5,35 @@ # Runs the specified X11 application in its own X server in Chromium OS. +. "`dirname "$0"`/../installer/functions" + if [ "$#" = 0 ]; then echo "Usage: $0 cmd params" 1>&2 exit 2 elif [ "$1" = '/' ]; then shift 1 - genwindowname="`cat /etc/crouton/name`/$1: \`\ - ratpoison -c 'windows %s%t' | sed -n '/^\*/s/^.//p'\`" "$@" & - exec /usr/bin/ratpoison -f /dev/stdin < Date: Tue, 17 Feb 2015 15:27:44 -0800 Subject: [PATCH 036/377] Update xiwi on title change --- chroot-bin/xiwi | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 39b5ef996..4e378d8a6 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -6,6 +6,7 @@ # Runs the specified X11 application in its own X server in Chromium OS. . "`dirname "$0"`/../installer/functions" +xiwicmd="`readlink -f "$0"`" if [ "$#" = 0 ]; then echo "Usage: $0 cmd params" 1>&2 @@ -13,8 +14,7 @@ if [ "$#" = 0 ]; then elif [ "$1" = '/' ]; then shift 1 "$@" & - xiwicmd="`readlink -f "$0"`" - exec ratpoison -f /dev/stdin </dev/null </dev/null \ + | while read _; do + "$xiwicmd" // "$2" + done + } 3>> "/tmp/crouton-lock/xiwi-$DISPLAY-$id" & else export XMETHOD=xiwi exec /usr/local/bin/xinit "`readlink -f "$0"`" / "$@" From ab9d15d3ea7d5dac3b107be75e1810f7db041c74 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 15:30:35 -0800 Subject: [PATCH 037/377] Improve app close responsiveness/correctness. --- chroot-bin/xiwi | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 4e378d8a6..e559bd25d 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -13,17 +13,14 @@ if [ "$#" = 0 ]; then exit 2 elif [ "$1" = '/' ]; then shift 1 - "$@" & - exec ratpoison -f /dev/stdin >/dev/null </dev/null <> "/tmp/crouton-lock/xiwi-$DISPLAY-$id" & else export XMETHOD=xiwi - exec /usr/local/bin/xinit "`readlink -f "$0"`" / "$@" + exec /usr/local/bin/xinit "$xiwicmd" / "$@" fi From 4c3b82a3ad5044db8ffcc1e92dcefaaebb69c974 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 17:41:55 -0800 Subject: [PATCH 038/377] Set the root cursor --- chroot-bin/xiwi | 1 + 1 file changed, 1 insertion(+) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index e559bd25d..2f379665f 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -13,6 +13,7 @@ if [ "$#" = 0 ]; then exit 2 elif [ "$1" = '/' ]; then shift 1 + xsetroot -cursor_name left_ptr ratpoison -f /dev/stdin >/dev/null < Date: Tue, 17 Feb 2015 16:32:38 -0800 Subject: [PATCH 039/377] Prevent crouton from segfaulting on bad cursors. Not sure when this happens, so just adding logging code for now. --- src/fbserver.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fbserver.c b/src/fbserver.c index cd0898af1..62ee7c791 100644 --- a/src/fbserver.c +++ b/src/fbserver.c @@ -438,6 +438,10 @@ int write_image(const struct screen* screen) { /* Writes cursor image to websocket */ int write_cursor() { XFixesCursorImage *img = XFixesGetCursorImage(dpy); + if (!img) { + error("XFixesGetCursorImage returned NULL"); + return -1; + } int size = img->width*img->height; const int replylength = sizeof(struct cursor_reply) + size*sizeof(uint32_t); char reply_raw[FRAMEMAXHEADERSIZE + replylength]; From e325260732436b98282a545dab29639e7267d4b3 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 17:38:30 -0800 Subject: [PATCH 040/377] kiwi: fall back on the default cursor when data is unavailable --- host-ext/nacl_src/kiwi.cc | 34 +++++++++++++++++++++++----------- src/fbserver.c | 29 +++++++++++++++-------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/host-ext/nacl_src/kiwi.cc b/host-ext/nacl_src/kiwi.cc index 7df041122..dc41fb409 100644 --- a/host-ext/nacl_src/kiwi.cc +++ b/host-ext/nacl_src/kiwi.cc @@ -211,6 +211,7 @@ class KiwiInstance : public pp::Instance { } cursor_cache_.clear(); + last_cursor_request_ = 0; SocketReceive(); @@ -311,11 +312,14 @@ class KiwiInstance : public pp::Instance { if (it == cursor_cache_.end()) { /* No cache entry, ask for data. */ SocketSend(pp::Var("P"), false); + last_cursor_request_ = reply->cursor_serial; } else { LogMessage(2) << "Cursor use cache for " << reply->cursor_serial; - pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM, - it->second.img, it->second.hot); + pp::MouseCursor::SetCursor(this, + it->second.img.is_null() ? PP_MOUSECURSOR_TYPE_POINTER + : PP_MOUSECURSOR_TYPE_CUSTOM, + it->second.img, it->second.hot); } } return true; @@ -348,21 +352,28 @@ class KiwiInstance : public pp::Instance { int w = cursor->width/scale; int h = cursor->height/scale; - pp::ImageData img(this, pp::ImageData::GetNativeImageDataFormat(), - pp::Size(w, h), true); - uint32_t* imgdata = (uint32_t*)img.data(); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - /* Nearest neighbour is least ugly */ - imgdata[y*w + x] = cursor->pixels[scale*y*scale*w + scale*x]; + pp::ImageData img; + if (cursor->cursor_serial) { + img = pp::ImageData(this, pp::ImageData::GetNativeImageDataFormat(), + pp::Size(w, h), true); + uint32_t* imgdata = (uint32_t*)img.data(); + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + /* Nearest neighbour is least ugly */ + imgdata[y*w + x] = cursor->pixels[scale*y*scale*w + scale*x]; + } } + } else { + cursor->cursor_serial = last_cursor_request_; } pp::Point hot(cursor->xhot/scale, cursor->yhot/scale); cursor_cache_[cursor->cursor_serial].img = img; cursor_cache_[cursor->cursor_serial].hot = hot; - pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM, - img, hot); + pp::MouseCursor::SetCursor(this, + img.is_null() ? PP_MOUSECURSOR_TYPE_POINTER + : PP_MOUSECURSOR_TYPE_CUSTOM, + img, hot); return true; } @@ -1088,6 +1099,7 @@ class KiwiInstance : public pp::Instance { pp::Point hot; }; std::unordered_map cursor_cache_; + uint32_t last_cursor_request_; /* Display to connect to */ int display_ = -1; diff --git a/src/fbserver.c b/src/fbserver.c index 62ee7c791..86fe0fd19 100644 --- a/src/fbserver.c +++ b/src/fbserver.c @@ -438,11 +438,10 @@ int write_image(const struct screen* screen) { /* Writes cursor image to websocket */ int write_cursor() { XFixesCursorImage *img = XFixesGetCursorImage(dpy); - if (!img) { - error("XFixesGetCursorImage returned NULL"); - return -1; + int size = 0; + if (img) { + size = img->width*img->height; } - int size = img->width*img->height; const int replylength = sizeof(struct cursor_reply) + size*sizeof(uint32_t); char reply_raw[FRAMEMAXHEADERSIZE + replylength]; struct cursor_reply* reply = @@ -451,18 +450,20 @@ int write_cursor() { memset(reply_raw, 0, sizeof(*reply_raw)); reply->type = 'P'; - reply->width = img->width; - reply->height = img->height; - reply->xhot = img->xhot; - reply->yhot = img->yhot; - reply->cursor_serial = img->cursor_serial; - /* This casts long[] to uint32_t[] */ - int i; - for (i = 0; i < size; i++) - reply->pixels[i] = img->pixels[i]; + if (img) { + reply->width = img->width; + reply->height = img->height; + reply->xhot = img->xhot; + reply->yhot = img->yhot; + reply->cursor_serial = img->cursor_serial; + /* This casts long[] to uint32_t[] */ + int i; + for (i = 0; i < size; i++) + reply->pixels[i] = img->pixels[i]; + XFree(img); + } socket_client_write_frame(reply_raw, replylength, WS_OPCODE_BINARY, 1); - XFree(img); return 0; } From 4483c655d66fbf6c69c2bfe643c6b6dfada93d3e Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 17:48:34 -0800 Subject: [PATCH 041/377] Revert "kiwi: fall back on the default cursor when data is unavailable" This reverts commit e325260732436b98282a545dab29639e7267d4b3. It doesn't appear to be necessary, but keeping the code here for reference. --- host-ext/nacl_src/kiwi.cc | 34 +++++++++++----------------------- src/fbserver.c | 29 ++++++++++++++--------------- 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/host-ext/nacl_src/kiwi.cc b/host-ext/nacl_src/kiwi.cc index dc41fb409..7df041122 100644 --- a/host-ext/nacl_src/kiwi.cc +++ b/host-ext/nacl_src/kiwi.cc @@ -211,7 +211,6 @@ class KiwiInstance : public pp::Instance { } cursor_cache_.clear(); - last_cursor_request_ = 0; SocketReceive(); @@ -312,14 +311,11 @@ class KiwiInstance : public pp::Instance { if (it == cursor_cache_.end()) { /* No cache entry, ask for data. */ SocketSend(pp::Var("P"), false); - last_cursor_request_ = reply->cursor_serial; } else { LogMessage(2) << "Cursor use cache for " << reply->cursor_serial; - pp::MouseCursor::SetCursor(this, - it->second.img.is_null() ? PP_MOUSECURSOR_TYPE_POINTER - : PP_MOUSECURSOR_TYPE_CUSTOM, - it->second.img, it->second.hot); + pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM, + it->second.img, it->second.hot); } } return true; @@ -352,28 +348,21 @@ class KiwiInstance : public pp::Instance { int w = cursor->width/scale; int h = cursor->height/scale; - pp::ImageData img; - if (cursor->cursor_serial) { - img = pp::ImageData(this, pp::ImageData::GetNativeImageDataFormat(), - pp::Size(w, h), true); - uint32_t* imgdata = (uint32_t*)img.data(); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - /* Nearest neighbour is least ugly */ - imgdata[y*w + x] = cursor->pixels[scale*y*scale*w + scale*x]; - } + pp::ImageData img(this, pp::ImageData::GetNativeImageDataFormat(), + pp::Size(w, h), true); + uint32_t* imgdata = (uint32_t*)img.data(); + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + /* Nearest neighbour is least ugly */ + imgdata[y*w + x] = cursor->pixels[scale*y*scale*w + scale*x]; } - } else { - cursor->cursor_serial = last_cursor_request_; } pp::Point hot(cursor->xhot/scale, cursor->yhot/scale); cursor_cache_[cursor->cursor_serial].img = img; cursor_cache_[cursor->cursor_serial].hot = hot; - pp::MouseCursor::SetCursor(this, - img.is_null() ? PP_MOUSECURSOR_TYPE_POINTER - : PP_MOUSECURSOR_TYPE_CUSTOM, - img, hot); + pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM, + img, hot); return true; } @@ -1099,7 +1088,6 @@ class KiwiInstance : public pp::Instance { pp::Point hot; }; std::unordered_map cursor_cache_; - uint32_t last_cursor_request_; /* Display to connect to */ int display_ = -1; diff --git a/src/fbserver.c b/src/fbserver.c index 86fe0fd19..62ee7c791 100644 --- a/src/fbserver.c +++ b/src/fbserver.c @@ -438,10 +438,11 @@ int write_image(const struct screen* screen) { /* Writes cursor image to websocket */ int write_cursor() { XFixesCursorImage *img = XFixesGetCursorImage(dpy); - int size = 0; - if (img) { - size = img->width*img->height; + if (!img) { + error("XFixesGetCursorImage returned NULL"); + return -1; } + int size = img->width*img->height; const int replylength = sizeof(struct cursor_reply) + size*sizeof(uint32_t); char reply_raw[FRAMEMAXHEADERSIZE + replylength]; struct cursor_reply* reply = @@ -450,20 +451,18 @@ int write_cursor() { memset(reply_raw, 0, sizeof(*reply_raw)); reply->type = 'P'; - if (img) { - reply->width = img->width; - reply->height = img->height; - reply->xhot = img->xhot; - reply->yhot = img->yhot; - reply->cursor_serial = img->cursor_serial; - /* This casts long[] to uint32_t[] */ - int i; - for (i = 0; i < size; i++) - reply->pixels[i] = img->pixels[i]; - XFree(img); - } + reply->width = img->width; + reply->height = img->height; + reply->xhot = img->xhot; + reply->yhot = img->yhot; + reply->cursor_serial = img->cursor_serial; + /* This casts long[] to uint32_t[] */ + int i; + for (i = 0; i < size; i++) + reply->pixels[i] = img->pixels[i]; socket_client_write_frame(reply_raw, replylength, WS_OPCODE_BINARY, 1); + XFree(img); return 0; } From 77df2b3fad7394011cd4134fd4ce78f9a5b51b0f Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 17 Feb 2015 18:30:05 -0800 Subject: [PATCH 042/377] Add nicer help and tip text for the xiwi command. --- chroot-bin/xiwi | 3 ++- targets/xiwi | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 2f379665f..e6ca7c207 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -9,7 +9,8 @@ xiwicmd="`readlink -f "$0"`" if [ "$#" = 0 ]; then - echo "Usage: $0 cmd params" 1>&2 + echo "Usage: ${0##*/} application [parameters ...] +Launches a windowed session in Chromium OS for any graphical application." 1>&2 exit 2 elif [ "$1" = '/' ]; then shift 1 diff --git a/targets/xiwi b/targets/xiwi index f2ad945e3..c84a72477 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -408,6 +408,11 @@ TIPS="$TIPS"' You can open your running chroot desktops by clicking on the extension icon. Once in a crouton window, press fullscreen or the "switch window" key to switch back to Chromium OS. + +You can launch individual apps in crouton windows by using the "xiwi" command +in the chroot shell. Wrap that command with enter-chroot to launch directly +from the host shell. Use the enter-chroot parameter -b to run in the background. +Example: sudo enter-chroot -b xiwi xterm ' ### append x11-common From f041008b26371e72dd5fc85421ebff0186b520ab Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 20 Feb 2015 18:16:49 -0800 Subject: [PATCH 043/377] Add in-app window cycling shortcuts. Ctrl+Alt+Tab = next window Ctrl+Alt+Shift+Tab = previous window Ctrl+Alt+Shift+Escape+Escape = close window --- chroot-bin/xiwi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index e6ca7c207..ead99d946 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -17,8 +17,12 @@ elif [ "$1" = '/' ]; then xsetroot -cursor_name left_ptr ratpoison -f /dev/stdin >/dev/null < Date: Sun, 22 Feb 2015 01:08:32 -0800 Subject: [PATCH 044/377] Bump extension version and remove unneeded tabs permission. --- host-ext/crouton/manifest.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/host-ext/crouton/manifest.json b/host-ext/crouton/manifest.json index 300874770..4a560c928 100644 --- a/host-ext/crouton/manifest.json +++ b/host-ext/crouton/manifest.json @@ -4,7 +4,7 @@ "name": "crouton integration", "short_name": "crouton", "description": "Improves integration with crouton chroots.", - "version": "2.2.0", + "version": "2.3.0", "icons": { "48": "icon-48.png", "128": "icon-128.png" @@ -25,7 +25,6 @@ "permissions": [ "clipboardRead", "clipboardWrite", - "notifications", - "tabs" + "notifications" ] } From a3ec7c31d0dc70e1b2b6610c90bdca2048935c9b Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sun, 22 Feb 2015 21:10:02 -0800 Subject: [PATCH 045/377] Handle commands like "xiwi startxfce4" correctly. It's just a heuristic though. The "xiwi" command isn't really intended for launching DEs. --- chroot-bin/xiwi | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index ead99d946..c6566d95c 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -9,23 +9,32 @@ xiwicmd="`readlink -f "$0"`" if [ "$#" = 0 ]; then - echo "Usage: ${0##*/} application [parameters ...] -Launches a windowed session in Chromium OS for any graphical application." 1>&2 + echo "Usage: ${0##*/} APPLICATION [PARAMETERS ...] +Launches a windowed session in Chromium OS for any graphical application. +All parameters are passed to the specified application. + +A default window manager will full-screen all windows, unless APPLICATION begins +with 'start'. You can cycle through multiple windows inside the application via +Ctrl-Alt-Tab/Ctrl-Alt-Shift-Tab, or close them via Ctrl-Alt-Shift-Escape-Escape. +If APPLICATION begins with 'start' but you still want to use the default window +manager, specify the full path of the application." 1>&2 exit 2 elif [ "$1" = '/' ]; then shift 1 xsetroot -cursor_name left_ptr - ratpoison -f /dev/stdin >/dev/null </dev/null < Date: Sun, 1 Mar 2015 13:29:06 -0800 Subject: [PATCH 046/377] Xiwi doesn't need croutonfreon.so anymore --- chroot-etc/xserverrc-xiwi | 6 +----- targets/xiwi | 5 ----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/chroot-etc/xserverrc-xiwi b/chroot-etc/xserverrc-xiwi index 90b8645c5..e8c1950ab 100644 --- a/chroot-etc/xserverrc-xiwi +++ b/chroot-etc/xserverrc-xiwi @@ -17,11 +17,7 @@ if [ -f /etc/crouton/xserverrc-local ]; then . /etc/crouton/xserverrc-local fi -# Handle Freon systems -if [ ! -f "/sys/class/tty/tty0/active" ]; then - export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" -fi - +# Xorg compatibility hacks export LD_PRELOAD="/usr/local/lib/croutonxorg.so:$LD_PRELOAD" exec /usr/bin/Xorg $XARGS "$@" diff --git a/targets/xiwi b/targets/xiwi index c84a72477..b7ea11de1 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -12,11 +12,6 @@ CHROOTETC='xbindkeysrc.scm xorg-dummy.conf xserverrc xserverrc-xiwi xserverrc-lo ### Append to prepare.sh: XMETHOD="${XMETHOD:-xiwi}" -# On Freon, we need crazy xorg hacks -if [ ! -f "/sys/class/tty/tty0/active" ]; then - compile freon '-ldl' so -fi - # We need xorg workarounds on all platforms compile xorg '-ldl' so From 550afdb32c048403844dc4ef8cd74e917ff9ee85 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 4 Mar 2015 14:54:26 -0800 Subject: [PATCH 047/377] Patch Xorg to avoid udev probing. A terrible, terrible hack that definitely hopefully maybe fixes #1450 finally. Remove the other hack that didn't completely fix the issue. So I guess that's net zero hacks for this commit, which is nice. --- chroot-etc/xserverrc-xiwi | 3 --- chroot-etc/xserverrc-xorg | 2 -- src/xorg.c | 28 ---------------------------- targets/x11-common | 7 +++++++ targets/xiwi | 3 --- targets/xorg | 3 --- 6 files changed, 7 insertions(+), 39 deletions(-) delete mode 100644 src/xorg.c diff --git a/chroot-etc/xserverrc-xiwi b/chroot-etc/xserverrc-xiwi index e8c1950ab..5bdb64c17 100644 --- a/chroot-etc/xserverrc-xiwi +++ b/chroot-etc/xserverrc-xiwi @@ -17,7 +17,4 @@ if [ -f /etc/crouton/xserverrc-local ]; then . /etc/crouton/xserverrc-local fi -# Xorg compatibility hacks -export LD_PRELOAD="/usr/local/lib/croutonxorg.so:$LD_PRELOAD" - exec /usr/bin/Xorg $XARGS "$@" diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index d2e2c4e00..4aeb99a7b 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -41,6 +41,4 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then export LD_PRELOAD="/usr/local/lib/croutonfreon.so:$LD_PRELOAD" fi -export LD_PRELOAD="/usr/local/lib/croutonxorg.so:$LD_PRELOAD" - exec "$X" $XARGS "$@" diff --git a/src/xorg.c b/src/xorg.c deleted file mode 100644 index ab4b12793..000000000 --- a/src/xorg.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2015 The crouton Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * LD_PRELOAD hack to make Xorg happy in a system with the vgem device enabled. - * gcc -shared -fPIC -ldl -Wall -O2 xorg.c -o croutonxorg.so - */ - -#define _GNU_SOURCE -#include -#include - -#define TRACE(...) /* fprintf(stderr, __VA_ARGS__) */ - -static int (*orig_udev_sysname)(void *udev_enumerate, const char *sysname); - -static void preload_init() { - orig_udev_sysname = dlsym(RTLD_NEXT, "udev_enumerate_add_match_sysname"); -} - -int udev_enumerate_add_match_sysname(void *udev_enum, const char *sysname) { - if (!orig_udev_sysname) preload_init(); - TRACE("udev_enumerate_add_match_sysname '%s'\n", sysname); - if (sysname && !strcmp(sysname, "card[0-9]*")) { - sysname = "card0"; - } - return orig_udev_sysname(udev_enum, sysname); -} diff --git a/targets/x11-common b/targets/x11-common index 3e625faf5..0d3eea5db 100644 --- a/targets/x11-common +++ b/targets/x11-common @@ -11,6 +11,13 @@ ln -sfT '/etc/crouton/xserverrc' '/etc/X11/xinit/xserverrc' echo "$XMETHOD" > '/etc/crouton/xmethod' +# Modify the Xorg executable to *not* poll udev for cards +offset="`grep -F -m 1 -boa 'card[0-9]*' /usr/bin/Xorg 2>/dev/null || true`" +if [ -n "$offset" ]; then + echo -n 'croutonhax' | dd seek="${offset%:*}" bs=1 of=/usr/bin/Xorg \ + conv=notrunc,nocreat 2>/dev/null +fi + # Install utility for croutoncycle compile wmtools '-lX11' libx11-dev diff --git a/targets/xiwi b/targets/xiwi index b7ea11de1..e246c38c1 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -12,9 +12,6 @@ CHROOTETC='xbindkeysrc.scm xorg-dummy.conf xserverrc xserverrc-xiwi xserverrc-lo ### Append to prepare.sh: XMETHOD="${XMETHOD:-xiwi}" -# We need xorg workarounds on all platforms -compile xorg '-ldl' so - ltspackages='' # On non-ARM precise, install lts-trusty xorg server for compatibility with xorg # if kernel version != 3.4 (lts-trusty mesa requires version >=3.6) diff --git a/targets/xorg b/targets/xorg index 371565b52..7df83c6e9 100644 --- a/targets/xorg +++ b/targets/xorg @@ -25,9 +25,6 @@ if [ ! -f "/sys/class/tty/tty0/active" ]; then compile freon '-ldl' so fi -# We need xorg workarounds on all platforms -compile xorg '-ldl' so - ltspackages='' # On non-ARM precise, install lts-trusty xorg server to support newer hardware # if kernel version != 3.4 (lts-trusty mesa requires version >=3.6) From 9a13a2f33fb444c7424cf7e7e61e57b079865de0 Mon Sep 17 00:00:00 2001 From: Stephen Barber Date: Mon, 16 Mar 2015 12:55:10 -0700 Subject: [PATCH 048/377] selectively apply vgem hack Only apply the vgem hack/workaround if the vgem device is present. Revert the hack if it's not present. --- targets/x11-common | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/targets/x11-common b/targets/x11-common index 0d3eea5db..4219b561a 100644 --- a/targets/x11-common +++ b/targets/x11-common @@ -11,11 +11,21 @@ ln -sfT '/etc/crouton/xserverrc' '/etc/X11/xinit/xserverrc' echo "$XMETHOD" > '/etc/crouton/xmethod' -# Modify the Xorg executable to *not* poll udev for cards -offset="`grep -F -m 1 -boa 'card[0-9]*' /usr/bin/Xorg 2>/dev/null || true`" -if [ -n "$offset" ]; then - echo -n 'croutonhax' | dd seek="${offset%:*}" bs=1 of=/usr/bin/Xorg \ - conv=notrunc,nocreat 2>/dev/null +# Only apply hack if vgem card exists +if [ -c '/dev/dri/card1' ]; then + # Modify the Xorg executable to *not* poll udev for cards + offset="`grep -F -m 1 -boa 'card[0-9]*' /usr/bin/Xorg 2>/dev/null || true`" + if [ -n "$offset" ]; then + echo -n 'croutonhax' | dd seek="${offset%:*}" bs=1 of=/usr/bin/Xorg \ + conv=notrunc,nocreat 2>/dev/null + fi +elif grep -q 'croutonhax' '/usr/bin/Xorg'; then + # Undo hack since there's no vgem module + offset="`grep -F -m 1 -boa 'croutonhax' /usr/bin/Xorg 2>/dev/null || true`" + if [ -n "$offset" ]; then + echo -n 'card[0-9]*' | dd seek="${offset%:*}" bs=1 of=/usr/bin/Xorg \ + conv=notrunc,nocreat 2>/dev/null + fi fi # Install utility for croutoncycle From 9678b5a590be4e9c1ec3d043b28f5c9f33e3ec6e Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Mon, 23 Mar 2015 14:44:20 +0700 Subject: [PATCH 049/377] croutonversion: Add kernel version and freon status to croutonversion So we don't have to keep asking people if /dev/tty0 exists... --- chroot-bin/croutonversion | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chroot-bin/croutonversion b/chroot-bin/croutonversion index 169f31664..08ce30a70 100755 --- a/chroot-bin/croutonversion +++ b/chroot-bin/croutonversion @@ -85,6 +85,12 @@ if [ -z "$CHANGES$DOWNLOAD$UPDATES" ]; then host="`awk -F= '/_RELEASE_DESCRIPTION=/{print $2}' "$hostrel"`" fi echo "host: version ${host:-unknown}" + echo "kernel: $(uname -a)" + freon="yes" + if [ -f /sys/class/tty/tty0/active ]; then + freon="no" + fi + echo "freon: $freon" exit 0 fi From b916dad0508c6854eaf44a7b8d4744dde0af8a47 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Mon, 23 Mar 2015 00:45:58 -0700 Subject: [PATCH 050/377] Glory to bots. May they rule the world in their infinite wisdom. please call off the drones... (#1471) From 75f252cceb8eb763d5d60740348c87eea169dd05 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Mon, 23 Mar 2015 15:56:53 +0700 Subject: [PATCH 051/377] croutoncycle: Fix croutoncycle display/list with Xephyr Active window was not displayed correctly (disp gets renamed and disp = curdisp comparison fails...). Fixes #1498. --- chroot-bin/croutoncycle | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/chroot-bin/croutoncycle b/chroot-bin/croutoncycle index d8b100e51..a16f3059c 100755 --- a/chroot-bin/croutoncycle +++ b/chroot-bin/croutoncycle @@ -168,6 +168,7 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then fi ) | sort | while read -r line; do disp="${line##* }" + display="${disp%"*"}" line="${line% *}" number='0' active=' ' @@ -177,7 +178,7 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then if [ "${number#[0-9]}" = "$number" ]; then number='0' else - disp=":$number" + display=":$number" line="`getname "$number"`" fi fi @@ -195,11 +196,11 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then fi if [ "$line" = 'aura_root_0' ]; then line="$chromiumos" - disp="cros" + display="cros" window='' fi if [ "$cmd" = 'l' ]; then - echo "${disp%"*"}$active $line" + echo "$display$active $line" fi done for disp in $displist; do From 98ba02a018e0402e02150ee8b1d8d298db8c16d3 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Mon, 23 Mar 2015 16:25:45 +0700 Subject: [PATCH 052/377] extension: Test for view.document.readyState instead of document. `document` is the background page, `view.document` is the popup. Should fix #1510. --- host-ext/crouton/background.js | 2 +- host-ext/crouton/manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index 16263d777..df2170113 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -146,7 +146,7 @@ function refreshUI() { for (var i = 0; i < views.length; views++) { var view = views[i]; /* Make sure page is ready */ - if (document.readyState === "complete") { + if (view.document.readyState === "complete") { /* Update "help" link */ helplink = view.document.getElementById("help"); helplink.onclick = showHelp; diff --git a/host-ext/crouton/manifest.json b/host-ext/crouton/manifest.json index 4a560c928..1c524ba0a 100644 --- a/host-ext/crouton/manifest.json +++ b/host-ext/crouton/manifest.json @@ -4,7 +4,7 @@ "name": "crouton integration", "short_name": "crouton", "description": "Improves integration with crouton chroots.", - "version": "2.3.0", + "version": "2.3.1", "icons": { "48": "icon-48.png", "128": "icon-128.png" From 9e9469f13310854340d20d4b7e34a45de6a33bb2 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 25 Mar 2015 17:18:04 -0700 Subject: [PATCH 053/377] Fix X11 auto-selection for Tegra K1. --- targets/x11 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/x11 b/targets/x11 index 5951d67cb..8a3e7a6f0 100644 --- a/targets/x11 +++ b/targets/x11 @@ -4,7 +4,7 @@ # found in the LICENSE file. if grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo || \ ([ "${ARCH#arm}" != "$ARCH" ] && \ - awk -F= '/_RELEASE_VERSION=/ { exit int($2) < 6689 }' \ + awk -F= '/_RELEASE_VERSION=/ { exit !(int($2) < 6689) }' \ '/etc/lsb-release'); then # Xorg won't work on Samsung ARM devices or K1 on release less than 6689 REQUIRES='xephyr' From d1087278e9367b2f06ba2207378de700f4ae3eba Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 25 Mar 2015 17:20:03 -0700 Subject: [PATCH 054/377] Handle the eventual move of Samsung Exynos to Freon --- targets/x11 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/targets/x11 b/targets/x11 index 8a3e7a6f0..229342669 100644 --- a/targets/x11 +++ b/targets/x11 @@ -7,7 +7,12 @@ if grep -q 'SAMSUNG EXYNOS' /proc/cpuinfo || \ awk -F= '/_RELEASE_VERSION=/ { exit !(int($2) < 6689) }' \ '/etc/lsb-release'); then # Xorg won't work on Samsung ARM devices or K1 on release less than 6689 - REQUIRES='xephyr' + # But if we're on Freon, we can't use xephyr either, so xiwi's all we have + if [ -f /sbin/frecon ]; then + REQUIRES='xiwi' + else + REQUIRES='xephyr' + fi else REQUIRES='xorg' fi From e8d61eebb63cdc88c42dee9165a04d4c859cb938 Mon Sep 17 00:00:00 2001 From: DennisL Date: Thu, 26 Mar 2015 01:35:46 -0400 Subject: [PATCH 055/377] Add croutonversion Add croutonversion for troubleshooting. --- chroot-bin/croutonxinitrc-wrapper | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chroot-bin/croutonxinitrc-wrapper b/chroot-bin/croutonxinitrc-wrapper index 6cdcc4193..1be0a6047 100755 --- a/chroot-bin/croutonxinitrc-wrapper +++ b/chroot-bin/croutonxinitrc-wrapper @@ -43,6 +43,10 @@ else fi # Run crouton-specific commands: + +# Show chroot specifics for troubleshooting +croutonversion + if [ -z "$XMETHOD" ]; then if [ -f '/etc/crouton/xmethod' ]; then read -r XMETHOD _ < /etc/crouton/xmethod From 5bd432f024e6a4c345e6d52be5b764c1ac9db68a Mon Sep 17 00:00:00 2001 From: Mike Kasick Date: Wed, 25 Mar 2015 23:54:26 -0400 Subject: [PATCH 056/377] croutontriggerd: Support use of right-{ctrl,shift,alt} in trigger. --- chroot-bin/croutontriggerd | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/chroot-bin/croutontriggerd b/chroot-bin/croutontriggerd index bdd424acd..0db94a8a5 100755 --- a/chroot-bin/croutontriggerd +++ b/chroot-bin/croutontriggerd @@ -28,6 +28,9 @@ STATE_UP=0 KEY_LEFTCTRL=29 KEY_LEFTALT=56 KEY_LEFTSHIFT=42 +KEY_RIGHTCTRL=97 +KEY_RIGHTALT=100 +KEY_RIGHTSHIFT=54 KEY_F1=59 KEY_F2=60 @@ -75,6 +78,7 @@ while :; do sleep "$EVENT_DEV_POLL" done | unbuffered_awk " function update() { + c = lc || rc; s = ls || rs; a = la || ra if (!cmd && c && s && a && p) { cmd = \"p\" } else if (!cmd && c && s && a && n) { @@ -84,9 +88,12 @@ done | unbuffered_awk " cmd = \"\" } } - $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTCTRL { c = $STATE; update() } - $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTSHIFT { s = $STATE; update() } - $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTALT { a = $STATE; update() } - $TYPE == $TYPE_EV_KEY && $KEY == $KEY_F1 { p = $STATE; update() } - $TYPE == $TYPE_EV_KEY && $KEY == $KEY_F2 { n = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTCTRL { lc = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTSHIFT { ls = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_LEFTALT { la = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_RIGHTCTRL { rc = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_RIGHTSHIFT { rs = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_RIGHTALT { ra = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_F1 { p = $STATE; update() } + $TYPE == $TYPE_EV_KEY && $KEY == $KEY_F2 { n = $STATE; update() } " From cf2aacba07e65d75c5b1c5484eae235588db1965 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 27 Mar 2015 19:51:06 -0700 Subject: [PATCH 057/377] Update CONTRIBUTORS --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index a7a6169ec..7469fffab 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -12,6 +12,7 @@ John Tantalo Maurice van Kruchten Micah Lee Michael Orr +Mike Kasick Mikito Takada Nevada Romsdahl Nicolas Boichat From 07facb0d8f42d82ed444f038274136687760257f Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Mar 2015 15:13:10 -0700 Subject: [PATCH 058/377] xiwi-app: use i3 instead of ratpoison Improves floating window behavior and compatibility with software that requires a reparenting window manager. Window title monitoring is also more efficient. Fixes #1483 --- chroot-bin/xiwi | 60 ++++++++++++++++++++++---------------------- chroot-etc/xiwi.conf | 27 ++++++++++++++++++++ targets/xiwi | 5 ++-- 3 files changed, 60 insertions(+), 32 deletions(-) create mode 100644 chroot-etc/xiwi.conf diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index c6566d95c..cafd6b162 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -15,7 +15,7 @@ All parameters are passed to the specified application. A default window manager will full-screen all windows, unless APPLICATION begins with 'start'. You can cycle through multiple windows inside the application via -Ctrl-Alt-Tab/Ctrl-Alt-Shift-Tab, or close them via Ctrl-Alt-Shift-Escape-Escape. +Ctrl-Alt-Tab/Ctrl-Alt-Shift-Tab, or close them via Ctrl-Alt-Shift-Escape. If APPLICATION begins with 'start' but you still want to use the default window manager, specify the full path of the application." 1>&2 exit 2 @@ -23,37 +23,37 @@ elif [ "$1" = '/' ]; then shift 1 xsetroot -cursor_name left_ptr if [ "${1#start}" = "$1" ]; then - ratpoison -f /dev/stdin >/dev/null </dev/null | { + monpid='' + monwid='' + while read _ wid; do + if [ "$wid" = "$monwid" ]; then + continue + fi + if [ -n "$monpid" ]; then + kill "$monpid" 2>/dev/null + fi + monwid="$wid" + xprop -spy -notype -id "$wid" 'WM_NAME' 2>/dev/null | { + while read _ title; do + title="${title%\"}" + title="`cat /etc/crouton/name`/$1: ${title#*\"}" + xprop -root -f CROUTON_NAME 8s -set CROUTON_NAME "$title" + ret="`{ echo -n 'C'; croutoncycle l; } | websocketcommand`" + done + } & + monpid="$!" + done + if [ -n "$monpid" ]; then + kill "$monpid" 2>/dev/null + fi + } & fi exec "$@" -elif [ "$1" = '//' ]; then - # Titlebar update. $2 has the original command name - wininfo="`ratpoison -c 'windows %s%i %t' | sed -n '/^\*/s/^.//p'`" - id="${wininfo%% *}" - title="`cat /etc/crouton/name`/$2: ${wininfo#* }" - xprop -root -f CROUTON_NAME 8s -set CROUTON_NAME "$title" - ret="`{ echo -n 'C'; croutoncycle l; } | websocketcommand`" - if [ "$ret" != 'COK' ]; then - error 1 "${ret#?}" - fi - # Launch titlebar monitoring daemon (only need one per window per display) - { - flock -n 3 || exit 0 - xprop -spy -notype -id "$id" '_NET_WM_NAME' 2>/dev/null \ - | while read _; do - "$xiwicmd" // "$2" - done - } 3>> "/tmp/crouton-lock/xiwi-$DISPLAY-$id" & else export XMETHOD=xiwi exec /usr/local/bin/xinit "$xiwicmd" / "$@" diff --git a/chroot-etc/xiwi.conf b/chroot-etc/xiwi.conf new file mode 100644 index 000000000..6adba9040 --- /dev/null +++ b/chroot-etc/xiwi.conf @@ -0,0 +1,27 @@ +# i3 config file (v4) +# Copyright (c) 2014 The crouton Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Style +new_window none +new_float normal +workspace_layout tabbed +font pango:Sans 8 + +# Colors border backgr. text indicator +client.focused #8E8E8F #EAEAEB #000000 #8E8E8F +client.focused_inactive #8E8E8F #CACACB #525252 #8E8E8F +client.unfocused #8E8E8F #CACACB #525252 #8E8E8F +client.urgent #FF8E8E #FFCACB #520000 #FF8E8E +client.background #C3C3C4 + +# Interaction +focus_follows_mouse no +bindsym Mod1+Shift+Control+Escape kill +floating_modifier Mod1 +bindsym Mod1+Tab focus right +bindsym Mod1+Shift+Tab focus left +bindsym Mod1+Control+Tab focus right +bindsym Mod1+Shift+Control+Tab focus left +bindsym --release button2 kill diff --git a/targets/xiwi b/targets/xiwi index e246c38c1..fae487c1d 100644 --- a/targets/xiwi +++ b/targets/xiwi @@ -6,7 +6,7 @@ REQUIRES='audio extension' PROVIDES='x11' DESCRIPTION='X.org X11 backend running unaccelerated in a Chromium OS window.' CHROOTBIN='croutoncycle croutonfindnacl croutontriggerd croutonxinitrc-wrapper setres xinit xiwi' -CHROOTETC='xbindkeysrc.scm xorg-dummy.conf xserverrc xserverrc-xiwi xserverrc-local.example' +CHROOTETC='xbindkeysrc.scm xiwi.conf xorg-dummy.conf xserverrc xserverrc-xiwi xserverrc-local.example' . "${TARGETSDIR:="$PWD"}/common" ### Append to prepare.sh: @@ -27,7 +27,8 @@ if [ "${DISTROAKA:-"$DISTRO"}" = 'debian' ]; then apt-mark unhold xserver-xorg-video-dummy$ltspackages || true 2>/dev/null fi -install xorg xserver-xorg-video-dummy$ltspackages ratpoison +install xorg xserver-xorg-video-dummy$ltspackages +install --minimal i3 # Compile croutonfbserver compile fbserver '-lX11 -lXfixes -lXdamage -lXext -lXtst' \ From 8c200a9f828c6fa853ecabe4fe8a2a2c8d8fc3e1 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 26 Mar 2015 15:33:55 -0700 Subject: [PATCH 059/377] xiwi: Minor cleanup --- chroot-bin/xiwi | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index cafd6b162..59ec595e6 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -28,6 +28,7 @@ elif [ "$1" = '/' ]; then xprop -spy -root | grep -q _NET_ACTIVE_WINDOW # Launch the window title monitoring daemon xprop -spy -notype -root 0i ' $0\n' '_NET_ACTIVE_WINDOW' 2>/dev/null | { + name="`cat /etc/crouton/name`" monpid='' monwid='' while read _ wid; do @@ -41,9 +42,12 @@ elif [ "$1" = '/' ]; then xprop -spy -notype -id "$wid" 'WM_NAME' 2>/dev/null | { while read _ title; do title="${title%\"}" - title="`cat /etc/crouton/name`/$1: ${title#*\"}" - xprop -root -f CROUTON_NAME 8s -set CROUTON_NAME "$title" - ret="`{ echo -n 'C'; croutoncycle l; } | websocketcommand`" + xprop -root -f CROUTON_NAME 8s -set CROUTON_NAME \ + "$name/$1: ${title#*\"}" + { + echo -n 'C' + croutoncycle l + } | websocketcommand >/dev/null done } & monpid="$!" From e844948d7b4524c7e5856c5f557da911fa415949 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 27 Mar 2015 20:05:14 -0700 Subject: [PATCH 060/377] Allow for user-specific init scripts for xiwi apps. Useful for setting things like keyboard layouts. --- chroot-bin/xiwi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 59ec595e6..2152616b5 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -56,6 +56,10 @@ elif [ "$1" = '/' ]; then kill "$monpid" 2>/dev/null fi } & + # Launch user init scripts + if [ -f "$HOME/.xiwirc" ]; then + /bin/sh "$HOME/.xiwirc" || true + fi fi exec "$@" else From f94a27436e2d758421f2f6e43fda6fb41bf6930d Mon Sep 17 00:00:00 2001 From: David Schneider Date: Fri, 27 Mar 2015 20:52:52 -0700 Subject: [PATCH 061/377] Add -f to xiwi to force xiwi to remain open If your gui app *must* fork, you can use this. You'll get a better experience if you can tell the app not to fork though... Fixes #1538 --- chroot-bin/xiwi | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 2152616b5..900d71f82 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -9,10 +9,16 @@ xiwicmd="`readlink -f "$0"`" if [ "$#" = 0 ]; then - echo "Usage: ${0##*/} APPLICATION [PARAMETERS ...] + echo "Usage: ${0##*/} [-f] APPLICATION [PARAMETERS ...] Launches a windowed session in Chromium OS for any graphical application. All parameters are passed to the specified application. +xiwi will normally close when the application returns. Some gui applications +fork before or during normal operation, which can confuse xiwi and cause it to +quit prematurely. If your application does not have a parameter that prevents +it from forking, you can use -f to prevent xiwi from quitting automatically. +You will need to Ctrl-C xiwi in the terminal to make it quit. + A default window manager will full-screen all windows, unless APPLICATION begins with 'start'. You can cycle through multiple windows inside the application via Ctrl-Alt-Tab/Ctrl-Alt-Shift-Tab, or close them via Ctrl-Alt-Shift-Escape. @@ -21,6 +27,11 @@ manager, specify the full path of the application." 1>&2 exit 2 elif [ "$1" = '/' ]; then shift 1 + forever='0' + if [ "$1" = '-f' ]; then + forever='infinity' + shift 1 + fi xsetroot -cursor_name left_ptr if [ "${1#start}" = "$1" ]; then i3 -c "/etc/crouton/xiwi.conf" & @@ -61,7 +72,8 @@ elif [ "$1" = '/' ]; then /bin/sh "$HOME/.xiwirc" || true fi fi - exec "$@" + "$@" + exec sleep "$forever" else export XMETHOD=xiwi exec /usr/local/bin/xinit "$xiwicmd" / "$@" From a7433319afa8339e58be8480e497b2b2b604a46d Mon Sep 17 00:00:00 2001 From: David Schneider Date: Mon, 30 Mar 2015 21:48:06 -0700 Subject: [PATCH 062/377] Improve error logging in fbserver.c --- src/fbserver.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/fbserver.c b/src/fbserver.c index 62ee7c791..baf5551c6 100644 --- a/src/fbserver.c +++ b/src/fbserver.c @@ -99,6 +99,14 @@ void kb_release_all() { /* X11-related functions */ static int xerror_handler(Display *dpy, XErrorEvent *e) { + if (verbose < 1) + return 0; + char msg[64] = {0}; + char op[32] = {0}; + sprintf(msg, "%d", e->request_code); + XGetErrorDatabaseText(dpy, "XRequest", msg, "", op, sizeof(op)); + XGetErrorText(dpy, e->error_code, msg, sizeof(msg)); + error("%s (%s)", msg, op); return 0; } @@ -378,9 +386,11 @@ int write_image(const struct screen* screen) { reply->cursor_updated = 0; while (XCheckTypedEvent(dpy, fixesEvent + XFixesCursorNotify, &ev)) { XFixesCursorNotifyEvent* curev = (XFixesCursorNotifyEvent*)&ev; - char* name = XGetAtomName(dpy, curev->cursor_name); - log(2, "cursor! %ld %s", curev->cursor_serial, name); - XFree(name); + if (verbose >= 2) { + char* name = XGetAtomName(dpy, curev->cursor_name); + log(2, "cursor! %ld %s", curev->cursor_serial, name); + XFree(name); + } reply->cursor_updated = 1; reply->cursor_serial = curev->cursor_serial; } From 0cdb49af55d078da84646ee66402f78ef2f734ea Mon Sep 17 00:00:00 2001 From: David Schneider Date: Mon, 30 Mar 2015 21:48:31 -0700 Subject: [PATCH 063/377] Add CROUTON_CONNECTED property for xiwi displays --- src/fbserver.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/fbserver.c b/src/fbserver.c index baf5551c6..c555c036f 100644 --- a/src/fbserver.c +++ b/src/fbserver.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,19 @@ static int xerror_handler(Display *dpy, XErrorEvent *e) { return 0; } +/* Sets the CROUTON_CONNECTED property for the root window */ +static void set_connected(Display *dpy, uint8_t connected) { + Window root = DefaultRootWindow(dpy); + Atom prop = XInternAtom(dpy, "CROUTON_CONNECTED", False); + if (prop == None) { + error("Unable to get atom"); + return; + } + XChangeProperty(dpy, root, prop, XA_INTEGER, 8, PropModeReplace, + &connected, 1); + XFlush(dpy); +} + /* Registers XDamage events for a given Window. */ static void register_damage(Display *dpy, Window win) { XWindowAttributes attrib; @@ -524,7 +538,9 @@ int main(int argc, char** argv) { int length; while (1) { + set_connected(dpy, False); socket_server_accept(VERSION); + set_connected(dpy, True); while (1) { length = socket_client_read_frame((char*)buffer, sizeof(buffer)); if (length < 0) { From 21bf27cf2fd03401c263094cfe7276a738def3f6 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Mon, 30 Mar 2015 22:24:39 -0700 Subject: [PATCH 064/377] xiwi -f: close when the window is closed if nothing is shown --- chroot-bin/xiwi | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 900d71f82..5653c6193 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -17,7 +17,7 @@ xiwi will normally close when the application returns. Some gui applications fork before or during normal operation, which can confuse xiwi and cause it to quit prematurely. If your application does not have a parameter that prevents it from forking, you can use -f to prevent xiwi from quitting automatically. -You will need to Ctrl-C xiwi in the terminal to make it quit. +xiwi will quit if you close the Chromium OS window when nothing is displayed. A default window manager will full-screen all windows, unless APPLICATION begins with 'start'. You can cycle through multiple windows inside the application via @@ -27,9 +27,9 @@ manager, specify the full path of the application." 1>&2 exit 2 elif [ "$1" = '/' ]; then shift 1 - forever='0' + foreground='' if [ "$1" = '-f' ]; then - forever='infinity' + foreground="y" shift 1 fi xsetroot -cursor_name left_ptr @@ -38,6 +38,8 @@ elif [ "$1" = '/' ]; then # Wait for i3 to launch xprop -spy -root | grep -q _NET_ACTIVE_WINDOW # Launch the window title monitoring daemon + # _NET_ACTIVE_WINDOW is more reliable than _NET_CLIENT_LIST_STACKING for + # keeping track of the topmost window. xprop -spy -notype -root 0i ' $0\n' '_NET_ACTIVE_WINDOW' 2>/dev/null | { name="`cat /etc/crouton/name`" monpid='' @@ -73,7 +75,21 @@ elif [ "$1" = '/' ]; then fi fi "$@" - exec sleep "$forever" + if [ -n "$foreground" ]; then + xprop -spy -notype -root 0i ' $0\n' 'CROUTON_CONNECTED' \ + | while read _ connected; do + if [ "$connected" != 0 ]; then + continue + fi + # _NET_CLIENT_LIST_STACKING is more reliable than + # _NET_ACTIVE_WINDOW for detecting when no windows exist + if ! xprop -notype -root '_NET_CLIENT_LIST_STACKING' \ + | grep -q '0x'; then + kill "$$" + break + fi + done + fi else export XMETHOD=xiwi exec /usr/local/bin/xinit "$xiwicmd" / "$@" From 8ee31495a1451830c5899bf57eecfa8366a11deb Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 31 Mar 2015 11:47:37 -0700 Subject: [PATCH 065/377] Recursively autobuild the extension pnacl --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index db13ce369..7dab818c6 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,9 @@ SCRIPTS := \ $(wildcard installer/*/*) \ $(wildcard src/*) \ $(wildcard targets/*) +EXTPEXE = host-ext/crouton/kiwi.pexe +EXTPEXESOURCES = $(wildcard host-ext/nacl_src/*.h) \ + $(wildcard host-ext/nacl_src/*.cc) EXTSOURCES = $(wildcard host-ext/crouton/*) GENVERSION = build/genversion.sh CONTRIBUTORSSED = build/CONTRIBUTORS.sed @@ -56,6 +59,9 @@ $(TARGET): $(WRAPPER) $(SCRIPTS) $(GENVERSION) $(GITHEAD) Makefile $(EXTTARGET): $(EXTSOURCES) Makefile rm -f $(EXTTARGET) && zip -q --junk-paths $(EXTTARGET) $(EXTSOURCES) +$(EXTPEXE): $(EXTPEXESOURCES) + $(MAKE) -C host-ext/nacl_src + $(SRCTARGETS): src/$(patsubst crouton%,src/%.c,$@) $($@_DEPS) Makefile gcc $(CFLAGS) $(patsubst crouton%,src/%.c,$@) $($@_LIBS) -o $@ From a9f5bfd017a2ca4e2062d10a5b3d798a9e069264 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 31 Mar 2015 13:11:49 -0700 Subject: [PATCH 066/377] Support parameters in XMETHOD Syntax is xiwi-flag-var=val --- chroot-bin/croutoncycle | 4 ++-- chroot-bin/croutonxinitrc-wrapper | 8 +++++--- chroot-bin/setres | 2 +- chroot-etc/xserverrc | 2 +- chroot-etc/xserverrc-xiwi | 4 +++- chroot-etc/xserverrc-xorg | 4 +++- host-bin/enter-chroot | 4 ++-- 7 files changed, 17 insertions(+), 11 deletions(-) diff --git a/chroot-bin/croutoncycle b/chroot-bin/croutoncycle index a16f3059c..420a9f563 100755 --- a/chroot-bin/croutoncycle +++ b/chroot-bin/croutoncycle @@ -88,7 +88,7 @@ for disp in /tmp/.X*-lock; do | grep -q 'INTEGER'; then displist="$displist $disp" elif DISPLAY="$disp" xprop -root 'CROUTON_XMETHOD' 2>/dev/null \ - | grep -q '= "xiwi"$'; then + | grep -q '= "xiwi'; then displist="$displist $disp" xiwiactive='y' fi @@ -304,7 +304,7 @@ if [ "${destdisp#:}" = "$destdisp" ]; then fi else export DISPLAY="$destdisp" - if xprop -root 'CROUTON_XMETHOD' 2>/dev/null | grep -q '= "xiwi"$'; then + if xprop -root 'CROUTON_XMETHOD' 2>/dev/null | grep -q '= "xiwi'; then if [ -z "$freonowner" -a "$tty" != 'tty1' ]; then sudo -n chvt 1 sleep .1 diff --git a/chroot-bin/croutonxinitrc-wrapper b/chroot-bin/croutonxinitrc-wrapper index 1be0a6047..7f5d77a1f 100755 --- a/chroot-bin/croutonxinitrc-wrapper +++ b/chroot-bin/croutonxinitrc-wrapper @@ -56,6 +56,8 @@ if [ -z "$XMETHOD" ]; then exit 1 fi fi +xmethodtype="${XMETHOD%%-*}" +xmethodargs="${XMETHOD#*-}" # Record the name of the chroot in the root window properties if [ -f '/etc/crouton/name' ] && hash xprop 2>/dev/null; then @@ -74,7 +76,7 @@ if hash croutonclip 2>/dev/null; then fi # Pass through the host cursor and correct mousewheels on xephyr -if [ "$XMETHOD" = 'xephyr' ]; then +if [ "$xmethodtype" = 'xephyr' ]; then host-x11 croutoncursor "$DISPLAY" & if [ -z "$CROUTON_WHEEL_PARAMS" -a -r "$HOME/.croutonwheel" ]; then CROUTON_WHEEL_PARAMS="`head -n1 "$HOME/.croutonwheel"`" @@ -86,7 +88,7 @@ fi croutontriggerd & # Input-related stuff is not needed for kiwi -if [ "$XMETHOD" != "xiwi" ]; then +if [ "$xmethodtype" != "xiwi" ]; then # Apply the Chromebook keyboard map if installed. if [ -f '/usr/share/X11/xkb/compat/chromebook' ]; then setxkbmap -model chromebook @@ -125,7 +127,7 @@ if [ "$XMETHOD" != "xiwi" ]; then fi # Crouton-in-a-tab: Start fbserver and launch display -if [ "$XMETHOD" = 'xiwi' ]; then +if [ "$xmethodtype" = 'xiwi' ]; then # The extension sends evdev key codes: fix the keyboard mapping rules setxkbmap -rules evdev # Reapply xkb map: This fixes autorepeat mask in "xset q" diff --git a/chroot-bin/setres b/chroot-bin/setres index bfcb3688d..ce100ee07 100755 --- a/chroot-bin/setres +++ b/chroot-bin/setres @@ -27,7 +27,7 @@ fi xmethod="`xprop -root 'CROUTON_XMETHOD' | sed -n 's/^.*\"\(.*\)\"/\1/p'`" -if [ "$xmethod" != "xiwi" ]; then +if [ "${xmethod%%-*}" != "xiwi" ]; then cvt "$x" "$y" "$r" | { read -r _ read -r _ mode data diff --git a/chroot-etc/xserverrc b/chroot-etc/xserverrc index 545ddfbe1..eb3e1eed5 100644 --- a/chroot-etc/xserverrc +++ b/chroot-etc/xserverrc @@ -12,7 +12,7 @@ if [ -z "$XMETHOD" ]; then fi fi -xserverrc="/etc/crouton/xserverrc-$XMETHOD" +xserverrc="/etc/crouton/xserverrc-${XMETHOD%%-*}" if [ "${XMETHOD##*/}" != "$XMETHOD" -o ! -f "$xserverrc" ]; then echo "Invalid X11 backend '$XMETHOD'" 1>&2 exit 2 diff --git a/chroot-etc/xserverrc-xiwi b/chroot-etc/xserverrc-xiwi index 5bdb64c17..8932d9192 100644 --- a/chroot-etc/xserverrc-xiwi +++ b/chroot-etc/xserverrc-xiwi @@ -11,7 +11,9 @@ for arg in "$@"; do fi done -export XMETHOD='xiwi' +if [ "${XMETHOD%%-*}" != 'xiwi' ]; then + export XMETHOD='xiwi' +fi XARGS="-nolisten tcp -config xorg-dummy.conf -logfile $logfile" if [ -f /etc/crouton/xserverrc-local ]; then . /etc/crouton/xserverrc-local diff --git a/chroot-etc/xserverrc-xorg b/chroot-etc/xserverrc-xorg index 4aeb99a7b..c0fc926ae 100644 --- a/chroot-etc/xserverrc-xorg +++ b/chroot-etc/xserverrc-xorg @@ -3,7 +3,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -export XMETHOD='xorg' +if [ "${XMETHOD%%-*}" != 'xorg' ]; then + export XMETHOD='xorg' +fi XARGS='-nolisten tcp' if [ -f /etc/crouton/xserverrc-local ]; then . /etc/crouton/xserverrc-local diff --git a/host-bin/enter-chroot b/host-bin/enter-chroot index da26b45a0..e279f09e7 100755 --- a/host-bin/enter-chroot +++ b/host-bin/enter-chroot @@ -138,8 +138,8 @@ fi # Check to ensure that the XMETHOD requested has been installed if [ -n "$TMPXMETHOD" ]; then - if ! grep -q "^$TMPXMETHOD$" "$CHROOTS/$NAME/.crouton-targets" 2>/dev/null; then - error 1 "$CHROOTS/$NAME does not contain XMETHOD '$TMPXMETHOD'" + if ! grep -q "^$TMPXMETHOD\(-\|\$\)" "$CHROOTS/$NAME/.crouton-targets"; then + error 1 "$CHROOTS/$NAME does not contain XMETHOD '${TMPXMETHOD%%-*}'" fi fi From 3517fd806c1eaceb4308bf158f299d653c275f03 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sun, 1 Mar 2015 00:53:12 -0800 Subject: [PATCH 067/377] Support extra parameters when launching xiwi windows. Currently, full-screen/window is supported. --- host-ext/crouton/background.js | 15 ++++++++++++--- host-ext/crouton/window.js | 6 ++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index df2170113..e36117835 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -491,8 +491,16 @@ function websocketMessage(evt) { break; case 'X': /* Ask to open a crouton window */ display = payload - match = display.match(/^:([0-9]+)$/) + match = display.match(/^:([0-9]+)([- ][^- ]*)*$/) displaynum = match ? match[1] : null + if (displaynum) { + display = ":" + displaynum; + } + mode = (match.length > 2 && match[2].length >= 2) ? match[2][1] : 'f' + if (mode != 'f' && mode != 'w') { + console.log('invalid xiwi mode: ' + mode); + mode = 'f'; + } if (!displaynum) { /* Minimize all kiwi windows */ var disps = Object.keys(kiwi_win_); @@ -520,7 +528,7 @@ function websocketMessage(evt) { !kiwi_win_[display].window.closing)) { /* focus/full screen an existing window */ var winid = kiwi_win_[display].id; - chrome.windows.update(winid, {focused: true}); + chrome.windows.update(winid, {'focused': true}); chrome.windows.get(winid, function(win) { if (win.state == "maximized") chrome.windows.update(winid, {'state': 'fullscreen'}, @@ -538,7 +546,8 @@ function websocketMessage(evt) { chrome.windows.create({ 'url': "window.html?display=" + displaynum + "&debug=" + (debug_ ? 1 : 0) + "&hidpi=" + (hidpi_ ? 1 : 0) + - "&title=" + encodeURIComponent(name), + "&title=" + encodeURIComponent(name) + + "&mode=" + mode, 'type': "popup" }, function(newwin) { kiwi_win_[display].id = newwin.id; diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index 8489b5f93..48811e47b 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -262,8 +262,10 @@ function handleFocusBlur(evt) { } /* Start in full screen */ -chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {'state': "fullscreen"}, function(win) {}) +if (location.search.search(/[&?]mode=f(&|$)/i) != -1) { + chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, + {'state': "fullscreen"}, function(win) {}) +} document.addEventListener('DOMContentLoaded', function() { listener_ = document.getElementById('listener'); From 66f4a55a9dbbf68b5e080fc27635d062f6d433f1 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 31 Mar 2015 13:28:46 -0700 Subject: [PATCH 068/377] Pass xiwi args to the extension --- chroot-bin/croutoncycle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/chroot-bin/croutoncycle b/chroot-bin/croutoncycle index 420a9f563..50a0576bf 100755 --- a/chroot-bin/croutoncycle +++ b/chroot-bin/croutoncycle @@ -304,7 +304,9 @@ if [ "${destdisp#:}" = "$destdisp" ]; then fi else export DISPLAY="$destdisp" - if xprop -root 'CROUTON_XMETHOD' 2>/dev/null | grep -q '= "xiwi'; then + xmethod="`xprop -root 'CROUTON_XMETHOD' 2>/dev/null \ + | sed -n 's/^.*\"\(.*\)\"/\1/p'`" + if [ "${xmethod%%-*}" = 'xiwi' ]; then if [ -z "$freonowner" -a "$tty" != 'tty1' ]; then sudo -n chvt 1 sleep .1 @@ -314,7 +316,7 @@ else if [ -z "$freonowner" ]; then host-x11 croutonwmtools raise "$aurawin" fi - STATUS="`echo -n "X${destdisp}" | websocketcommand`" + STATUS="`echo -n "X${destdisp} ${xmethod#*-}" | websocketcommand`" if [ "$STATUS" != 'XOK' ]; then error 1 "${STATUS#?}" fi From 82d1ed1ef67353c238e3bf835a5984e91c9629f6 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 31 Mar 2015 14:20:34 -0700 Subject: [PATCH 069/377] xiwi: start in windowed mode unless -F is supplied. Add -T although it doesn't work yet. --- chroot-bin/xiwi | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/chroot-bin/xiwi b/chroot-bin/xiwi index 5653c6193..573d565b3 100755 --- a/chroot-bin/xiwi +++ b/chroot-bin/xiwi @@ -5,14 +5,13 @@ # Runs the specified X11 application in its own X server in Chromium OS. -. "`dirname "$0"`/../installer/functions" -xiwicmd="`readlink -f "$0"`" - -if [ "$#" = 0 ]; then - echo "Usage: ${0##*/} [-f] APPLICATION [PARAMETERS ...] +USAGE="Usage: ${0##*/} [-f] [-F|-T] APPLICATION [PARAMETERS ...] Launches a windowed session in Chromium OS for any graphical application. All parameters are passed to the specified application. +By default, the app is launched in a window. Passing -F will launch the app +full-screen, and passing -T will launch the app in a tab. + xiwi will normally close when the application returns. Some gui applications fork before or during normal operation, which can confuse xiwi and cause it to quit prematurely. If your application does not have a parameter that prevents @@ -20,20 +19,30 @@ it from forking, you can use -f to prevent xiwi from quitting automatically. xiwi will quit if you close the Chromium OS window when nothing is displayed. A default window manager will full-screen all windows, unless APPLICATION begins -with 'start'. You can cycle through multiple windows inside the application via -Ctrl-Alt-Tab/Ctrl-Alt-Shift-Tab, or close them via Ctrl-Alt-Shift-Escape. -If APPLICATION begins with 'start' but you still want to use the default window -manager, specify the full path of the application." 1>&2 - exit 2 +with 'start' or is 'xinit'. You can cycle through multiple windows inside the +application via Ctrl-Alt-Tab/Ctrl-Alt-Shift-Tab, or close them via +Ctrl-Alt-Shift-Escape. If APPLICATION begins with 'start' but you still want to +use the default window manager, specify the full path of the application." + +. "`dirname "$0"`/../installer/functions" +xiwicmd="`readlink -f "$0"`" +OPTSTRING='FfTt' + +if [ "$#" = 0 ]; then + error 2 "$USAGE" elif [ "$1" = '/' ]; then shift 1 foreground='' - if [ "$1" = '-f' ]; then - foreground="y" - shift 1 - fi + while getopts "$OPTSTRING" f; do + case "$f" in + f) foreground='y';; + t|T|F) :;; + \?) error 2 "$USAGE";; + esac + done + shift "$((OPTIND-1))" xsetroot -cursor_name left_ptr - if [ "${1#start}" = "$1" ]; then + if [ "$1" != 'xinit' -a "${1#start}" = "$1" ]; then i3 -c "/etc/crouton/xiwi.conf" & # Wait for i3 to launch xprop -spy -root | grep -q _NET_ACTIVE_WINDOW @@ -91,6 +100,14 @@ elif [ "$1" = '/' ]; then done fi else - export XMETHOD=xiwi + export XMETHOD='xiwi-window' + while getopts "$OPTSTRING" f; do + case "$f" in + f) :;; + F) export XMETHOD='xiwi-fullscreen';; + t|T) export XMETHOD='xiwi-tab';; + \?) error 2 "$USAGE";; + esac + done exec /usr/local/bin/xinit "$xiwicmd" / "$@" fi From 8421b0a48d963f120f8620f835b63647bc4cb404 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 31 Mar 2015 18:30:08 -0700 Subject: [PATCH 070/377] Remove unnecessary quotes on object definitions. --- host-ext/crouton/background.js | 14 +++++++------- host-ext/crouton/window.js | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index e36117835..bcb4c9e86 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -138,7 +138,7 @@ function refreshUI() { icon = "disconnected"; chrome.browserAction.setIcon( - {path: {'19': icon + '-19.png', '38': icon + '-38.png'}} + {path: {19: icon + '-19.png', 38: icon + '-38.png'}} ); chrome.browserAction.setTitle({title: 'crouton: ' + icon}); @@ -510,14 +510,14 @@ function websocketMessage(evt) { minimize = function(win) { chrome.windows.update(winid, - {'state': 'minimized'}, function(win) {})} + {state: 'minimized'}, function(win) {})} chrome.windows.get(winid, function(win) { /* To make restore nicer, first exit full screen, * then minimize */ if (win.state == "fullscreen") { chrome.windows.update(winid, - {'state': 'maximized'}, minimize) + {state: 'maximized'}, minimize) } else { minimize() } @@ -528,10 +528,10 @@ function websocketMessage(evt) { !kiwi_win_[display].window.closing)) { /* focus/full screen an existing window */ var winid = kiwi_win_[display].id; - chrome.windows.update(winid, {'focused': true}); + chrome.windows.update(winid, {focused: true}); chrome.windows.get(winid, function(win) { if (win.state == "maximized") - chrome.windows.update(winid, {'state': 'fullscreen'}, + chrome.windows.update(winid, {state: 'fullscreen'}, function(win) {}) }) } else { @@ -543,12 +543,12 @@ function websocketMessage(evt) { win = windows_.filter(function(x){ return x.display == display })[0] name = win ? win.name : "crouton in a window"; - chrome.windows.create({ 'url': "window.html?display=" + displaynum + + chrome.windows.create({ url: "window.html?display=" + displaynum + "&debug=" + (debug_ ? 1 : 0) + "&hidpi=" + (hidpi_ ? 1 : 0) + "&title=" + encodeURIComponent(name) + "&mode=" + mode, - 'type': "popup" }, + type: "popup" }, function(newwin) { kiwi_win_[display].id = newwin.id; focus_win_ = display; diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index 48811e47b..1134b8089 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -180,18 +180,18 @@ function handleMessage(message) { newstate = "fullscreen"; } chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {'state': newstate}, function(win) {}) + {state: newstate}, function(win) {}) }) } else if (type == "state" && payload == "hide") { /* Hide window */ chrome.windows.getCurrent(function(win) { minimize = function(win) { chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {'state': 'minimized'}, function(win) {})} + {state: 'minimized'}, function(win) {})} /* To make restore nicer, first exit full screen, then minimize */ if (win.state == "fullscreen") { chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {'state': 'maximized'}, minimize) + {state: 'maximized'}, minimize) } else { minimize() } @@ -264,7 +264,7 @@ function handleFocusBlur(evt) { /* Start in full screen */ if (location.search.search(/[&?]mode=f(&|$)/i) != -1) { chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {'state': "fullscreen"}, function(win) {}) + {state: "fullscreen"}, function(win) {}) } document.addEventListener('DOMContentLoaded', function() { From a684c8c3fc6fa1cda6032f4a912f65d10022d02a Mon Sep 17 00:00:00 2001 From: David Schneider Date: Tue, 31 Mar 2015 20:08:48 -0700 Subject: [PATCH 071/377] Tab support! --- host-ext/crouton/background.js | 140 ++++++++++++++++++++++----------- host-ext/crouton/window.js | 10 ++- 2 files changed, 103 insertions(+), 47 deletions(-) diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index bcb4c9e86..695ebf94f 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -42,7 +42,7 @@ var logger_ = []; /* Array of status messages: [LogLevel, time, message] */ var windows_ = []; /* Array of windows. (.display, .name) */ var kiwi_win_ = {}; /* Map of kiwi windows. Key is display, value is object - (.id, .window: window element) */ + (.id, .isTab, .window: window element) */ var focus_win_ = -1; /* Focused kiwi window. -1 if no kiwi window focused. */ var notifications_ = {}; /* Map of notification id to function to be called when @@ -181,8 +181,15 @@ function refreshUI() { refreshUI(); var disps = Object.keys(kiwi_win_); for (var i = 0; i < disps.length; i++) { - if (kiwi_win_[disps[i]].window) - kiwi_win_[disps[i]].window.setDebug(debug_?1:0); + var win = kiwi_win_[disps[i]]; + if (win.window) { + if (win.isTab) { + chrome.tabs.sendMessage(win.id, + {func: 'setDebug', param: debug_?1:0}); + } else { + win.window.setDebug(debug_?1:0); + } + } } } debugcheck.checked = debug_; @@ -195,8 +202,15 @@ function refreshUI() { refreshUI(); var disps = Object.keys(kiwi_win_); for (var i = 0; i < disps.length; i++) { - if (kiwi_win_[disps[i]].window) - kiwi_win_[disps[i]].window.setHiDPI(hidpi_?1:0); + var win = kiwi_win_[disps[i]]; + if (win.window) { + if (win.isTab) { + chrome.tabs.sendMessage(win.id, + {func: 'setHiDPI', param: hidpi_?1:0}); + } else { + win.window.setHiDPI(hidpi_?1:0); + } + } } } hidpicheck.disabled = false; @@ -274,9 +288,15 @@ function clipboardStart() { LogLevel.INFO); setStatus("Started...", false); - /* Monitor window focus changes/removals and report to croutonclip */ - chrome.windows.onFocusChanged.addListener(windowFocusChanged) - chrome.windows.onRemoved.addListener(windowRemoved) + /* Monitor window/tab focus changes/removals and report to croutonclip */ + chrome.windows.onFocusChanged.addListener( + function(id) { onFocusChanged(id, false); }); + chrome.windows.onRemoved.addListener( + function(id) { onRemoved(id, false); }); + chrome.tabs.onActivated.addListener( + function(data) { onFocusChanged(data.tabId, true); }); + chrome.tabs.onRemoved.addListener( + function(id, data) { onRemoved(id, true); }); clipboardholder_ = document.getElementById("clipboardholder"); @@ -479,8 +499,14 @@ function websocketMessage(evt) { ).filter( function(x) { return !!x; } ) windows_.forEach(function(k) { - if (kiwi_win_[k.display] && kiwi_win_[k.display].window) { - kiwi_win_[k.display].window.setTitle(k.name); + var win = kiwi_win_[k.display]; + if (win && win.window) { + if (win.isTab) { + chrome.tabs.sendMessage(win.id, + {func: 'setTitle', param: k.name}); + } else { + win.window.setTitle(k.name); + } } }) @@ -492,34 +518,37 @@ function websocketMessage(evt) { case 'X': /* Ask to open a crouton window */ display = payload match = display.match(/^:([0-9]+)([- ][^- ]*)*$/) - displaynum = match ? match[1] : null + displaynum = match ? match[1] : null; + mode = null; if (displaynum) { display = ":" + displaynum; - } - mode = (match.length > 2 && match[2].length >= 2) ? match[2][1] : 'f' - if (mode != 'f' && mode != 'w') { - console.log('invalid xiwi mode: ' + mode); - mode = 'f'; + mode = match[2].length >= 2 ? match[2].charAt(1) : 'f'; + if ('fwt'.indexOf(mode) == -1) { + console.log('invalid xiwi mode: ' + mode); + mode = 'f'; + } } if (!displaynum) { /* Minimize all kiwi windows */ var disps = Object.keys(kiwi_win_); for (var i = 0; i < disps.length; i++) { + if (kiwi_win_[disps[i]].isTab) { + continue; + } var winid = kiwi_win_[disps[i]].id; chrome.windows.update(winid, {focused: false}); minimize = function(win) { - chrome.windows.update(winid, - {state: 'minimized'}, function(win) {})} + chrome.windows.update(winid, {state: 'minimized'}); }; chrome.windows.get(winid, function(win) { /* To make restore nicer, first exit full screen, * then minimize */ if (win.state == "fullscreen") { - chrome.windows.update(winid, - {state: 'maximized'}, minimize) + chrome.windows.update(winid, {state: 'maximized'}, + minimize); } else { - minimize() + minimize(); } }) } @@ -528,33 +557,49 @@ function websocketMessage(evt) { !kiwi_win_[display].window.closing)) { /* focus/full screen an existing window */ var winid = kiwi_win_[display].id; - chrome.windows.update(winid, {focused: true}); - chrome.windows.get(winid, function(win) { - if (win.state == "maximized") - chrome.windows.update(winid, {state: 'fullscreen'}, - function(win) {}) - }) + if (kiwi_win_[display].isTab) { + chrome.tabs.update(winid, {active: true}); + chrome.tabs.get(winid, function(tab) { + chrome.windows.update(tab.windowId, {focused: true}); + }); + } else { + chrome.windows.update(winid, {focused: true}); + chrome.windows.get(winid, function(win) { + if (win.state == "maximized") + chrome.windows.update(winid, {state: 'fullscreen'}); + }); + } } else { /* Open a new window */ kiwi_win_[display] = new Object(); kiwi_win_[display].id = -1; + kiwi_win_[display].isTab = mode == 't'; kiwi_win_[display].window = null; - win = windows_.filter(function(x){ return x.display == display })[0] + win = windows_.filter(function(x){return x.display == display})[0]; name = win ? win.name : "crouton in a window"; + create = chrome.windows.create; + data = {}; + + if (kiwi_win_[display].isTab) { + name = win ? win.name : "crouton in a tab"; + create = chrome.tabs.create; + } else { + data['type'] = "popup"; + } - chrome.windows.create({ url: "window.html?display=" + displaynum + - "&debug=" + (debug_ ? 1 : 0) + - "&hidpi=" + (hidpi_ ? 1 : 0) + - "&title=" + encodeURIComponent(name) + - "&mode=" + mode, - type: "popup" }, - function(newwin) { - kiwi_win_[display].id = newwin.id; - focus_win_ = display; - if (active_ && sversion_ >= 2) - websocket_.send("Cs" + focus_win_); - }); + data['url'] = "window.html?display=" + displaynum + + "&debug=" + (debug_ ? 1 : 0) + + "&hidpi=" + (hidpi_ ? 1 : 0) + + "&title=" + encodeURIComponent(name) + + "&mode=" + mode; + + create(data, function(newwin) { + kiwi_win_[display].id = newwin.id; + focus_win_ = display; + if (active_ && sversion_ >= 2) + websocket_.send("Cs" + focus_win_); + }); } websocket_.send("XOK"); closePopup(); @@ -598,13 +643,14 @@ function websocketClose() { checkUpdate(false); } -/* Called when window in focus changes: feeback to the extension so the +/* Called when window/tab in focus changes: feeback to the extension so the * clipboard can be transfered. */ -function windowFocusChanged(windowid) { +function onFocusChanged(id, isTab) { var disps = Object.keys(kiwi_win_); nextfocus_win_ = "cros"; for (var i = 0; i < disps.length; i++) { - if (kiwi_win_[disps[i]].id == windowid) { + if (kiwi_win_[disps[i]].isTab == isTab + && kiwi_win_[disps[i]].id == id) { nextfocus_win_ = disps[i]; break; } @@ -617,12 +663,14 @@ function windowFocusChanged(windowid) { } } -/* Called when a window is removed, so we can delete its reference. */ -function windowRemoved(windowid) { +/* Called when a window/tab is removed, so we can delete its reference. */ +function onRemoved(id, isTab) { var disps = Object.keys(kiwi_win_); for (var i = 0; i < disps.length; i++) { - if (kiwi_win_[disps[i]].id == windowid) { + if (kiwi_win_[disps[i]].isTab == isTab + && kiwi_win_[disps[i]].id == id) { kiwi_win_[disps[i]].id = -1; + kiwi_win_[disps[i]].isTab = false; kiwi_win_[disps[i]].window = null; printLog("Window " + disps[i] + " removed", LogLevel.DEBUG); } diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index 1134b8089..3a129d57c 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -16,7 +16,7 @@ var errordiv_ = null; /* error div */ var debug_ = 0; /* Debuging level, passed to NaCl module */ var hidpi_ = 0; /* HiDPI mode */ var display_ = null; /* Display number to use */ -var title_ = "crouton in a window"; /* window title */ +var title_ = "crouton"; /* window title */ var connected_ = false; var closing_ = false; /* Disconnected, and waiting for the window to close */ var error_ = false; /* An error has occured */ @@ -69,6 +69,13 @@ function handleCrash(event) { registerWindow(false); } +/* Handle requests from the background page (for tabs) */ +function handleRequest(message, sender, sendResponse) { + if (typeof(window[message.func]) == "function") { + window[message.func](message.param); + } +}; + /* Change debugging level */ function setDebug(debug) { debug_ = (debug > 0) ? DEBUG_LEVEL : 0; @@ -278,6 +285,7 @@ document.addEventListener('DOMContentLoaded', function() { window.addEventListener('focus', handleFocusBlur); window.addEventListener('blur', handleFocusBlur); document.addEventListener('visibilitychange', handleFocusBlur); + chrome.runtime.onMessage.addListener(handleRequest); infodiv_ = document.getElementById('info'); statusdiv_ = document.getElementById('status'); From 1cd26661c9b233b7a0b7d76264296e8e8f74028c Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 1 Apr 2015 21:03:59 -0700 Subject: [PATCH 072/377] Various review fixes. --- host-bin/enter-chroot | 2 +- host-ext/crouton/background.js | 4 +-- host-ext/crouton/window.js | 46 ++++++++++++++++++---------------- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/host-bin/enter-chroot b/host-bin/enter-chroot index e279f09e7..7b4d319dc 100755 --- a/host-bin/enter-chroot +++ b/host-bin/enter-chroot @@ -138,7 +138,7 @@ fi # Check to ensure that the XMETHOD requested has been installed if [ -n "$TMPXMETHOD" ]; then - if ! grep -q "^$TMPXMETHOD\(-\|\$\)" "$CHROOTS/$NAME/.crouton-targets"; then + if ! grep -q "^${TMPXMETHOD%%-*}$" "$CHROOTS/$NAME/.crouton-targets"; then error 1 "$CHROOTS/$NAME does not contain XMETHOD '${TMPXMETHOD%%-*}'" fi fi diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index 695ebf94f..b2e5c4000 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -573,7 +573,7 @@ function websocketMessage(evt) { /* Open a new window */ kiwi_win_[display] = new Object(); kiwi_win_[display].id = -1; - kiwi_win_[display].isTab = mode == 't'; + kiwi_win_[display].isTab = (mode == 't'); kiwi_win_[display].window = null; win = windows_.filter(function(x){return x.display == display})[0]; @@ -643,7 +643,7 @@ function websocketClose() { checkUpdate(false); } -/* Called when window/tab in focus changes: feeback to the extension so the +/* Called when window/tab in focus changes: feedback to the extension so the * clipboard can be transfered. */ function onFocusChanged(id, isTab) { var disps = Object.keys(kiwi_win_); diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index 3a129d57c..ca8021906 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -15,7 +15,7 @@ var errordiv_ = null; /* error div */ var debug_ = 0; /* Debuging level, passed to NaCl module */ var hidpi_ = 0; /* HiDPI mode */ -var display_ = null; /* Display number to use */ +var display_ = -1; /* Display number to use */ var title_ = "crouton"; /* window title */ var connected_ = false; var closing_ = false; /* Disconnected, and waiting for the window to close */ @@ -268,11 +268,27 @@ function handleFocusBlur(evt) { KiwiModule_.focus(); } -/* Start in full screen */ -if (location.search.search(/[&?]mode=f(&|$)/i) != -1) { - chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {state: "fullscreen"}, function(win) {}) -} +/* Parse arguments */ +(function() { + var args = location.search.substring(1).split('&'); + for (var i = 0; i < args.length; i++) { + var keyval = args[i].split('='); + if (keyval[0] == "display") { + display_ = keyval[1]; + } else if (keyval[0] == "title") { + title_ = decodeURIComponent(keyval[1]); + } else if (keyval[0] == "debug") { + debug_ = keyval[1]; + } else if (keyval[0] == "hidpi") { + hidpi_ = keyval[1]; + } else if (keyval[0] == "mode") { + if (keyval[1] == 'f') { + chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, + {state: "fullscreen"}); + } + } + } +}()); document.addEventListener('DOMContentLoaded', function() { listener_ = document.getElementById('listener'); @@ -298,22 +314,8 @@ document.addEventListener('DOMContentLoaded', function() { warningdiv_.style.display = 'block'; errordiv_.style.display = 'block'; - /* Parse arguments */ - var args = location.search.substring(1).split('&'); - display_ = -1; - debug_ = 0; - for (var i = 0; i < args.length; i++) { - var keyval = args[i].split('=') - if (keyval[0] == "display") - display_ = keyval[1]; - else if (keyval[0] == "title") - title_ = decodeURIComponent(keyval[1]); - else if (keyval[0] == "debug") - setDebug(keyval[1]); - else if (keyval[0] == "hidpi") - setHiDPI(keyval[1]); - } - + setDebug(debug_); + setHiDPI(hidpi_); setTitle(title_); registerWindow(true); From f95420f8a1a93f926f4bdd60da8921d2b5a7ff5f Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 1 Apr 2015 21:28:49 -0700 Subject: [PATCH 073/377] Enable javascript strict mode --- host-ext/crouton/background.js | 78 +++++++++++++++++----------------- host-ext/crouton/popup.js | 2 + host-ext/crouton/window.js | 15 ++++--- 3 files changed, 49 insertions(+), 46 deletions(-) diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index b2e5c4000..ea13a04d0 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -1,6 +1,7 @@ // Copyright (c) 2014 The crouton Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +'use strict'; /* Constants */ var URL = "ws://localhost:30001/"; @@ -12,11 +13,11 @@ var WINDOW_UPDATE_INTERVAL = 15; /* Update window list every 15" at most */ /* String to copy to the clipboard if it should be empty */ var DUMMY_EMPTYSTRING = "%"; -LogLevel = { +var LogLevel = Object.freeze({ ERROR : "error", - INFO : "info", + INFO : "info", DEBUG : "debug" -} +}); /* Global variables */ var clipboardholder_; /* textarea used to hold clipboard content */ @@ -110,7 +111,7 @@ function updateWindowList(force) { /* Called from kiwi (window.js), so we can directly access each window */ function registerKiwi(displaynum, window) { - display = ":" + displaynum + var display = ":" + displaynum; if (kiwi_win_[display] && kiwi_win_[display].id >= 0) { kiwi_win_[display].window = window; } @@ -128,14 +129,13 @@ function closePopup() { function refreshUI() { updateWindowList(false); + var icon = "disconnected"; if (error_) - icon = "error" + icon = "error"; else if (!enabled_) - icon = "disabled" + icon = "disabled"; else if (active_) icon = "connected"; - else - icon = "disconnected"; chrome.browserAction.setIcon( {path: {19: icon + '-19.png', 38: icon + '-38.png'}} @@ -148,10 +148,10 @@ function refreshUI() { /* Make sure page is ready */ if (view.document.readyState === "complete") { /* Update "help" link */ - helplink = view.document.getElementById("help"); + var helplink = view.document.getElementById("help"); helplink.onclick = showHelp; /* Update enable/disable link. */ - enablelink = view.document.getElementById("enable"); + var enablelink = view.document.getElementById("enable"); if (enabled_) { enablelink.textContent = "Disable"; enablelink.onclick = function() { @@ -175,7 +175,7 @@ function refreshUI() { } /* Update debug mode according to checkbox state. */ - debugcheck = view.document.getElementById("debugcheck"); + var debugcheck = view.document.getElementById("debugcheck"); debugcheck.onclick = function() { debug_ = debugcheck.checked; refreshUI(); @@ -195,7 +195,7 @@ function refreshUI() { debugcheck.checked = debug_; /* Update hidpi mode according to checkbox state. */ - hidpicheck = view.document.getElementById("hidpicheck"); + var hidpicheck = view.document.getElementById("hidpicheck"); if (window.devicePixelRatio > 1) { hidpicheck.onclick = function() { hidpi_ = hidpicheck.checked; @@ -224,7 +224,7 @@ function refreshUI() { /* Update window table */ /* FIXME: Improve UI */ - windowlist = view.document.getElementById("windowlist"); + var windowlist = view.document.getElementById("windowlist"); while (windowlist.rows.length > 0) { windowlist.deleteRow(0); @@ -247,7 +247,7 @@ function refreshUI() { } /* Update logger table */ - loggertable = view.document.getElementById("logger"); + var loggertable = view.document.getElementById("logger"); /* FIXME: only update needed rows */ while (loggertable.rows.length > 0) { @@ -255,7 +255,7 @@ function refreshUI() { } /* Only update if "show log" is enabled */ - logcheck = view.document.getElementById("logcheck"); + var logcheck = view.document.getElementById("logcheck"); logcheck.onclick = function() { showlog_ = logcheck.checked; refreshUI(); @@ -263,7 +263,7 @@ function refreshUI() { logcheck.checked = showlog_; if (showlog_) { for (var i = 0; i < logger_.length; i++) { - value = logger_[i]; + var value = logger_[i]; if (value[0] == LogLevel.DEBUG && !debug_) continue; @@ -483,7 +483,7 @@ function websocketMessage(evt) { if (payload.length > 0) { windows_ = payload.split('\n').map( function(x) { - m = x.match(/^([^ *]*)\*? +(.*)$/) + var m = x.match(/^([^ *]*)\*? +(.*)$/); if (!m) return null; @@ -491,12 +491,12 @@ function websocketMessage(evt) { if (m[1] != "cros" && !m[1].match(/^:([0-9]+)$/)) return null; - k = new Object() + var k = new Object(); k.display = m[1]; k.name = m[2]; return k; } - ).filter( function(x) { return !!x; } ) + ).filter( function(x) { return !!x; } ); windows_.forEach(function(k) { var win = kiwi_win_[k.display]; @@ -508,7 +508,7 @@ function websocketMessage(evt) { win.window.setTitle(k.name); } } - }) + }); lastwindowlistupdate_ = new Date().getTime(); websocket_.send("COK"); @@ -516,10 +516,10 @@ function websocketMessage(evt) { refreshUI(); break; case 'X': /* Ask to open a crouton window */ - display = payload - match = display.match(/^:([0-9]+)([- ][^- ]*)*$/) - displaynum = match ? match[1] : null; - mode = null; + var display = payload; + var match = display.match(/^:([0-9]+)([- ][^- ]*)*$/); + var displaynum = match ? match[1] : null; + var mode = null; if (displaynum) { display = ":" + displaynum; mode = match[2].length >= 2 ? match[2].charAt(1) : 'f'; @@ -538,7 +538,7 @@ function websocketMessage(evt) { var winid = kiwi_win_[disps[i]].id; chrome.windows.update(winid, {focused: false}); - minimize = function(win) { + var minimize = function(win) { chrome.windows.update(winid, {state: 'minimized'}); }; chrome.windows.get(winid, function(win) { @@ -550,7 +550,7 @@ function websocketMessage(evt) { } else { minimize(); } - }) + }); } } else if (kiwi_win_[display] && kiwi_win_[display].id >= 0 && (!kiwi_win_[display].window || @@ -576,10 +576,10 @@ function websocketMessage(evt) { kiwi_win_[display].isTab = (mode == 't'); kiwi_win_[display].window = null; - win = windows_.filter(function(x){return x.display == display})[0]; - name = win ? win.name : "crouton in a window"; - create = chrome.windows.create; - data = {}; + var win = windows_.filter(function(x){return x.display == display})[0]; + var name = win ? win.name : "crouton in a window"; + var create = chrome.windows.create; + var data = {}; if (kiwi_win_[display].isTab) { name = win ? win.name : "crouton in a tab"; @@ -647,16 +647,16 @@ function websocketClose() { * clipboard can be transfered. */ function onFocusChanged(id, isTab) { var disps = Object.keys(kiwi_win_); - nextfocus_win_ = "cros"; + var nextfocus_win = "cros"; for (var i = 0; i < disps.length; i++) { if (kiwi_win_[disps[i]].isTab == isTab && kiwi_win_[disps[i]].id == id) { - nextfocus_win_ = disps[i]; + nextfocus_win = disps[i]; break; } } - if (focus_win_ != nextfocus_win_) { - focus_win_ = nextfocus_win_; + if (focus_win_ != nextfocus_win) { + focus_win_ = nextfocus_win; if (active_ && sversion_ >= 2) websocket_.send("Cs" + focus_win_); printLog("Window " + focus_win_ + " focused", LogLevel.DEBUG); @@ -702,10 +702,10 @@ function padstr0(i) { /* Add a message in the log. */ function printLog(str, level) { - date = new Date; - datestr = padstr0(date.getHours()) + ":" + - padstr0(date.getMinutes()) + ":" + - padstr0(date.getSeconds()); + var date = new Date; + var datestr = padstr0(date.getHours()) + ":" + + padstr0(date.getMinutes()) + ":" + + padstr0(date.getSeconds()); if (str.length > 200) str = str.substring(0, 197) + "..."; @@ -748,7 +748,7 @@ chrome.runtime.onInstalled.addListener(function(details) { chrome.runtime.getPlatformInfo(function(platforminfo) { if (platforminfo.os == 'cros') { /* On error: disconnect WebSocket, then log errors */ - onerror = function(msg, url, line) { + var onerror = function(msg, url, line) { if (websocket_) websocket_.close(); error("Uncaught JS error: " + msg, false); diff --git a/host-ext/crouton/popup.js b/host-ext/crouton/popup.js index b3811cd53..4c4f4401a 100644 --- a/host-ext/crouton/popup.js +++ b/host-ext/crouton/popup.js @@ -2,6 +2,8 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +'use strict'; + document.addEventListener('DOMContentLoaded', function() { chrome.extension.getBackgroundPage().refreshUI(); }); diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index ca8021906..12443d37e 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -1,6 +1,7 @@ // Copyright (c) 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +'use strict'; var CLOSE_TIMEOUT = 2; /* Close window x seconds after disconnect */ var DEBUG_LEVEL = 2; /* If debug is enabled, use this level in NaCl */ @@ -187,22 +188,22 @@ function handleMessage(message) { newstate = "fullscreen"; } chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {state: newstate}, function(win) {}) - }) + {state: newstate}, function(win) {}); + }); } else if (type == "state" && payload == "hide") { /* Hide window */ chrome.windows.getCurrent(function(win) { - minimize = function(win) { + var minimize = function(win) { chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, {state: 'minimized'}, function(win) {})} /* To make restore nicer, first exit full screen, then minimize */ if (win.state == "fullscreen") { chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {state: 'maximized'}, minimize) + {state: 'maximized'}, minimize); } else { - minimize() + minimize(); } - }) + }); } else if (type == "resize") { i = payload.indexOf("/"); if (i < 0) return; @@ -319,4 +320,4 @@ document.addEventListener('DOMContentLoaded', function() { setTitle(title_); registerWindow(true); -}) +}); From 4fbc34d669f4d53755f36abf1ed548f5f40542f9 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 1 Apr 2015 21:52:13 -0700 Subject: [PATCH 074/377] Fix race between tab/window creation and registration A bad outcome would result in no titlebar updates. --- host-ext/crouton/background.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host-ext/crouton/background.js b/host-ext/crouton/background.js index ea13a04d0..57c891765 100644 --- a/host-ext/crouton/background.js +++ b/host-ext/crouton/background.js @@ -112,7 +112,7 @@ function updateWindowList(force) { /* Called from kiwi (window.js), so we can directly access each window */ function registerKiwi(displaynum, window) { var display = ":" + displaynum; - if (kiwi_win_[display] && kiwi_win_[display].id >= 0) { + if (kiwi_win_[display] && kiwi_win_[display].id >= -1) { kiwi_win_[display].window = window; } } @@ -669,7 +669,7 @@ function onRemoved(id, isTab) { for (var i = 0; i < disps.length; i++) { if (kiwi_win_[disps[i]].isTab == isTab && kiwi_win_[disps[i]].id == id) { - kiwi_win_[disps[i]].id = -1; + kiwi_win_[disps[i]].id = -2; kiwi_win_[disps[i]].isTab = false; kiwi_win_[disps[i]].window = null; printLog("Window " + disps[i] + " removed", LogLevel.DEBUG); From 67b3ccf4e6f5bee6db86118a760e2b480107de81 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Wed, 1 Apr 2015 21:52:49 -0700 Subject: [PATCH 075/377] Simplify the titlebar. "crouton" is redundant with the icon. The display number is usually unnecessary, and you can always deduce it from the crouton extension popup. Makes the tab title a little bit more useful, although it's still usually taken up by "chrootname/applicationname". --- host-ext/crouton/window.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index 12443d37e..619ee9e3c 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -103,7 +103,7 @@ function setHiDPI(hidpi) { } function setTitle(title) { - document.title = "crouton (" + display_ + "): " + title; + document.title = title; } /* Set status message */ From 018b33b25165e25bf2b326318b09987c77702f11 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 2 Apr 2015 09:45:48 -0700 Subject: [PATCH 076/377] Clean up argument processing --- host-ext/crouton/window.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/host-ext/crouton/window.js b/host-ext/crouton/window.js index 619ee9e3c..15ec7c616 100644 --- a/host-ext/crouton/window.js +++ b/host-ext/crouton/window.js @@ -270,26 +270,23 @@ function handleFocusBlur(evt) { } /* Parse arguments */ -(function() { - var args = location.search.substring(1).split('&'); - for (var i = 0; i < args.length; i++) { - var keyval = args[i].split('='); - if (keyval[0] == "display") { - display_ = keyval[1]; - } else if (keyval[0] == "title") { - title_ = decodeURIComponent(keyval[1]); - } else if (keyval[0] == "debug") { - debug_ = keyval[1]; - } else if (keyval[0] == "hidpi") { - hidpi_ = keyval[1]; - } else if (keyval[0] == "mode") { - if (keyval[1] == 'f') { - chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, - {state: "fullscreen"}); - } +location.search.substring(1).split('&').forEach(function(arg) { + var keyval = arg.split('='); + if (keyval[0] == "display") { + display_ = keyval[1]; + } else if (keyval[0] == "title") { + title_ = decodeURIComponent(keyval[1]); + } else if (keyval[0] == "debug") { + debug_ = keyval[1]; + } else if (keyval[0] == "hidpi") { + hidpi_ = keyval[1]; + } else if (keyval[0] == "mode") { + if (keyval[1] == 'f') { + chrome.windows.update(chrome.windows.WINDOW_ID_CURRENT, + {state: "fullscreen"}); } } -}()); +}); document.addEventListener('DOMContentLoaded', function() { listener_ = document.getElementById('listener'); From d35137abd2b3bc38e72791c371ac5325c23af84a Mon Sep 17 00:00:00 2001 From: David Schneider Date: Thu, 2 Apr 2015 09:53:32 -0700 Subject: [PATCH 077/377] Close tags and provide style type --- host-ext/crouton/window.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/host-ext/crouton/window.html b/host-ext/crouton/window.html index 9d381c227..2ba7def7e 100644 --- a/host-ext/crouton/window.html +++ b/host-ext/crouton/window.html @@ -6,11 +6,11 @@ - - + + Crouton in a tab -