summaryrefslogtreecommitdiff
path: root/mdm/src/mdm-start-seat
blob: 4fdd1feaabc71f3e7f1cb3fdf2082ffbaab545ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#!/bin/bash

# Copyright (C) 2004-2007 Centro de Computacao Cientifica e Software Livre
# Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.

# This script starts a seat.
# Its arguments are:
# - The number of the "video card". Video card N has display 0.((N-1)) on the
#   underneath xserver.
# - The number of the display that the seat will have to open. This should be
#   unique for all seats.

# We assume $DISPLAY is already set here

MDM_PREFIX=/
MDM_SCRIPTS=${MDM_PREFIX}/usr/sbin
MDM_INCLUDE=${MDM_SCRIPTS}/mdm-common
source $MDM_INCLUDE

READ_DEVICES=${MDM_SCRIPTS}/read-devices
WRITE_MESSAGE=${MDM_SCRIPTS}/write-message
SEAT_PARENT_WINDOW=${MDM_SCRIPTS}/seat-parent-window

VIDEO_CARD_NUMBER=$1
SEAT_DISPLAY=$2

#MY_LOG=$MDM_LOGS/mdm-start-seat.${VIDEO_CARD_NUMBER}.log

function open_seat_parent_window () {
    # The first parameter given to this function must be [width]*n, where n is
    # a multiplier that gives the coordinates to correctly open
    # seat_parent_window. This number is also used on names of files.
    if [ -f "${MDM_PIDS}/seat-parent-window${DISPLAY}-$1.pid" ]; then
        kill `cat ${MDM_PIDS}/seat-parent-window${DISPLAY}-$1.pid` 2> /dev/null
        rm -f ${MDM_PIDS}/seat-parent-window${DISPLAY}-$1.pid 2> /dev/null
    fi

    $SEAT_PARENT_WINDOW $MY_SCREEN_SIZE+$1+0 seat-parent-window$DISPLAY-$1 &
    PID=$!
    echo $PID > ${MDM_PIDS}/seat-parent-window${DISPLAY}-$1.pid

    SEAT_WINDOW_ID=$(xwininfo -name "seat-parent-window${DISPLAY}-$1"   |
                        grep "Window id" | cut -d' ' -f4)
}


function display_message () {
    case $1 in
        key_press)
	    $WRITE_MESSAGE $SEAT_WINDOW_ID "Press the F$2 key" 1>&2
	    ;;
	button_press)
	    $WRITE_MESSAGE $SEAT_WINDOW_ID "Press the mouse left button" 1>&2
	    ;;
	wait)
	    $WRITE_MESSAGE $SEAT_WINDOW_ID "Please wait" 1>&2
	    ;;
	reconfigure)
	    $WRITE_MESSAGE $SEAT_WINDOW_ID "Press ESC to reconfigure" 1>&2
	    ;;
    esac

}

function parse_config_file () {

    if [ ! -z ${XKB_MODEL[VIDEO_CARD_NUMBER]} ]; then
        MY_XKB_MODEL=${XKB_MODEL[VIDEO_CARD_NUMBER]}
    else
        MY_XKB_MODEL=$DEFAULT_XKB_MODEL
    fi
    if [ ! -z ${XKB_LAYOUT[VIDEO_CARD_NUMBER]} ]; then
        MY_XKB_LAYOUT=${XKB_LAYOUT[VIDEO_CARD_NUMBER]}
    else
        MY_XKB_LAYOUT=$DEFAULT_XKB_LAYOUT
    fi
    if [ ! -z ${MODE[SEAT_NUMBER]} ]; then
        MY_SCREEN_SIZE=${MODE[VIDEO_CARD_NUMBER]}
    else
        MY_SCREEN_SIZE=$DEFAULT_MODE
    fi
}

function select_keyboard () {
    if [ -e "${MDM_DEVICES}/keyboard${SEAT_DISPLAY}" ]; then
	return
    fi

    display_message key_press $SEAT_DISPLAY

    CREATED=0
    while (( ! CREATED )); do
	# Who are the keyboards?
	KEYBOARDS=$($DISCOVER_DEVICES kevdev | cut -f2)
	#echo "    Keyboards = $KEYBOARDS" 1>&2

	# Remove used keyboards
	REMOVE=$(stat -c %N $MDM_DEVICES/keyboard* 2> /dev/null|
	         cut -d'`' -f3 | cut -d"'" -f1)
	for i in ${REMOVE}; do
	    KEYBOARDS=`sed "s#$i# #g" <<< $KEYBOARDS`
	done
	#echo "    ... after removing: Keyboards = $KEYBOARDS" 1>&2
	
	if [ -z "$KEYBOARDS" ]; then
	    # No keyboards. Hopefully someone will connect one.
	    sleep 1 # Don't use 100% CPU
	    continue
	fi

	# See if someone presses the key:
	PRESSED=$($READ_DEVICES $SEAT_DISPLAY $KEYBOARDS | grep '^detect' |
	            cut -d'|' -f2)

	if [ -z "$PRESSED" ]; then
	    # if $READ_DEVICES gets killed the script won't do bad stuff
	    continue
	fi
	if [ "$PRESSED" = 'timeout' ]; then
	    continue
	fi

	# Ok, someone pressed the key
	ln -sf $PRESSED $MDM_DEVICES/keyboard${SEAT_DISPLAY}
	CREATED=1

	# Verify is there is already another link in $MDM_DEVICES/keyboard* that
	# points to the device. If there is, erase the one I created and
	# continue looping
	for i in `ls $MDM_DEVICES | grep "\<keyboard"`; do
	    if [ "$i" != "keyboard${SEAT_DISPLAY}" ]; then
		AUX=$(stat -c %N $MDM_DEVICES/$i| cut -d'`' -f3| cut -d"'" -f1)
		if [ "$AUX" = "$PRESSED" ]; then
		    # Keyboard link already exists...
		    rm -f $MDM_DEVICES/keyboard${SEAT_DISPLAY}
		    CREATED=0
		fi
	    fi
	done
    done

    KEYBOARD="$MDM_DEVICES/keyboard${SEAT_DISPLAY}"

}

function select_mouse () {
    if [ -e "${MDM_DEVICES}/mouse${SEAT_DISPLAY}" ]; then
	return
    fi

    CREATED=0
    while (( ! CREATED )); do
	# Who are the mice?
	MICE=$($DISCOVER_DEVICES mevdev | cut -f2)
	
	REMOVE=$(stat -c %N ${MDM_DEVICES}/mouse* 2> /dev/null|
	         cut -d'`' -f3 | cut -d"'" -f1)
	for i in ${REMOVE}; do
	    MICE=`sed "s#$i# #g" <<< $MICE`
	done
	
	if [ -z "$MICE" ]; then
	    # No mice. Hopefully someone will connect one.
	    sleep 1 # Don't use 100% CPU
	    continue
	fi

	# Create the lock
	LOCK_EXISTS=1
	while (( LOCK_EXISTS )); do
	    touch ${MDM_DEVICES}/lock${SEAT_DISPLAY}
	    LOCK_EXISTS=0
	    for i in `ls $MDM_DEVICES | grep "\<lock"`; do
		if [ "$i" != "lock${SEAT_DISPLAY}" ]; then
		    LOCK_EXISTS=1
		fi
	    done
	    if (( LOCK_EXISTS )); then
		# Yes, we'll call this lots of times...
		display_message wait
		rm -f ${MDM_DEVICES}/lock${SEAT_DISPLAY}
		sleep 1;
	    fi
	done

	# Now we have the lock!
	display_message button_press

	# See if someone presses the button:
	PRESSED=$($READ_DEVICES 13 $MICE | grep '^detect' | cut -d'|' -f2)

	if [ -z "$PRESSED" ]; then
	    # If $READ_DEVICES gets killed, don't do unwanted stuff
	    rm -f ${MDM_DEVICES}/lock${SEAT_DISPLAY}
	    continue
	fi
	if [ "$PRESSED" = 'timeout' ]; then
	    # Wait 5 seconds to give other machines the opportunity to enter the
	    # lock
	    display_message wait
	    rm -f ${MDM_DEVICES}/lock${SEAT_DISPLAY}
	    sleep 5
	    continue
	fi

	# Ok, someone pressed the key
	ln -sf $PRESSED ${MDM_DEVICES}/mouse${SEAT_DISPLAY}
	CREATED=1

	# Verify is there is already another link in $MDM_DEVICES/mouse* that
	# points to the device. If there is, erase the one I created and
	# continue looping
	for i in `ls $MDM_DEVICES | grep "\<mouse"`; do
	    if [ "$i" != "mouse${SEAT_DISPLAY}" ]; then
		AUX=$(stat -c %N ${MDM_DEVICES}/$i| cut -d'`' -f3|cut -d"'" -f1)
		if [ "$AUX" = "$PRESSED" ]; then
		    # Mouse link already exists...
		    rm -f ${MDM_DEVICES}/mouse${SEAT_DISPLAY}
		    CREATED=0
		fi
	    fi
	done
	rm -f ${MDM_DEVICES}/lock${SEAT_DISPLAY}
    done

    MOUSE="${MDM_DEVICES}/mouse${SEAT_DISPLAY}"
}

parse_config_file

KEYBOARD=
MOUSE=
SEAT_WINDOW_ID=
SCREEN_X_ORIGIN=($(grep -A4 $DISPLAY $XRANDR_INFO_FILE |
					tail -1 | cut -d'=' -f2))

# XXX: In case $SCREEN_X_ORIGIN has only one value, and SEAT_DISPLAY is odd,
# the open_seat_parent_window given parameter would be empty
# ($SCREEN_X_ORIGIN[1] for example).

open_seat_parent_window ${SCREEN_X_ORIGIN[$((SEAT_DISPLAY % 2))]:=0}

while (( 1 )); do

    #log --log-file-only "Configuring devices..."
    echo -e "\n--"
    echo "Configuring seat:"

    echo "  selecting keyboard"
    select_keyboard
    echo "  selecting mouse"
    select_mouse

    echo "  starting seat"
    display_manager_start_seat
    
    display_message reconfigure

    PRESSED=$($READ_DEVICES 14 $KEYBOARD | grep '^detect' | cut -d'|' -f2)
    if [ "$PRESSED" = 'esc' ]; then
	rm -f $KEYBOARD
	rm -f $MOUSE
    fi

done