]> git.plutz.net Git - x11sh/commitdiff
draft of initial functions master
authorPaul Hänsch <paul@plutz.net>
Fri, 7 Apr 2023 09:52:49 +0000 (11:52 +0200)
committerPaul Hänsch <paul@plutz.net>
Fri, 7 Apr 2023 09:52:49 +0000 (11:52 +0200)
libx11.sh [new file with mode: 0755]

diff --git a/libx11.sh b/libx11.sh
new file mode 100755 (executable)
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