diff --git a/.gitignore b/.gitignore
index cfd03fe10..dfd56e7b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
*.tar.*
.*.swp
.*.tmp
+nacl_sdk/
/crouton*
/tests/run
/releases/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..48c6cc6b0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,9 @@
+##For users who want to report an issue
+Please read [this wiki page]
+(https://github.com/dnschneid/crouton/wiki/Common-issues-and-reporting)
+for instructions on reporting an issue.
+
+##For contributors
+Please read [this
+section](https://github.com/dnschneid/crouton#i-want-to-be-a-contributor)
+of the README and the following relevant sections first.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 38f76de20..7469fffab 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -12,9 +12,12 @@ John Tantalo
Maurice van Kruchten
Micah Lee
Michael Orr
+Mike Kasick
+Mikito Takada
Nevada Romsdahl
Nicolas Boichat
Stephen Barber
Steven Maude
Tobbe Lundberg
+Tony Xue
Yuri Pole
diff --git a/Makefile b/Makefile
index 1261d977c..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
@@ -22,10 +25,16 @@ RELEASE = build/release.sh
VERSION = 1
TARPARAMS ?= -j
+CFLAGS=-g -Wall -Werror -Os
+
croutoncursor_LIBS = -lX11 -lXfixes -lXrender
+croutonfbserver_LIBS = -lX11 -lXdamage -lXext -lXfixes -lXtst
croutonwmtools_LIBS = -lX11
croutonxi2event_LIBS = -lX11 -lXi
+croutonwebsocket_DEPS = src/websocket.h
+croutonfbserver_DEPS = src/websocket.h
+
ifeq ($(wildcard .git/HEAD),)
GITHEAD :=
else
@@ -50,8 +59,17 @@ $(TARGET): $(WRAPPER) $(SCRIPTS) $(GENVERSION) $(GITHEAD) Makefile
$(EXTTARGET): $(EXTSOURCES) Makefile
rm -f $(EXTTARGET) && zip -q --junk-paths $(EXTTARGET) $(EXTSOURCES)
-$(SRCTARGETS): src/$(patsubst crouton%,src/%.c,$@) Makefile
- gcc -g -Wall -Werror $(patsubst crouton%,src/%.c,$@) $($@_LIBS) -o $@
+$(EXTPEXE): $(EXTPEXESOURCES)
+ $(MAKE) -C host-ext/nacl_src
+
+$(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 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)
diff --git a/README.md b/README.md
index 292770f47..78151b12a 100644
--- a/README.md
+++ b/README.md
@@ -47,11 +47,21 @@ to the rest of Chromium OS.
Prerequisites
-------------
You need a device running Chromium OS that has been switched to developer mode.
+
+For instructions on how to do that, go to [this Chromium OS wiki page]
+(http://www.chromium.org/chromium-os/developer-information-for-chrome-os-devices),
+click on your device model and follow the steps in the *Entering Developer Mode*
+section.
+
Note that developer mode, in its default configuration, is *completely
insecure*, so don't expect a password in your chroot to keep anyone from your
data. crouton does support encrypting chroots, but the encryption is only as
strong as the quality of your passphrase. Consider this your warning.
+It's also highly recommended that you install the [crouton extension]
+(https://goo.gl/OVQOEt), which, when combined with the `extension` or `xiwi`
+targets, provides much improved integration with Chromium OS.
+
That's it! Surprised?
@@ -99,7 +109,8 @@ Examples
6. Exit the chroot by logging out of Xfce.
### With encryption!
- 1. Add the `-e` parameter when you run crouton to create an encrypted chroot.
+ 1. Add the `-e` parameter when you run crouton to create an encrypted chroot
+ or encrypt a non-encrypted chroot.
2. You can get some extra protection on your chroot by storing the decryption
key separately from the place the chroot is stored. Use the `-k` parameter
to specify a file or directory to store the keys in (such as a USB drive or
@@ -111,6 +122,15 @@ Examples
2. Run `sh ~/Downloads/crouton -r list` to list the recognized releases and
which distros they belong to.
+### Wasteful rendundancies are wasteful: one clipboard, one browser, one window
+ 1. Install the [crouton extension](https://goo.gl/OVQOEt) into Chromium OS.
+ 2. Add the `extension` or `xiwi` version to your chroot.
+ 3. Try some copy-pasta, or uninstall all your web browsers from the chroot.
+
+*Installing the extension and its target gives you synchronized clipboards, the
+option of using Chromium OS to handle URLs, and allows chroots to create
+graphical sessions as Chromium OS windows.*
+
### I don't always use Linux, but when I do, I use CLI
1. You can save a chunk of space by ditching X and just installing
command-line tools using `-t core` or `-t cli-extra`
@@ -118,6 +138,8 @@ Examples
`sudo enter-chroot`
3. Use the [Crosh Window](https://goo.gl/eczLT) extension to keep Chromium OS
from eating standard keyboard shortcuts.
+ 4. If you installed cli-extra, `startcli` will launch a new VT right into the
+ chroot.
### A new version of crouton came out; my chroot is therefore obsolete and sad
1. Check for updates, download the latest version, and see what's new by
@@ -125,8 +147,6 @@ Examples
to see what those parameters actually do).
2. Exit the chroot and run `sudo sh ~/Downloads/crouton -u -n chrootname`.
It will update all installed targets.
- 3. You can use this with `-e` to encrypt a non-encrypted chroot, but make sure
- you don't interrupt the operation.
### A backup a day keeps the price-gouging data restoration services away
1. `sudo edit-chroot -b chrootname` backs up your chroot to a timestamped
@@ -160,7 +180,8 @@ Examples
3. Include the `-r` parameter if you want to specify for which release to
prepare a bootstrap.
4. You can then create chroots using the tarball by running
- `sudo sh ~/Downloads/crouton -f ~/Downloads/mybootstrap.tar.bz2`
+ `sudo sh ~/Downloads/crouton -f ~/Downloads/mybootstrap.tar.bz2`. Make sure
+ you also specify the target environment with `-t`.
*This is the quickest way to create multiple chroots at once, since you won't
have to determine and download the bootstrap files every time.*
@@ -184,7 +205,7 @@ Tips
* Chroots are cheap! Create multiple ones using `-n`, break them, then make
new, better ones!
* You can change the distro mirror from the default by using `-m`
- * Behind a proxy? `-P` lets you specify one.
+ * Want to use a proxy? `-P` lets you specify one (or disable it).
* A script is installed in your chroot called `brightness`. You can assign
this to keyboard shortcuts to adjust the brightness of the screen (e.g.
`brightness up`) or keyboard (e.g. `brightness k down`).
@@ -198,6 +219,8 @@ Tips
`croutonpowerd -i command and arguments` will automatically stop inhibiting
power management when the command exits.
* Have a Pixel or two or 4.352 million? `-t touch` improves touch support.
+ * Want to share some files and/or folders between ChromeOS and your chroot?
+ Check out the `/etc/crouton/shares` file, or read all about it in the wiki.
* Want more tips? Check the [wiki](https://github.com/dnschneid/crouton/wiki).
@@ -207,13 +230,14 @@ Running another OS in a chroot is a pretty messy technique (although it's hidden
behind very pretty scripts), and these scripts are relatively new, so problems
are not surprising. Check the issue tracker and file a bug if your issue isn't
there. When filing a new bug, include the output of `croutonversion` run from
-inside the chroot (if possible).
+inside the chroot or, if you cannot mount your chroot, include the output
+of `cat /etc/lsb-release` from Crosh.
I want to be a Contributor!
---------------------------
That's great! But before your code can be merged, you'll need to have signed
-the [Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual#sign-electronically).
+the [Individual Contributor License Agreement](https://cla.developers.google.com/clas/new?kind=KIND_INDIVIDUAL&domain=DOMAIN_GOOGLE).
Don't worry, it only takes a minute and you'll definitely get to keep your
firstborn, probably. If you've already signed it for contributing to Chromium
or Chromium OS, you're already done.
@@ -243,7 +267,8 @@ But how?
There's a way For Everyone to help!
* Something broken? File a bug! Bonus points if you try to fix it. It helps if
- you provide the output of `croutonversion` when you submit the bug.
+ you provide the output of `croutonversion` (or the output of
+ `cat /etc/lsb-release` from Crosh) when you submit the bug.
* Want to try and break something? Look through [requests for testing](https://github.com/dnschneid/crouton/issues?labels=needstesting&state=open)
and then do your best to brutally rip the author's work to shreds.
* Look through [open issues](https://github.com/dnschneid/crouton/issues?state=open)
diff --git a/build/wrapper.sh b/build/wrapper.sh
index 502ad1bbe..ea7f11d5c 100644
--- a/build/wrapper.sh
+++ b/build/wrapper.sh
@@ -38,8 +38,8 @@ set -e
VERSION='git'
-# Minimum Chromium OS version is R31 stable
-CROS_MIN_VERS=4731
+# Minimum Chromium OS version is R35 stable
+CROS_MIN_VERS=5712
if [ "$1" = '-x' -a "$#" -le 2 ]; then
# Extract to the specified directory.
@@ -62,6 +62,33 @@ if [ -z "$TRAP" ]; then
exit
fi
+# See if we want to just run a script from the bundle
+if [ "$1" = '-X' ]; then
+ script="$SCRIPTDIR/$2"
+ if [ ! -f "$script" ]; then
+ cd "$SCRIPTDIR"
+ echo "USAGE: ${0##*/} -X DIR/SCRIPT [ARGS]
+Runs a script directly from the bundle. Valid DIR/SCRIPT combos:" 1>&2
+ ls chroot-bin/* host-bin/* 1>&2
+ if [ -n "$2" ]; then
+ echo 1>&2
+ echo "Invalid script '$2'" 1>&2
+ fi
+ exit 2
+ fi
+ shift 2
+ # If this script was called with '-x' or '-v', pass that on
+ SETOPTIONS="-e"
+ if set -o | grep -q '^xtrace.*on$'; then
+ SETOPTIONS="$SETOPTIONS -x"
+ fi
+ if set -o | grep -q '^verbose.*on$'; then
+ SETOPTIONS="$SETOPTIONS -v"
+ fi
+ sh $SETOPTIONS "$script" "$@"
+ exit "$?"
+fi
+
# Execute the main script inline. It will use SCRIPTDIR to find what it needs.
. "$SCRIPTDIR/installer/main.sh"
diff --git a/chroot-bin/crouton-noroot b/chroot-bin/crouton-noroot
new file mode 100755
index 000000000..08b94fb0e
--- /dev/null
+++ b/chroot-bin/crouton-noroot
@@ -0,0 +1,32 @@
+#!/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.
+
+# Wrapper for scripts that shouldn't be launched as root.
+# Symlink to launch the application with the same name in /usr/bin/
+# Launch directly with a parameter to launch that executable
+# Launch directly with a blank or - first parameter and a word to just check and
+# exit with an exit code, printing out the second parameter as the app name.
+
+APPLICATION="${0##*/}"
+if [ "$APPLICATION" = 'crouton-noroot' ]; then
+ if [ -z "$1" -o "$1" = '-' -o "$1" = '--' ]; then
+ APPLICATION=''
+ else
+ APPLICATION="$1"
+ shift
+ fi
+else
+ APPLICATION="/usr/bin/$APPLICATION"
+fi
+
+if [ "$USER" = root -o "$UID" = 0 ]; then
+ app="${APPLICATION:-"$2"}"
+ echo "Do not launch ${app##*/} as root inside the chroot." 1>&2
+ exit 2
+elif [ -z "$APPLICATION" ]; then
+ exit 0
+fi
+
+exec "$APPLICATION" "$@"
diff --git a/chroot-bin/croutonclip b/chroot-bin/croutonclip
index 4dfa38b32..310419ab1 100755
--- a/chroot-bin/croutonclip
+++ b/chroot-bin/croutonclip
@@ -10,36 +10,18 @@ VERBOSE=''
. "`dirname "$0"`/../installer/functions"
-PIPEDIR='/tmp/crouton-ext'
-PIPEIN="$PIPEDIR/in"
-PIPEOUT="$PIPEDIR/out"
-PIPELOCK="$PIPEDIR/lock"
-
-# Write a command to croutonwebsocket, and read back response
-websocketcommand() {
- # Check that $PIPEDIR and the FIFO pipes exist
- if ! [ -d "$PIPEDIR" -a -p "$PIPEIN" -a -p "$PIPEOUT" ]; then
- echo "EError $PIPEIN or $PIPEOUT are not pipes."
- exit 0
- fi
-
- (
- flock 5
- cat > "$PIPEIN"
- cat "$PIPEOUT"
- ) 5>"$PIPELOCK"
-}
-
# rundisplay :X cmd ...
-# Run a command on the specified display (uses host-x11 on :0)
+# Run a command on the specified display
rundisplay() {
local disp="$1"
shift
- if [ "$disp" = ":0" ]; then
- host-x11 "$@"
- else
+ (
+ # If display is :0, setup XAUTHORITY
+ if [ "$disp" = ":0" ]; then
+ eval "`host-x11`" 2>/dev/null
+ fi
DISPLAY="$disp" "$@"
- fi
+ )
}
copyclip() {
@@ -60,7 +42,7 @@ copyclip() {
# Copy clipboard content from the current display
{
- if [ "$current" = 'aura' ]; then
+ if [ "$current" = 'cros' ]; then
echo -n 'R' | websocketcommand
else
# Check if display is still running
@@ -81,7 +63,7 @@ copyclip() {
fi
# Paste clipboard content to the next display
- if [ "$next" = 'aura' ]; then
+ if [ "$next" = 'cros' ]; then
STATUS="`(echo -n 'W'; cat) | websocketcommand`"
if [ "$STATUS" != 'WOK' ]; then
# Write failed, skip Chromium OS (do not update $current)
@@ -138,19 +120,16 @@ waitwebsocket() {
# Assume current display is Chromium OS: avoid race as we may not be able to
# detect the first VT/window change.
-current='aura'
-
-# Only let one instance *really* run at a time
-PIDFILE='/tmp/crouton-lock/clip'
+current='cros'
-mkdir -m 775 -p /tmp/crouton-lock
-exec 3>>"$PIDFILE"
+mkdir -m 775 -p "$CROUTONLOCKDIR"
+exec 3>>"$CROUTONLOCKDIR/clip"
if ! flock -n 3; then
echo "Another instance of croutonclip running, waiting..."
flock 3
fi
-addtrap "echo -n > '$PIDFILE' 2>/dev/null"
+addtrap "echo -n > '$CROUTONLOCKDIR/clip' 2>/dev/null"
(
# This subshell handles USR1 signals from croutoncycle.
@@ -172,7 +151,7 @@ addtrap "echo -n > '$PIDFILE' 2>/dev/null"
trap "echo 'USR1'" USR1
# Set the PID of this subshell after the trap is in place
- sh -c 'echo -n "$PPID"' > "$PIDFILE"
+ sh -c 'echo -n "$PPID"' > "$CROUTONLOCKDIR/clip"
# Force an update when started.
echo "Force"
diff --git a/chroot-bin/croutoncycle b/chroot-bin/croutoncycle
index 7e6c6174a..50a0576bf 100755
--- a/chroot-bin/croutoncycle
+++ b/chroot-bin/croutoncycle
@@ -3,6 +3,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+. "`dirname "$0"`/../installer/functions"
+
USAGE="${0##*/} next|prev|cros|list|#
Cycles through running graphical chroots.
next: switch to the next display
@@ -15,9 +17,20 @@ Cycles through running graphical chroots.
# Undocumented:
# display: return display associated with current window
# (used from croutonclip):
-# - aura: Chromium OS
-# - 0: Chromium OS X11 display (non-aura window)
-# - 1-9: chroot displays
+# - cros: Chromium OS
+# - :0: Chromium OS X11 display (non-aura window)
+# - :1-9: chroot displays
+# s: informs of a Chromium OS window change (called from extension):
+# - cros: any Chromium OS window
+# - :1-9: kiwi window: X11 display number
+# force [command]: Force switching display, even if it does not appear
+# to be necessary.
+
+force=''
+if [ "${1#[Ff]}" != "$1" ]; then
+ force='y'
+ shift
+fi
case "$1" in
[Ll]*) cmd='l';;
@@ -25,9 +38,10 @@ case "$1" in
[Cc]*) cmd='0';;
[Pp]*) cmd='p';;
[Nn]*) cmd='n';;
-:*) cmd=":$((${1#:}))";;
+[Ss]*) cmd='s' disp="${1#s}";;
+:*) cmd="${1%%.*}"; cmd=":$((${cmd#:}))";;
[0-9]*) cmd="$(($1))";;
-*) echo "$USAGE" 1>&2; exit 2;;
+*) error 2 "$USAGE";;
esac
# Returns the chroot name of an X11 display specified in $1 on stdout
@@ -43,44 +57,83 @@ getname() {
}
# Only let one instance run at a time to avoid nasty race conditions
-mkdir -m 775 -p /tmp/crouton-lock
-exec 3>/tmp/crouton-lock/cycle
+mkdir -m 775 -p "$CROUTONLOCKDIR"
+exec 3>"$CROUTONLOCKDIR/cycle"
flock 3
+# set display command from extension
+if [ "$cmd" = 's' ]; then
+ echo "$disp" > "$CRIATDISPLAY"
+ if [ -s "$CROUTONLOCKDIR/clip" ]; then
+ kill -USR1 "`cat "$CROUTONLOCKDIR/clip"`" || true
+ fi
+ exit 0
+fi
+
# Ensure environment sanity
export XAUTHORITY=''
+# Set to y if there is any xiwi instance running
+xiwiactive=''
+
# Prepare display list for easier looping
displist=''
for disp in /tmp/.X*-lock; do
disp="${disp#*X}"
disp=":${disp%-lock}"
- # Only add VT-based chroots here
+ # Only add VT-based and xiwi-based chroots here (that excludes Xephyr)
if [ "$disp" = ':0' ]; then
continue
elif DISPLAY="$disp" xprop -root 'XFree86_VT' 2>/dev/null \
| grep -q 'INTEGER'; then
displist="$displist $disp"
+ elif DISPLAY="$disp" xprop -root 'CROUTON_XMETHOD' 2>/dev/null \
+ | grep -q '= "xiwi'; then
+ displist="$displist $disp"
+ xiwiactive='y'
fi
done
-# List windows on :0. Includes aura
-winlist="`host-x11 croutonwmtools list nim | sort | awk '{ printf $NF " " }'`"
+
+# 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 -r 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'`"
+fi
# Combine the two
fulllist="$winlist$displist"
fulllist="${fulllist% }"
-# Figure out the current display number
-tty="`cat '/sys/class/tty/tty0/active'`"
-if [ "$tty" = 'tty1' ]; then
- # Either in Chromium OS, xephyr chroot, or window. Active window is starred.
+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
if [ "${disp%"*"}" != "$disp" ]; then
curdisp="$disp"
+ if [ -n "$xiwiactive" -a "${disp%"*"}" = "$aurawin" -a \
+ -s "$CRIATDISPLAY" ]; then
+ kiwidisp="`cat $CRIATDISPLAY`"
+ if [ "${kiwidisp#:[0-9]}" != "$kiwidisp" ]; then
+ curdisp="$kiwidisp"
+ fi
+ fi
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
@@ -90,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
@@ -99,8 +160,15 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then
chromiumos="`awk -F= '/_RELEASE_NAME=/{print $2}' \
'/var/host/lsb-release'`"
fi
- host-x11 croutonwmtools list nim | sort | while read -r line; do
+ (
+ if [ -z "$freonowner" ]; then
+ host-x11 croutonwmtools list nim
+ else
+ echo "aura_root_0 aura*"
+ fi
+ ) | sort | while read -r line; do
disp="${line##* }"
+ display="${disp%"*"}"
line="${line% *}"
number='0'
active=' '
@@ -110,6 +178,7 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then
if [ "${number#[0-9]}" = "$number" ]; then
number='0'
else
+ display=":$number"
line="`getname "$number"`"
fi
fi
@@ -117,7 +186,7 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then
active='*'
if [ "$cmd" = 'd' ]; then
if [ "$line" = 'aura_root_0' ]; then
- echo 'aura'
+ echo 'cros'
else
echo ":$number"
fi
@@ -127,13 +196,14 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then
fi
if [ "$line" = 'aura_root_0' ]; then
line="$chromiumos"
+ display="cros"
+ window=''
fi
if [ "$cmd" = 'l' ]; then
- echo "$number$active $line"
+ echo "$display$active $line"
fi
done
for disp in $displist; do
- number="${disp#:}"
active=' '
if [ "$disp" = "$curdisp" ]; then
active='*'
@@ -144,7 +214,7 @@ if [ "$cmd" = 'l' -o "$cmd" = 'd' ]; then
fi
if [ "$cmd" = 'l' ]; then
- echo -n "$number$active "
+ echo -n "$disp$active "
getname "$disp"
fi
done
@@ -155,6 +225,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=''
@@ -166,8 +242,7 @@ if [ -n "${cmd#[pn]}" ]; then
i="$((i+1))"
done
if [ -z "$destdisp" ]; then
- echo "Display number out of range." 1>&2
- exit 2
+ error 2 "Display number out of range."
fi
fi
elif [ "$cmd" = 'p' ]; then
@@ -192,17 +267,16 @@ elif [ "$cmd" = 'n' ]; then
destdisp="${fulllist%% *}"
fi
else
- echo "Bad command $cmd." 1>&2
- exit 3
+ error 3 "Bad command $cmd."
fi
# No-op on no-op
-if [ "$destdisp" = "$curdisp" ]; then
+if [ "$destdisp" = "$curdisp" -a -z "$force" ]; then
exit 0
fi
# Make sure tap-to-click is enabled
-if 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
@@ -210,26 +284,67 @@ fi
# Determine if the target display is on a VT
if [ "${destdisp#:}" = "$destdisp" ]; then
- eval "`host-x11`"
- # Raise the right window after chvting, so that it can update
- if [ "$tty" != 'tty1' ]; then
- sudo -n chvt 1
- sleep .1
+ if [ -z "$freonowner" ]; then
+ eval "`host-x11`"
+ # Raise the right window after chvting, so that it can update
+ if [ "$tty" != 'tty1' ]; then
+ sudo -n chvt 1
+ sleep .1
+ fi
+ croutonwmtools raise "${destdisp%"*"}"
+ elif [ "${freonowner:-0}" != 0 ]; then
+ kill -USR1 "$freonowner"
+ fi
+
+ if [ -n "$xiwiactive" -a "${destdisp%"*"}" = "$aurawin" ]; then
+ STATUS="`echo -n "Xcros" | websocketcommand`"
+ if [ "$STATUS" != 'XOK' ]; then
+ error 1 "${STATUS#?}"
+ fi
fi
- croutonwmtools raise "${destdisp%"*"}"
else
export DISPLAY="$destdisp"
- dest="`xprop -root 'XFree86_VT' 2>/dev/null`"
- dest="${dest##* }"
- if [ "${dest#[1-9]}" = "$dest" ]; then
- dest='1'
+ 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
+ elif [ "${freonowner:-0}" != 0 ]; then
+ kill -USR1 "$freonowner"
+ fi
+ if [ -z "$freonowner" ]; then
+ host-x11 croutonwmtools raise "$aurawin"
+ fi
+ STATUS="`echo -n "X${destdisp} ${xmethod#*-}" | websocketcommand`"
+ if [ "$STATUS" != 'XOK' ]; then
+ error 1 "${STATUS#?}"
+ fi
+ elif [ -z "$freonowner" ]; then
+ dest="`xprop -root 'XFree86_VT' 2>/dev/null`"
+ dest="${dest##* }"
+ if [ "${dest#[1-9]}" = "$dest" ]; then
+ dest='1'
+ fi
+ # When the destination we are changing to is using fbdev driver in X, we
+ # need first a change to vt 2, else only the session switches and the
+ # 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
- sudo -n chvt "$dest"
fi
-CROUTONPIDFILE='/tmp/crouton-lock/clip'
-if [ -s "$CROUTONPIDFILE" ]; then
- kill -USR1 "`cat "$CROUTONPIDFILE"`" || true
+if [ -s "$CROUTONLOCKDIR/clip" ]; then
+ kill -USR1 "`cat "$CROUTONLOCKDIR/clip"`" || true
fi
# Wait a flip and then refresh the display for good measure
diff --git a/chroot-bin/croutonfindnacl b/chroot-bin/croutonfindnacl
new file mode 100755
index 000000000..80d54ea24
--- /dev/null
+++ b/chroot-bin/croutonfindnacl
@@ -0,0 +1,79 @@
+#!/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.
+
+# croutonfindnacl address signature ["pids"]
+#
+# This script is used by croutonfbserver to find the nacl_helper process it is
+# connected to, and, in particular, the file descriptor corresponding to the shm
+# memory that the nacl_helper process shares with Chromium.
+#
+# - address: NaCl-space address of the shared memory (hexadecimal). We assume
+# that the NaCl/hardware memory mapping conserves the address,
+# possibly with a prefix in the MSBs.
+# - signature: random 8 byte pattern (hexadecimal, machine byte order) that is
+# written at the beginning of the shared buffer by the NaCl
+# application. The first 8 bytes of each candidate buffer is read,
+# guaranteeing that the correct buffer is returned.
+# - pids: (normally ununsed, defaults to all processes named "nacl_helper")
+# Space-separated list of PIDs to scan for.
+#
+# On success, prints "pid:filename" and exits with code 0.
+# On error (shm not found, invalid parameters), exits with code >0.
+
+set -e
+
+VERBOSE=
+
+if [ "$#" -lt 2 -o "$#" -gt 3 ]; then
+ echo "Invalid parameters"
+ exit 2
+fi
+
+ADDRESS="$1"
+PATTERN="$2"
+PIDS="${3:-"`pgrep nacl_helper`"}"
+
+MATCH=""
+
+# Iterate over all NaCl helper processes
+for pid in $PIDS; do
+ [ -n "$VERBOSE" ] && echo "pid:$pid" 1>&2
+ # Find candidate mappings
+ file="`awk '$1 ~ /^[0-9a-f]*'"$ADDRESS"'-/ && $2 == "rw-s" \
+ && $6 ~ /\/shm\/\.(com\.google\.Chrome|org\.chromium\.Chromium)/ \
+ { print $6 }
+ ' "/proc/$pid/maps"`"
+ [ -n "$VERBOSE" ] && echo "file:$file" 1>&2
+ if [ -z "$file" ]; then
+ continue
+ fi
+
+ # Iterate over mappings, and check signature
+ for fd in "/proc/$pid/fd"/*; do
+ link="`readlink -- "$fd"`"
+ link="${link% (deleted)}"
+ if [ "$link" = "$file" ]; then
+ # Check if signature matches
+ pattern="`od -An -t x1 -N8 "$fd" | tr -d ' '`"
+ [ -n "$VERBOSE" ] && echo "FD:$fd ($pattern)" 1>&2
+ if [ "$pattern" = "$PATTERN" ]; then
+ # Second match? This should never happen
+ if [ -n "$MATCH" ]; then
+ echo -n "-1:ambiguous"
+ exit 1
+ fi
+ MATCH="$pid:$fd"
+ fi
+ fi
+ done
+done
+
+if [ -n "$MATCH" ]; then
+ echo -n "$MATCH"
+ exit 0
+else
+ echo -n "-1:no match"
+ exit 1
+fi
diff --git a/chroot-bin/croutonnotify b/chroot-bin/croutonnotify
new file mode 100755
index 000000000..f86d31bcd
--- /dev/null
+++ b/chroot-bin/croutonnotify
@@ -0,0 +1,104 @@
+#!/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.
+
+USAGE="${0##*/} -j
+${0##*/} -t title [-m message] [-d] [-i icon] [-I id]
+Raises a notification in Chromium OS (requires crouton extension).
+
+When -j is specified, reads JSON data from stdin, in the format required
+by chrome.notifications API, with 2 additional fields, \"crouton_id\" and
+\"crouton_display\", corresponding respectively to the notification id, and the
+display to switch to when the notification is clicked (croutoncycle parameter).
+
+Otherwise, constructs a \"basic\" notification with the requested fields.
+
+Options:
+ -j Read JSON data from stdin (see example below)
+ -t Title to display (chrome.notifications field: \"title\")
+ -m Message to display (chrome.notifications field: \"message\")
+ -d Switch to display in environment variable DISPLAY ($DISPLAY) when
+ the notification is clicked. Default: Do not switch display.
+ -i Small icon to display on the left of the notification
+ (chrome.notifications field: \"iconUrl\")
+ -I ID to pass to chrome.notifications.create: only the last
+ notification with a given ID is shown.
+ Default: Display a new notification.
+
+Example JSON data:
+"'{
+ "type": "basic",
+ "title": "Primary Title",
+ "message": "Primary message to display",
+ "crouton_display": ":1",
+ "iconUrl": "data:image/png;base64,"
+}'
+
+. "$(dirname "$0")/../installer/functions"
+
+SWITCHDISPLAY=""
+MESSAGE=""
+TITLE=""
+ID=""
+ICON=""
+JSON=""
+
+# Process arguments
+while getopts 'di:I:jm:t:' f; do
+ case "$f" in
+ d) SWITCHDISPLAY="$DISPLAY";;
+ i) ICON="$OPTARG";;
+ I) ID="$OPTARG";;
+ j) JSON="y";;
+ m) MESSAGE="$OPTARG";;
+ t) TITLE="$OPTARG";;
+ \?) error 2 "$USAGE";;
+ esac
+done
+
+# No extra parameters, -j precludes other parameters, and at least title
+# must be specified (or -j)
+if [ "$#" != "$((OPTIND-1))" ] ||
+ [ "$JSON" = 'y' -a -n "$SWITCHDISPLAY$ICON$ID$MESSAGE$TITLE" ] ||
+ [ -z "$JSON$TITLE" ]; then
+ error 2 "$USAGE"
+fi
+
+if [ -n "$ICON" ] && [ ! -r "$ICON" -o ! -f "$ICON" ]; then
+ error 2 "Cannot open $ICON."
+fi
+
+# Escape json string (backslash and double quotes)
+json_escape() {
+ echo -n "$1" | sed -e 's/\\/\\u005C/g;s/"/\\u0022/g;2~1s/^/\\u000A/;' \
+ | tr -d '\n'
+}
+
+STATUS="$({
+ echo -n "N"
+ if [ -z "$JSON" ]; then
+ echo -n '{
+ "type": "basic",
+ "title": "'"$(json_escape "$TITLE")"'",
+ "message": "'"$(json_escape "$MESSAGE")"'",
+ "crouton_display": "'"$(json_escape "$SWITCHDISPLAY")"'",
+ "crouton_id": "'"$(json_escape "$ID")"'"'
+ if [ -n "$ICON" ]; then
+ ext="${ICON##*.}"
+ if grep -Iq '