Last active
December 24, 2015 01:39
-
-
Save kiko/6724792 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/chroot-bin/croutonclip b/chroot-bin/croutonclip | |
index a280419..226f26d 100755 | |
--- a/chroot-bin/croutonclip | |
+++ b/chroot-bin/croutonclip | |
@@ -5,6 +5,7 @@ | |
# | |
# Synchronizes clipboard between X displays, making use of crouton's WebSocket | |
# server and Chromium extension to synchronize the clipboard with Chromium OS | |
+# Define XMETHOD variable (x11, xephyr or cros) in prior to run this script. | |
VERBOSE='' | |
@@ -47,7 +48,7 @@ copyclip() { | |
# Copy clipboard content from the current display | |
{ | |
- if [ "$current" = ':0' ]; then | |
+ if [ "$current" = 'aura' ]; then | |
echo -n 'R' | websocketcommand | |
else | |
# Check if display is still running | |
@@ -68,7 +69,7 @@ copyclip() { | |
fi | |
# Paste clipboard content to the next display | |
- if [ "$next" = ':0' ]; then | |
+ if [ "$next" = 'aura' ]; then | |
STATUS="`(echo -n 'W'; cat) | websocketcommand`" | |
if [ "$STATUS" != 'WOK' ]; then | |
# Write failed, skip Chromium OS (do not update $current) | |
@@ -125,20 +126,19 @@ waitwebsocket() { | |
croutonwebsocket & | |
addtrap "kill $! 2>/dev/null" | |
-xmethod="`readlink -f '/etc/X11/xinit/xserverrc'`" | |
-xmethod="${xmethod##*-}" | |
- | |
# For both x11/xephyr, the code works as follow: | |
# - A command outputs one line per event (window/tty change). | |
# - In a second subshell, read these events, one by one, and transfer the | |
# clipboard content. | |
# This makes sure we do not miss any events and that we copy the clipboard | |
# around in the right sequence. | |
+# For cros, guest OS shares X display with Chrome OS (:0). | |
-if [ "$xmethod" = 'xephyr' ]; then | |
+case "$XMETHOD" in | |
+'xephyr' | 'cros') | |
# Assume current display is Chromium OS, as the awk script does not detect | |
# the current window | |
- current=':0' | |
+ current='aura' | |
# Wait for ratpoison to come up | |
while ! host-x11 xprop -root _NET_WM_NAME | grep -q 'ratpoison'; do | |
@@ -175,7 +175,9 @@ if [ "$xmethod" = 'xephyr' ]; then | |
# Translate window id to display number | |
id="${line%,}" | |
if [ "$id" = "$aura" ]; then | |
- display=":0" | |
+ display="aura" | |
+ elif [ "$XMETHOD" = 'cros' ]; then | |
+ display=':0' | |
else | |
# This relies on WM_NAME looking like "Xephyr on :1.0 (...)" | |
display="`host-x11 xprop -format WM_NAME 8s '\t$0' \ | |
@@ -185,8 +187,8 @@ if [ "$xmethod" = 'xephyr' ]; then | |
copyclip "$display" | |
done | |
- } | |
-elif [ "$xmethod" = 'x11' ]; then | |
+ };; | |
+'x11') | |
# No need to set $current: | |
# croutonvtmonitor outputs the current tty right after it is started | |
@@ -204,7 +206,7 @@ elif [ "$xmethod" = 'x11' ]; then | |
while read tty; do | |
display='' | |
if [ "$tty" = "tty1" ]; then | |
- display=":0" | |
+ display="aura" | |
else | |
# Find which process owns the tty | |
process="`ps -o pid= -t "$tty" | sed 's/ //g'`" | |
@@ -222,9 +224,8 @@ elif [ "$xmethod" = 'x11' ]; then | |
copyclip "$display" | |
done | |
- } | |
-else | |
- echo "Invalid xmethod='$xmethod'." >&2 | |
-fi | |
- | |
+ };; | |
+*) | |
+ echo "Invalid xmethod='$XMETHOD'." >&2;; | |
+esac | |
exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh -e | |
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. | |
# Use of this source code is governed by a BSD-style license that can be | |
# found in the LICENSE file. | |
# | |
# Synchronizes clipboard between X displays, making use of crouton's WebSocket | |
# server and Chromium extension to synchronize the clipboard with Chromium OS | |
# Define XMETHOD variable (x11, xephyr or cros) in prior to run this script. | |
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" | |
} | |
current='' | |
copyclip() { | |
next="$1" | |
# Do not copy if next is empty (display cannot be detected), or | |
# if current == next. Also set current=$next if $current is empty | |
if [ -z "$next" -o "${current:="$next"}" = "$next" ]; then | |
return 0 | |
fi | |
if [ -n "$VERBOSE" ]; then | |
echo ">>Current: $current>>" | |
fi | |
# Copy clipboard content from the current display | |
{ | |
if [ "$current" = 'aura' ]; then | |
echo -n 'R' | websocketcommand | |
else | |
# Check if display is still running | |
if DISPLAY="$current" xdpyinfo >/dev/null 2>&1; then | |
echo -n 'R' | |
DISPLAY="$current" xclip -o -sel clip | |
else | |
echo -n "EUnable to open display '$current'." | |
fi | |
fi | |
} | ( | |
STATUS="`head -c 1`" | |
if [ "$STATUS" != 'R' ]; then | |
echo -n "croutonwebsocket error: " >&2 | |
cat >&2 | |
# Stop here (the clipboard content is lost in this case) | |
exit 0 | |
fi | |
# Paste clipboard content to the next display | |
if [ "$next" = 'aura' ]; then | |
STATUS="`(echo -n 'W'; cat) | websocketcommand`" | |
if [ "$STATUS" != 'WOK' ]; then | |
# Write failed, skip Chromium OS (do not update $current) | |
echo -n "croutonwebsocket error: $STATUS" >&2 | |
exit 1 | |
fi | |
else | |
# Do not override content if it "looks" the same | |
# (we might have rich text or other content in the clipboard) | |
cliptmp="`mktemp "croutonclip.XXX" --tmpdir=/tmp`" | |
trap "rm -f '$cliptmp'" 0 | |
cat > $cliptmp | |
if ! DISPLAY="$next" xclip -o -sel clip | diff -q - "$cliptmp" > /dev/null; then | |
cat "$cliptmp" | DISPLAY="$next" xclip -i -sel clip | |
fi | |
fi | |
) && current="$next" | |
if [ -n "$VERBOSE" ]; then | |
echo "<<Next: $current<<" | |
fi | |
} | |
# Wait for the websocket server to get connected to the extension | |
# Timeout after 10 seconds (twice crouton extension retry period) | |
waitwebsocket() { | |
timeout=10 | |
while [ $timeout -gt 0 ]; do | |
if [ -n "$VERBOSE" ]; then | |
echo "Ping..." | |
fi | |
# Prepare and send a ping message | |
MSG="PING$$$timeout" | |
STATUS="`echo -n "$MSG" | websocketcommand`" | |
if [ "$STATUS" = "$MSG" ]; then | |
if [ -n "$VERBOSE" ]; then | |
echo "OK!" | |
fi | |
return 0 | |
fi | |
if [ -n "$VERBOSE" ]; then | |
echo "$STATUS" | |
fi | |
sleep 1 | |
timeout=$(($timeout-1)) | |
done | |
echo "Timeout waiting for extension to connect." >&2 | |
} | |
croutonwebsocket & | |
addtrap "kill $! 2>/dev/null" | |
# For both x11/xephyr, the code works as follow: | |
# - A command outputs one line per event (window/tty change). | |
# - In a second subshell, read these events, one by one, and transfer the | |
# clipboard content. | |
# This makes sure we do not miss any events and that we copy the clipboard | |
# around in the right sequence. | |
# For cros, guest OS shares X display with Chrome OS (:0). | |
case "$XMETHOD" in | |
'xephyr' | 'cros') | |
# Assume current display is Chromium OS, as the awk script does not detect | |
# the current window | |
current='aura' | |
# Wait for ratpoison to come up | |
while ! host-x11 xprop -root _NET_WM_NAME | grep -q 'ratpoison'; do | |
sleep .1 | |
done 2>&- | |
# Get the aura root window number (hex) | |
aura="`host-x11 xwininfo -root -children | mawk '/aura_root/ {print $1}'`" | |
# Detect window change using MapNotify events that do not have the | |
# override-redirect flag ("override NO" in xev events) | |
{ | |
host-x11 xev -root & | |
cpid=$! | |
addtrap "kill $cpid 2>/dev/null" | |
if ! wait $cpid; then | |
echo "croutonclip: xev error ($?)" | |
fi | |
} | mawk -W interactive ' | |
m { | |
if ($6 == "NO") { | |
print $4 # Window id | |
} | |
m = 0 | |
} | |
/^MapNotify/ { | |
m = 1 | |
} | |
' | { | |
# Wait for extension to connect (do not fail even if it times out) | |
waitwebsocket | |
while read line; do | |
# Translate window id to display number | |
id="${line%,}" | |
if [ "$id" = "$aura" ]; then | |
display="aura" | |
elif [ "$XMETHOD" = 'cros' ]; then | |
display=':0' | |
else | |
# This relies on WM_NAME looking like "Xephyr on :1.0 (...)" | |
display="`host-x11 xprop -format WM_NAME 8s '\t$0' \ | |
-id "$id" WM_NAME | cut -f 2 | \ | |
sed -n -e 's/^\"Xephyr on \(:[0-9]\{1,\}\).*$/\1/p'`" | |
fi | |
copyclip "$display" | |
done | |
};; | |
'x11') | |
# No need to set $current: | |
# croutonvtmonitor outputs the current tty right after it is started | |
{ | |
croutonvtmonitor & | |
cpid=$! | |
addtrap "kill $cpid 2>/dev/null" | |
if ! wait $cpid; then | |
echo "croutonclip: croutonvtmonitor error ($?)" | |
fi | |
} | { | |
# Wait for extension to connect (do not fail even if it times out) | |
waitwebsocket | |
while read tty; do | |
display='' | |
if [ "$tty" = "tty1" ]; then | |
display="aura" | |
else | |
# Find which process owns the tty | |
process="`ps -o pid= -t "$tty" | sed 's/ //g'`" | |
if [ -n "$process" ]; then | |
# Find which display the process owns (if any) | |
for lock in /tmp/.X*-lock; do | |
if grep -q "^ *$process$" "$lock"; then | |
display="${lock#/tmp/.X}" | |
display=":${display%-lock}" | |
fi | |
done | |
fi | |
fi | |
copyclip "$display" | |
done | |
};; | |
*) | |
echo "Invalid xmethod='$XMETHOD'." >&2;; | |
esac | |
exit 1 |
You genius, all hacks are removed now. Thanks again!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
One more thing... Trying to figure out how to integrate this neatly in the crouton framework.
You could remove lines 130-131, and instead rely on an environment variable XMETHOD that needs to be passed to the script. That removes the need for the
xserverr-cros
hack, and make it possible to use the script in bothcros
orx11
/xephyr
context.