]> git.plutz.net Git - x11sh/blob - libx11.sh
draft of initial functions
[x11sh] / libx11.sh
1 #!/bin/sh
2
3 _EXEC="${0}"
4 X11_FORK="${X11_FORK:-0}"
5
6 debug(){
7   DEBUG="${DEBUG:-/dev/stderr}"
8   if [ $# -gt 0 ]; then
9     printf "$@" >"$DEBUG"
10   else
11     tee -- "$DEBUG"
12   fi
13 }
14
15 printe(){ printf "$@" >&2; }
16   
17 case $DISPLAY in
18   :[0-9]*)
19     X11_UNIX=${DISPLAY#:}
20     X11_UNIX="/tmp/.X11-unix/X${X11_UNIX%.*}"
21     ;;
22   *:[0-9]*)
23     X11_HOST=${DISPLAY%:*}
24     X11_PORT=${DISPLAY#*:}
25     X11_PORT=$((6000 + ${X11_PORT%.*}))
26     ;;
27 esac
28
29 if [ "$X11_FORK" = 1 ]; then
30   X11_FORK=2
31   debug "Forking into hexdump\n"
32   stdbuf -o0 hexdump -ve '3/1 " %u" /1 " %u\n"' |"$_EXEC"
33   exit $?
34
35 elif [ "$X11_FORK" = 2 ]; then
36   debug "Reassigning file handles\n"
37   exec 3<&0 4>&1
38   exec 0<&- 1>&-
39   exec 0<&8 1>&9
40   exec 8<&- 9>&-
41
42 elif [ "$X11_HOST" -a "$X11_PORT" ]; then
43   exec 8<&0 9>&1
44   export X11_FORK=1
45   debug 'Using `ncat` for TCP socket %s:%i\n' "$X11_HOST" "$X11_PORT"
46   if ! ncat "$X11_HOST" "$X11_PORT" -e "$_EXEC"; then
47     e=$?
48     printe '`ncat` could not connect to TCP socket %s:%i\n' "$X11_HOST" "$X11_PORT"
49     exit $e
50   fi
51   exit 0
52
53 elif [ "$X11_UNIX" ]; then
54   exec 8<&0 9>&1
55   export X11_FORK=1
56   debug 'Using `ncat` for UNIX socket %s\n' "$X11_UNIX"
57   if ! ncat -U "$X11_UNIX" -e "$_EXEC"; then
58     e=$?
59     printe '`ncat` could not connect to UNIX socket %s\n' "$X11_UNIX"
60     exit $e
61   fi
62   exit 0
63
64 else
65   printe 'No DISPLAY specified, set a DISPLAY variable to connect to a server.'
66   exit 1
67
68 fi
69
70 debug 'Connected to X11-Server\n'
71
72 X11_VERSION=
73 X11_RID_BASE=
74 X11_RID_MASK=
75
76 x11_additional_data=
77
78 STRING8(){
79   local string='' chars="$1"
80   while [ "$chars" -gt 0 ]; do
81     string="$string ${x11_additional_data%% *}"
82     x11_additional_data="${x11_additional_data#* }"
83     chars="$((chars - 1))"
84   done
85   printf "$(printf '\\%o' $string)";
86 }
87 # CARD16(){ printf "%i\n" $((256 * $1 + $2)); }
88 # CARD32(){ printf "%i\n" $((16777216 * $1 + 65536 * $2 + 256 * $3 + $4)); }
89
90 x11_additional_data(){
91   # Argument: Number of 4-Octet (32bit) data words
92   # Return: list of decimal representation of octets
93   local data l words="$1" 
94   while [ $words -gt 0 ]; do
95     read -r l
96     data="$data $l"
97     words=$((words - 1))
98   done <&3
99   printf '%i ' $data
100 }
101
102 x11_read_values(){
103   local data chars m1 m2 m3 m4;
104   read data;
105   data="${data} "
106   while [ $# -gt 0 ]; do case $1 in
107     CARD8|BYTE)
108       m1="${data%% *}" data="${data#* }"
109       printf "%i " $m1;
110       shift 1
111       ;;
112     CARD16)
113       m1="${data%% *}" data="${data#* }"
114       m2="${data%% *}" data="${data#* }"
115       printf "%i " $((256 * m1 + m2));
116       shift 1
117       ;;
118     CARD32|VALUE|TIMESTAMP)
119       m1="${data%% *}" data="${data#* }"
120       m2="${data%% *}" data="${data#* }"
121       m3="${data%% *}" data="${data#* }"
122       m4="${data%% *}" data="${data#* }"
123       printf "%i " $((16777216 * m1 + 65536 * m2 + 256 * m3 + m4));
124       shift 1
125       ;;
126     STRING8) # Argument: Number of characters
127       chars="${2:-0}" m1='' m2=''
128       while [ $chars -gt 0 ]; do
129         m1="$m1 ${data%% *}"
130         data="${data#* }"
131         chars=$((chars - 1))
132       done 
133       printf "$(printf '\\%o' $m1)\n";
134       shift 2
135       ;;
136     pad) # Argument: Number of octets, discards octets without output
137       chars="${2:-0}"
138       while [ $chars -gt 0 ]; do
139         data="${data#* }"
140         chars=$((chars - 1))
141       done 
142       shift 2
143       ;;
144     FORMAT):
145       #printf 
146       ;;
147     *)
148       debug 'Unknown value type: %s\n' "$1"
149       shift 1
150       ;;
151   esac; done
152
153   printf '%s\n' "$data"
154 }
155
156 x11_setup(){
157   local m1 m2 m3 m4 m5 m6 m7 m8 data
158
159   printf 'B~\000\013\000\000\000\000\000\000~~' >&4
160
161   read m1 m2 m3 m4 <&3
162   read m5 m6 m7 m8 <&3
163
164   X11_VERSION="$((256 * m3 + m4)).$((256 * m5 + m6))"
165   data="$(x11_additional_data "$((256 * m7 + m8))")"
166
167   case $m1 in
168     0): # Failed
169       debug 'X11: Setup Failed\nProtocol Version: %s\n' "$X11_VERSION"
170       debug '%s\n' "$(printf '%i ' $data |x11_read_values STRING8 $m2)"
171       return 1
172       ;;
173     2): # Authenticate
174       debug 'X11: Setup Authenticate\n'
175       debug '%s\n' "$(printf '%i ' $data |x11_read_values STRING8 $m2)"
176       return 2
177       ;;
178     1): # Success
179       debug 'X11: Setup Success\nProtocol Version: %s\n' "$X11_VERSION"
180       { read X11_RELEASE X11_RID_BASE X11_RID_MASK X11_MBUF_SIZE \
181              m1 X11_MAX_RQ_LENGTH \
182              m2 m3 X11_IMAGE_BO X11_BITMAP_BO \
183              X11_SCANLINE_UNIT X11_SCANLINE_PAD \
184              X11_MIN_KEYCODE X11_MAX_KEYCODE \
185              junk data;
186       } <<-EOF
187         $( printf '%i ' $data |x11_read_values \
188             CARD32 CARD32 CARD32 CARD32 \
189             CARD16 CARD16 \
190             CARD8 CARD8 CARD8 CARD8 \
191             CARD8 CARD8 \
192             CARD8 CARD8 \
193             CARD32
194           )
195         EOF
196       debug "Number of Screens: %i\n" $m2
197       { read X11_VENDOR; read data; } <<-EOF
198         $( printf '%i ' $data |x11_read_values STRING8 $m1 pad $(( (4 - m1 % 4) % 4 )) )
199         EOF
200       debug "Vendor (%i): %s\n" "$m1" "$X11_VENDOR"
201       ;;
202   esac
203 }
204
205 x11_setup
206 # cat <&3