From: Paul Hänsch Date: Fri, 7 Apr 2023 09:52:49 +0000 (+0200) Subject: draft of initial functions X-Git-Url: https://git.plutz.net/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=x11sh draft of initial functions --- fc0dd3b52e12459ec9475cf16c69b45e4ab3f06b diff --git a/libx11.sh b/libx11.sh new file mode 100755 index 0000000..a109939 --- /dev/null +++ b/libx11.sh @@ -0,0 +1,206 @@ +#!/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