1  #!/bin/sh -- # A comment mentioning perl
2eval 'exec perl -S $0 ${1+"$@"}'
3        if 0;
4#
5# vcinject.pl: simple hack to inject keystrokes into Linux VC tty.
6# See LinuxVNC.c for a more careful treatment using C and public API.
7#
8# Usage:  vcinject.pl <N>   (or /dev/ttyN)
9#
10# This is an example x11vnc -pipeinput program  E.g.:
11#
12#   x11vnc -rawfb map:/dev/fb0@1024x768x16 -pipeinput "vcinject.pl /dev/tty3"
13#
14# (see fbset(8) for obtaining fb info).
15#
16# It reads lines like this from STDIN:
17#
18# Keysym <id> <down> <n> <Keysym> ...
19#
20# <id> is ignored, it uses the rest to deduce the keystrokes to send
21# to the console.
22#
23
24$tty = shift;
25$tty = "/dev/tty$tty" if $tty =~ /^\d+$/;
26
27warn "strange tty device: $tty\n" if $tty !~ m,^/dev/tty\d+$,;
28
29open(TTY, ">$tty") || die "open $tty: $!\n";
30$fd = fileno(TTY);
31
32$linux_ioctl_syscall = 54;	# common knowledge, eh? :-)
33$TIOCSTI = 0x5412;
34
35%Map = qw(
36	Escape		27
37	Tab 		 9
38	Return		13
39	BackSpace	 8
40	Home		 1
41	End		 5
42	Up		16
43	Down		14
44	Right		 6
45	Left		 2
46	Next		 6
47	Prior		 2
48);
49# the latter few above seem to be vi specials. (since they are normally
50# escape sequences, e.g. ESC [ 5 ~)
51
52sub lookup {
53	my($down, $key, $name) = @_;
54
55	my $n = -1;
56	$name =~ s/^KP_//;
57
58	# algorithm borrowed from LinuxVNC.c:
59	if (! $down) {
60		if ($name =~ /^Control/) {
61			$control--;
62		}
63		return $n;
64	}
65
66	if ($name =~ /^Control/) {
67		$control++;
68	} else {
69		if (exists($Map{$name})) {
70			$n = $Map{$name};
71		}
72		if ($control && $name =~ /^[A-z]$/) {
73			$n = ord($name);
74			# shift down to the Control zone:
75			if ($name =~ /[a-z]/) {
76				$n -= (ord("a") - 1);
77			} else {
78				$n -= (ord("A") - 1);
79			}
80		}
81		if ($n < 0 && $key < 256) {
82			$n = $key;
83		}
84	}
85	return $n;
86}
87
88$control = 0;
89$debug = 0;
90
91while (<>) {
92	chomp;
93	if (/^\w+$/) {
94		# for debugging, you type the keysym in manually.
95		$_ = "Keysym 1 0 999 $_ None";
96	}
97	next unless /^Keysym/;
98
99	my ($j, $id, $down, $k, $keysym, $rest) = split(' ', $_);
100
101	$n = lookup($down, $k, $keysym);
102	if ($n < 0 || $n > 255) {
103		print STDERR "skip: '$keysym' -> $n\n" if $down && $debug;
104		next;
105	}
106
107	$n_p = pack("c", $n);
108	$ret = syscall($linux_ioctl_syscall, $fd, $TIOCSTI, $n_p);
109
110	print STDERR "ctrl=$control $keysym/$k syscall(" .
111		"$linux_ioctl_syscall, $fd, $TIOCSTI, $n) = $ret\n" if $debug;
112
113}
114