Merged different version of scripts.
[hqbeamer.git] / script / beamer.sh
1 #!/bin/bash
2
3 # Andreas Schiermeier <andreas@schiermeier.name>
4
5 # BT Pairing using a PIN
6 # Debian squeeze:
7 # bluetooth-agent PIN 00:07:80:43:76:05
8 # Debian wheezy:
9 # apt-get install bluez python-gobject
10 # bluez-simple-agent hci0 00:07:80:43:76:05
11 #
12 # /etc/bluetooth/rfcomm.conf:
13 # rfcomm0 {
14 #   bind no;
15 #   device 00:07:80:43:76:05;
16 #   channel 1;
17 # }
18
19
20 BT_IF="rfcomm0"
21 BT_SPEED="9600"
22
23 control_pipe="/dev/stdin"
24 output="/dev/stdout"
25 rfcomm_init=0
26 pipe_client=0
27
28 declare -A commands
29 commands=(
30   ['POWERON']='!'
31   ['POWEROFF']='"'
32   ['INPUTCOMP1']='_r1'
33   ['INPUTCOMP2']='_r2'
34   ['INPUTDVI']='_d1'
35   ['INPUTVIDEO']='_v1'
36   ['INPUTSVIDEO']='_v2'
37   ['MUTEON']='MUTE1'
38   ['MUTEOFF']='MUTE0'
39   ['VOLUP']='r06'
40   ['VOLDOWN']='r07'
41   ['KEYSTONE']='r43'
42   ['EXPAND']='r02'
43   ['PINP']='r04'
44   ['MUTE']='ra6'
45   ['UP']='r53'
46   ['DOWN']='r2b'
47   ['LEFT']='r4f'
48   ['RIGHT']='r59'
49   ['MENU']='r54'
50   ['ENTER']='r10'
51   ['AUTOPOS']='r09'
52   ['STILL']='ra4'
53   ['ASPECT']='re2'
54   ['WALLSCREEN']='rd7'
55   ['CE']='re7'
56   )
57
58 function spawnRfcomm {
59   # try to establish a conecting to the projectors BT dongle
60   # in the background
61   (
62     while true
63     do
64       if [ -c "/dev/${BT_IF}" ]
65       then
66         rfcomm release "${BT_IF}" &> /dev/null
67       fi
68       # establish raw (-r) connection to projectors serial if
69       rfcomm -r connect "${BT_IF}" &> /dev/null
70       sleep 2
71     done
72   ) &
73   # clean up process group processes (rfcomm) in case the script exits
74   trap 'kill 0' EXIT
75 }
76
77 function sendCmd {
78   trycount=0
79   # is the device available?
80   while [ ! -c "/dev/${BT_IF}" ]
81   do
82     # try three times before giving up
83     let trycount++
84     if [ ${trycount} -gt 3 ]
85     then
86       return 1
87     fi
88     sleep 1 
89   done
90   # is the device the one we've already initialized?
91   rfcomm_created=$(stat -c %Z "/dev/${BT_IF}")
92   if [ ${rfcomm_created} -gt ${rfcomm_init} ]
93   then
94     # configure speed and enable CR to NL conversion for incoming data
95     stty -F "/dev/${BT_IF}" "${BT_SPEED}" icrnl
96     # \r ensures there is no grabage left on the serial connection to the projector
97     echo -en '\r' > "/dev/${BT_IF}"
98     rfcomm_init=${rfcomm_created}
99   fi
100   # empty action is used to init the connection
101   if [ -n "${1}" ]
102   then
103     echo -en '00'${commands[$1]}'\r' > "/dev/${BT_IF}"
104     # with for projectors reply up to one second
105     read -t1 ret < "/dev/${BT_IF}"
106     # projector replies back accepted commands
107     if [ "${ret}" != "00${commands[$1]}" ]
108     then
109       return 2
110     fi
111   fi
112 }
113
114 function usage {
115   cat <<__EOF>&2
116   
117 usage:  $0 [-c] [/path/to/namedpipe]
118
119
120 __EOF
121   exit
122 }
123
124 while getopts ":c" optname; do
125     case "${optname}" in
126         c)
127             pipe_client=1
128             ;;
129         *)
130             usage
131             ;;
132     esac
133 done
134 shift $((OPTIND-1))
135
136 if [ -p "${1}" ]
137 then
138   control_pipe="${1}"
139   if [ ${pipe_client} -eq 0 ]
140   then
141     output="/dev/null"
142   fi
143 fi
144
145 if [ ${pipe_client} -eq 0 ]
146 then
147   spawnRfcomm
148 fi
149
150 cat <<'EOF' > "${output}"
151 MENU m, POWERON p, POWEROFF P, UP k, DOWN j, LEFT h, RIGHT l, STILL s
152 INPUTCOMP1 1, INPUTCOMP2 2. INPUTDVI 3, INPUTVIDEO 4, INPUTSVIDEO 5, ENTER Return
153 TOGGLE INPUTCOMP1/DVI1 ~
154 QUIT Q
155
156 ready.
157 EOF
158
159 while true
160 do
161   # read from STDIN when acting as pipe client
162   if [ ${pipe_client} -eq 0 ]
163   then
164     read_pipe="${control_pipe}"
165   else
166     read_pipe="/dev/stdin"
167   fi
168   cmd=""
169   # read one key each time from STDIN / pipe
170   read -s -N 1 key < "${read_pipe}"
171   case "${key}" in
172     "m")
173       cmd='MENU'
174       ;;
175     "p")
176       cmd='POWERON'
177       ;;
178     "P")
179       cmd='POWEROFF'
180       ;;
181     "k"|"A") # A is part of the escape sequence sent by the arrow key (^]A)
182       cmd='UP'
183       ;;
184     "j"|"B") # B is part of the escape sequence sent by the arrow key (^]B)
185       cmd='DOWN'
186       ;;
187     "h"|"D") # K is part of the escape sequence sent by the arrow key (^]D)
188       cmd='LEFT'
189       ;;
190     "l"|"C") # C is part of the escape sequence sent by the arrow key (^]C)
191       cmd='RIGHT'
192       ;;
193     "s")
194       cmd='STILL'
195       ;;
196     "1")
197       cmd='INPUTCOMP1'
198       ;;
199     "2")
200       cmd='INPUTCOMP2'
201       ;;
202     "3")
203       cmd='INPUTDVI'
204       ;;
205     "4")
206       cmd='INPUTVIDEO'
207       ;;
208     "5")
209       cmd='INPUTSVIDEO'
210       ;;
211     "")
212       cmd='ENTER'
213       ;;
214     "~")
215       # SPECIAL CMD: toggle VGA1 and DVI
216       # --------------------------------
217       if [ ${pipe_client} -eq 0 ]
218       then
219         # init connection
220         sendCmd ''
221         # request selected input
222         echo -en '00vI\r' > "/dev/${BT_IF}"
223         read -t1 ret < "/dev/${BT_IF}"
224         # ret contains 00vIr1 for VGA1, 00vId1 for DVI
225         case "${ret}" in
226           00vIr1)
227             # VGA1 is active, switch to DVI
228             sendCmd 'INPUTDVI'
229             ;;
230           *)
231             # otherwise switch to VGA1
232             sendCmd 'INPUTCOMP1'
233             ;;
234         esac
235       fi  
236       ;;
237     "Q")
238       exit
239       ;;
240     *)
241       continue
242       ;;
243   esac
244   # just write key to pipe when acting as pipe client
245   # otherwise call sendCmd
246   if [ ${pipe_client} -eq 1 ]
247   then
248     echo -n "${key}" > "${control_pipe}"
249   elif [ -n "${cmd}" ]
250   then
251     echo -n "${cmd}: " > "${output}"
252     # sendCmd returns 0 if projector replied back the sent command
253     #                 1 if serial device is not available
254     #                 2 if projector doesn't reply the sent command within one second
255     if sendCmd "${cmd}"
256     then
257       echo "OK." > "${output}"
258     else
259       echo "failed (err: $?)." > "${output}"
260     fi
261   fi
262 done
263