+#!/bin/sh
+
+_EXEC="${0}"
+X11_FORK="${X11_FORK:-0}"
+
+debug(){
+ DEBUG="${DEBUG:-/dev/stderr}"
+ if [ $# -gt 0 ]; then
+ printf "$@" >"$DEBUG"
+ else
+ tee -- "$DEBUG"
+ fi
+}
+
+printe(){ printf "$@" >&2; }
+
+case $DISPLAY in
+ :[0-9]*)
+ X11_UNIX=${DISPLAY#:}
+ X11_UNIX="/tmp/.X11-unix/X${X11_UNIX%.*}"
+ ;;
+ *:[0-9]*)
+ X11_HOST=${DISPLAY%:*}
+ X11_PORT=${DISPLAY#*:}
+ X11_PORT=$((6000 + ${X11_PORT%.*}))
+ ;;
+esac
+
+if [ "$X11_FORK" = 1 ]; then
+ X11_FORK=2
+ debug "Forking into hexdump\n"
+ stdbuf -o0 hexdump -ve '3/1 " %u" /1 " %u\n"' |"$_EXEC"
+ exit $?
+
+elif [ "$X11_FORK" = 2 ]; then
+ debug "Reassigning file handles\n"
+ exec 3<&0 4>&1
+ exec 0<&- 1>&-
+ exec 0<&8 1>&9
+ exec 8<&- 9>&-
+
+elif [ "$X11_HOST" -a "$X11_PORT" ]; then
+ exec 8<&0 9>&1
+ export X11_FORK=1
+ debug 'Using `ncat` for TCP socket %s:%i\n' "$X11_HOST" "$X11_PORT"
+ if ! ncat "$X11_HOST" "$X11_PORT" -e "$_EXEC"; then
+ e=$?
+ printe '`ncat` could not connect to TCP socket %s:%i\n' "$X11_HOST" "$X11_PORT"
+ exit $e
+ fi
+ exit 0
+
+elif [ "$X11_UNIX" ]; then
+ exec 8<&0 9>&1
+ export X11_FORK=1
+ debug 'Using `ncat` for UNIX socket %s\n' "$X11_UNIX"
+ if ! ncat -U "$X11_UNIX" -e "$_EXEC"; then
+ e=$?
+ printe '`ncat` could not connect to UNIX socket %s\n' "$X11_UNIX"
+ exit $e
+ fi
+ exit 0
+
+else
+ printe 'No DISPLAY specified, set a DISPLAY variable to connect to a server.'
+ exit 1
+
+fi
+
+debug 'Connected to X11-Server\n'
+
+X11_VERSION=
+X11_RID_BASE=
+X11_RID_MASK=
+
+x11_additional_data=
+
+STRING8(){
+ local string='' chars="$1"
+ while [ "$chars" -gt 0 ]; do
+ string="$string ${x11_additional_data%% *}"
+ x11_additional_data="${x11_additional_data#* }"
+ chars="$((chars - 1))"
+ done
+ printf "$(printf '\\%o' $string)";
+}
+# CARD16(){ printf "%i\n" $((256 * $1 + $2)); }
+# CARD32(){ printf "%i\n" $((16777216 * $1 + 65536 * $2 + 256 * $3 + $4)); }
+
+x11_additional_data(){
+ # Argument: Number of 4-Octet (32bit) data words
+ # Return: list of decimal representation of octets
+ local data l words="$1"
+ while [ $words -gt 0 ]; do
+ read -r l
+ data="$data $l"
+ words=$((words - 1))
+ done <&3
+ printf '%i ' $data
+}
+
+x11_read_values(){
+ local data chars m1 m2 m3 m4;
+ read data;
+ data="${data} "
+ while [ $# -gt 0 ]; do case $1 in
+ CARD8|BYTE)
+ m1="${data%% *}" data="${data#* }"
+ printf "%i " $m1;
+ shift 1
+ ;;
+ CARD16)
+ m1="${data%% *}" data="${data#* }"
+ m2="${data%% *}" data="${data#* }"
+ printf "%i " $((256 * m1 + m2));
+ shift 1
+ ;;
+ CARD32|VALUE|TIMESTAMP)
+ m1="${data%% *}" data="${data#* }"
+ m2="${data%% *}" data="${data#* }"
+ m3="${data%% *}" data="${data#* }"
+ m4="${data%% *}" data="${data#* }"
+ printf "%i " $((16777216 * m1 + 65536 * m2 + 256 * m3 + m4));
+ shift 1
+ ;;
+ STRING8) # Argument: Number of characters
+ chars="${2:-0}" m1='' m2=''
+ while [ $chars -gt 0 ]; do
+ m1="$m1 ${data%% *}"
+ data="${data#* }"
+ chars=$((chars - 1))
+ done
+ printf "$(printf '\\%o' $m1)\n";
+ shift 2
+ ;;
+ pad) # Argument: Number of octets, discards octets without output
+ chars="${2:-0}"
+ while [ $chars -gt 0 ]; do
+ data="${data#* }"
+ chars=$((chars - 1))
+ done
+ shift 2
+ ;;
+ FORMAT):
+ #printf
+ ;;
+ *)
+ debug 'Unknown value type: %s\n' "$1"
+ shift 1
+ ;;
+ esac; done
+
+ printf '%s\n' "$data"
+}
+
+x11_setup(){
+ local m1 m2 m3 m4 m5 m6 m7 m8 data
+
+ printf 'B~\000\013\000\000\000\000\000\000~~' >&4
+
+ read m1 m2 m3 m4 <&3
+ read m5 m6 m7 m8 <&3
+
+ X11_VERSION="$((256 * m3 + m4)).$((256 * m5 + m6))"
+ data="$(x11_additional_data "$((256 * m7 + m8))")"
+
+ case $m1 in
+ 0): # Failed
+ debug 'X11: Setup Failed\nProtocol Version: %s\n' "$X11_VERSION"
+ debug '%s\n' "$(printf '%i ' $data |x11_read_values STRING8 $m2)"
+ return 1
+ ;;
+ 2): # Authenticate
+ debug 'X11: Setup Authenticate\n'
+ debug '%s\n' "$(printf '%i ' $data |x11_read_values STRING8 $m2)"
+ return 2
+ ;;
+ 1): # Success
+ debug 'X11: Setup Success\nProtocol Version: %s\n' "$X11_VERSION"
+ { read X11_RELEASE X11_RID_BASE X11_RID_MASK X11_MBUF_SIZE \
+ m1 X11_MAX_RQ_LENGTH \
+ m2 m3 X11_IMAGE_BO X11_BITMAP_BO \
+ X11_SCANLINE_UNIT X11_SCANLINE_PAD \
+ X11_MIN_KEYCODE X11_MAX_KEYCODE \
+ junk data;
+ } <<-EOF
+ $( printf '%i ' $data |x11_read_values \
+ CARD32 CARD32 CARD32 CARD32 \
+ CARD16 CARD16 \
+ CARD8 CARD8 CARD8 CARD8 \
+ CARD8 CARD8 \
+ CARD8 CARD8 \
+ CARD32
+ )
+ EOF
+ debug "Number of Screens: %i\n" $m2
+ { read X11_VENDOR; read data; } <<-EOF
+ $( printf '%i ' $data |x11_read_values STRING8 $m1 pad $(( (4 - m1 % 4) % 4 )) )
+ EOF
+ debug "Vendor (%i): %s\n" "$m1" "$X11_VENDOR"
+ ;;
+ esac
+}
+
+x11_setup
+# cat <&3