-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLINUX386FB.Input.Mod.txt
188 lines (177 loc) · 7.31 KB
/
LINUX386FB.Input.Mod.txt
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
MODULE Input; (*NW 5.10.86 / 15.11.90 Ceres-2; PDR 21.4.12 / NW 15.5.2013 Ceres-4*)
IMPORT SYSTEM, Host;
CONST msMax = 2; kbdMax = 32;
VAR kbdCode: BYTE; (*last keyboard code read*)
Recd, Up, Shift, Ctrl, Ext: BOOLEAN;
KTabAdr: INTEGER; (*keyboard code translation table*)
MW, MH, MX, MY: INTEGER; (*mouse limits and coords*)
MK: SET; (*mouse keys*)
syscall2: PROCEDURE (eax, ebx: INTEGER): INTEGER;
syscall4: PROCEDURE (eax, ebx, ecx, edx: INTEGER): INTEGER;
kbd: ARRAY kbdMax OF INTEGER; (*keyboard event fd*)
ms: ARRAY msMax OF INTEGER; (*mouse fd*)
KN, MN: INTEGER; (*number of keyboard/mouse*)
(*FIFO implemented in hardware, because every read must be handled,
including tracking the state of the Shift and Ctrl keys*)
PROCEDURE Peek();
VAR i, fd, res, count, type, code, value: INTEGER; buf: ARRAY 4 OF INTEGER;
BEGIN i := 0;
WHILE ~Recd & (i < KN) DO fd := kbd[i];
REPEAT
count := 0;
REPEAT (*read*)
res := syscall4(3, fd, SYSTEM.ADR(buf) + count, 16 - count);
IF res > 0 THEN INC(count, res) END
UNTIL (res # -4) & ((count = 0) OR (count = 16));
IF count = 16 THEN
type := buf[2] MOD 65536;
code := buf[2] DIV 65536 MOD 65536;
value := buf[3];
IF type = 0 THEN (*EV_SYN*)
IF code = 3 THEN (* SYN_DROPPED => fsync(fd) *)
res := syscall2(118, fd);
kbdCode := 0; Up := FALSE; Shift := FALSE; Ctrl := FALSE; Recd := FALSE
END
ELSIF (type = 1) & (code <= 127) THEN (*EV_KEY*)
kbdCode := code; Up := value = 0;
IF (code = 42) OR (code = 54) THEN (*shift*) Shift := ~Up
ELSIF code = 29 THEN (*ctrl*) Ctrl := ~Up
ELSIF ~Up THEN Recd := TRUE (*real key going down*)
END
END
END
UNTIL (res <= 0) OR (count = 0) OR Recd;
INC(i)
END
END Peek;
PROCEDURE Available*(): INTEGER;
BEGIN Peek();
RETURN ORD(Recd)
END Available;
PROCEDURE Read*(VAR ch: CHAR);
BEGIN
WHILE ~Recd DO Peek() END ;
IF Shift OR Ctrl THEN INC(kbdCode, 80H) END; (*ctrl implies shift*)
(* ch := kbdTab[kbdCode]; *)
SYSTEM.GET(KTabAdr + kbdCode, ch);
IF Ctrl THEN ch := CHR(ORD(ch) MOD 20H) END;
Recd := FALSE
END Read;
PROCEDURE PeekMouse();
VAR i, dx, dy, res, count, fd: INTEGER; s, u, v: SET; buf: ARRAY 3 OF BYTE;
BEGIN u := {}; v := {};
FOR i := 0 TO MN - 1 DO fd := ms[i];
count := 0;
REPEAT
res := syscall4(3, fd, SYSTEM.ADR(buf) + count, 3 - count);
IF res > 0 THEN INC(count, res) END
UNTIL (res # -4) & ((count = 0) OR (count = 3));
IF count = 3 THEN
s := SYSTEM.VAL(SET, ORD(buf[0]));
IF 0 IN s THEN INCL(u, 2) ELSE INCL(v, 2) END; (* ML *)
IF 1 IN s THEN INCL(u, 0) ELSE INCL(v, 0) END; (* MR *)
IF 2 IN s THEN INCL(u, 1) ELSE INCL(v, 1) END; (* MM *)
dx := buf[1]; IF dx >= 128 THEN DEC(dx, 256) END;
dy := buf[2]; IF dy >= 128 THEN DEC(dy, 256) END;
INC(MX, dx); INC(MY, dy)
END
END;
IF MX < 0 THEN MX := 0 ELSIF MX >= MW THEN MX := MW-1 END;
IF MY < 0 THEN MY := 0 ELSIF MY >= MH THEN MY := MH-1 END;
MK := MK - v + u
END PeekMouse;
PROCEDURE Mouse*(VAR keys: SET; VAR x, y: INTEGER);
BEGIN PeekMouse(); keys := MK; x := MX; y := MY
END Mouse;
PROCEDURE SetMouseLimits*(w, h: INTEGER);
BEGIN MW := w; MH := h
END SetMouseLimits;
PROCEDURE Decimal (VAR s: ARRAY OF CHAR; j, x: INTEGER);
VAR i: INTEGER; x0: LONGINT; a: ARRAY 12 OF CHAR;
BEGIN
IF ROR(x, 31) = 1 THEN a := "8463847412-"; i := 12
ELSE i := 0;
IF x < 0 THEN x0 := -x ELSE x0 := x END;
REPEAT
a[i] := CHR(x0 MOD 10 + 30H); x0 := x0 DIV 10; INC(i)
UNTIL x0 = 0;
IF x < 0 THEN a[i] := "-"; INC(i) END
END;
REPEAT DEC(i); s[j] := a[i]; INC(j) UNTIL i = 0; s[j] := 0X
END Decimal;
PROCEDURE Init*;
VAR i, j, k, fd, res, key: INTEGER;
name: ARRAY 32 OF CHAR;
events: SET;
ok: BOOLEAN;
keys: ARRAY 8 OF SET;
ch: CHAR;
BEGIN Up := FALSE; Shift := FALSE; Ctrl := FALSE; Recd := FALSE;
KTabAdr := SYSTEM.ADR($
00 1B 31 32 33 34 35 36 37 38 39 30 2D 3D 08 09
71 77 65 72 74 79 75 69 6F 70 5B 5D 0D 00 61 73
64 66 67 68 6A 6B 6C 3B 27 60 00 5C 7A 78 63 76
62 6E 6D 2C 2E 2F 00 00 00 20 00 1A 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 7F 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 1B 21 40 23 24 25 5E 26 2A 28 29 5F 2B 08 09
51 57 45 52 54 59 55 49 4F 50 7B 7D 0D 00 41 53
44 46 47 48 4A 4B 4C 3A 22 7E 00 7C 5A 58 43 56
42 4E 4D 3C 3E 3F 00 00 00 20 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 7F 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00$);
SYSTEM.PUT(SYSTEM.ADR(syscall2), SYSTEM.ADR($8B442408 8B5C2404 CD80 C20800 6690 90$));
SYSTEM.PUT(SYSTEM.ADR(syscall4), SYSTEM.ADR($8B442410 8B5C240C 8B4C2408 8B542404 CD80 C21000 6690 90$));
FOR i := 0 TO MN-1 DO res := syscall2(6, ms[i]) END; (*close*)
FOR i := 0 TO KN-1 DO res := syscall2(6, kbd[i]) END; (*close*)
name := "/dev/input/eventX"; KN := 0; MN := 0; i := 0;
WHILE (i < 256) & (KN < kbdMax) DO
Decimal(name, 16, i);
REPEAT (*open(name, O_NONBLOCK|O_RDONLY)*)
fd := syscall4(5, SYSTEM.ADR(name), 800H, 0)
UNTIL fd # -4;
IF fd >= 0 THEN
ok := FALSE;
IF syscall4(54, fd, 80044520H, SYSTEM.ADR(events)) > 0 THEN (*ioctl(fd, EVIOCGBIT(0, 4), &events)*)
IF 1 IN events THEN
res := syscall4(54, fd, 80204521H, SYSTEM.ADR(keys)); (*ioctl(fd, EVIOCGBIT(EV_KEY, 32), keys)*)
IF res > 0 THEN
j := 0;
REPEAT (*at least one key must be supported by keyboard*)
key := j MOD 128;
IF key < res * 4 THEN
SYSTEM.GET(KTabAdr + j, ch); ok := (ch # 0X) & ((key MOD 32) IN keys[key DIV 32])
END;
INC(j)
UNTIL ok OR (j >= 256)
END
END
END;
IF ok THEN kbd[KN] := fd; INC(KN)
ELSE res := syscall2(6, fd) (*close*)
END
END;
INC(i)
END;
REPEAT fd := syscall4(5, SYSTEM.ADR("/dev/psaux"), 800H, 0) UNTIL fd # -4;
IF fd >= 0 THEN ms[MN] := fd; INC(MN) END;
REPEAT fd := syscall4(5, SYSTEM.ADR("/dev/input/mice"), 800H, 0) UNTIL fd # -4;
IF fd >= 0 THEN ms[MN] := fd; INC(MN) END;
IF MN = 0 THEN
REPEAT res := syscall4(4, 2, SYSTEM.ADR("input error: no mouse found"), 27) UNTIL res # -4;
REPEAT res := syscall4(4, 2, SYSTEM.ADR($0A$), 1) UNTIL res # -4;
Host.Abort
END;
IF KN = 0 THEN
REPEAT res := syscall4(4, 2, SYSTEM.ADR("input error: no keyboard found"), 30) UNTIL res # -4;
REPEAT res := syscall4(4, 2, SYSTEM.ADR($0A$), 1) UNTIL res # -4;
Host.Abort
END;
Host.Init({0})
END Init;
BEGIN Init
END Input.