2
0

Inputs.Mod 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
  2. MODULE Inputs; (** AUTHOR "pjm"; PURPOSE "Abstract input device"; *)
  3. (* Based on SemInput.Mod by Marc Frei *)
  4. IMPORT Machine, Kernel, Plugins;
  5. CONST
  6. (** KeyboardMsg flags. *)
  7. Release* = 0; (** a key release event, otherwise a key press or repeat. *)
  8. (** shift key states. *)
  9. LeftShift* = 1; RightShift* = 2; LeftCtrl* = 3; RightCtrl* = 4;
  10. LeftAlt* = 5; RightAlt* = 6; LeftMeta* = 7; RightMeta* = 8;
  11. (** combined shift key states. *)
  12. Shift* = {LeftShift, RightShift}; Ctrl* = {LeftCtrl, RightCtrl};
  13. Alt* = {LeftAlt, RightAlt}; Meta* = {LeftMeta, RightMeta};
  14. (** flags for KeyState *)
  15. SHIFT* = 0; CTRL* = 1; ALT* = 2;
  16. (** keysym values, similar to X11 keysyms *)
  17. KsNil* = 0FFFFFFH; (** no key *)
  18. (** TTY Functions, cleverly chosen to map to ascii *)
  19. KsBackSpace* = 0FF08H; (** back space, back char *)
  20. KsTab* = 0FF09H;
  21. KsReturn* = 0FF0DH; (** Return, enter *)
  22. KsPause* = 0FF13H; (** Pause, hold *)
  23. KsScrollLock* = 0FF14H;
  24. KsSysReq* = 0FF15H;
  25. KsEscape* = 0FF1BH;
  26. KsDelete* = 0FFFFH; (** Delete, rubout *)
  27. (** Cursor control & motion *)
  28. KsHome* = 0FF50H;
  29. KsLeft* = 0FF51H; (** Move left, left arrow *)
  30. KsUp* = 0FF52H; (** Move up, up arrow *)
  31. KsRight* = 0FF53H; (** Move right, right arrow *)
  32. KsDown* = 0FF54H; (** Move down, down arrow *)
  33. KsPageUp* = 0FF55H; (** Prior, previous *)
  34. KsPageDown* = 0FF56H; (** Next *)
  35. KsEnd* = 0FF57H; (** EOL *)
  36. (** Misc Functions *)
  37. KsPrint* = 0FF61H;
  38. KsInsert* = 0FF63H; (** Insert, insert here *)
  39. KsMenu* = 0FF67H; (** Windows menu *)
  40. KsBreak* = 0FF6BH;
  41. KsNumLock* = 0FF7FH;
  42. (** Keypad functions *)
  43. KsKPEnter* = 0FF8DH; (** enter *)
  44. KsKPMultiply* = 0FFAAH;
  45. KsKPAdd* = 0FFABH;
  46. KsKPSubtract* = 0FFADH;
  47. KsKPDecimal* = 0FFAEH;
  48. KsKPDivide* = 0FFAFH;
  49. (** Function keys *)
  50. KsF1* = 0FFBEH; KsF2* = 0FFBFH; KsF3* = 0FFC0H; KsF4* = 0FFC1H; KsF5* = 0FFC2H; KsF6* = 0FFC3H;
  51. KsF7* = 0FFC4H; KsF8* = 0FFC5H; KsF9* = 0FFC6H; KsF10* = 0FFC7H; KsF11* = 0FFC8H; KsF12* = 0FFC9H;
  52. (** Modifiers *)
  53. KsShiftL* = 0FFE1H; (** Left shift *)
  54. KsShiftR* = 0FFE2H; (** Right shift *)
  55. KsControlL* = 0FFE3H; (** Left control *)
  56. KsControlR* = 0FFE4H; (** Right control *)
  57. KsCapsLock* = 0FFE5H; (** Caps lock *)
  58. KsMetaL* = 0FFE7H; (** Left meta, Left Windows *)
  59. KsMetaR* = 0FFE8H; (** Right meta, Right Windows *)
  60. KsAltL* = 0FFE9H; (** Left alt *)
  61. KsAltR* = 0FFEAH; (** Right alt *)
  62. (** HID Consumer Keys**)
  63. KsScanPreviousTrack*= 0FF0000H;
  64. KsScanNextTrack*= 0FF0001H;
  65. KsALConsumerControl*= 0FF0002H;
  66. KsMute*= 0FF0003H;
  67. KsVolumeDecrement*= 0FF0004H;
  68. KsVolumeIncrement*= 0FF0005H;
  69. KsPlayPause*= 0FF0006H;
  70. KsStopOSC*= 0FF0007H;
  71. KsALEmailReader*= 0FF0008H;
  72. KsALCalculator*= 0FF0009H;
  73. KsACSearch*= 0FF000AH;
  74. KsACHome*= 0FF000BH;
  75. KsACBack*= 0FF000CH;
  76. KsACForward*= 0FF000DH;
  77. KsACBookmarks*= 0FF000EH;
  78. KsConsumerButtons*= 0FFF000H;
  79. TYPE
  80. Message* = RECORD END; (** generic message. *)
  81. KeyboardMsg* = RECORD (Message)
  82. ch*: CHAR; (** extended ASCII key code, or 0X if not relevant *)
  83. flags*: SET; (** key flags *)
  84. keysym*: LONGINT (** X11-compatible key code *)
  85. END;
  86. MouseMsg* = RECORD (Message)
  87. keys*: SET; (** mouse key state. *)
  88. dx*, dy*, dz*: LONGINT (** mouse movement vector. *)
  89. END;
  90. AbsMouseMsg*= RECORD(Message);
  91. keys*: SET;
  92. x*,y*,z*,dx*,dy*,dz*: LONGINT;
  93. END;
  94. PointerMsg* = RECORD (Message)
  95. keys*: SET; (** pointer key state. *)
  96. x*, y*, z*: LONGINT; (** pointer position. *)
  97. mx*, my*, mz*: LONGINT (** pointer max values. *)
  98. END;
  99. TYPE
  100. Sink* = OBJECT (** a message receiver. *)
  101. (** Handle is overriden by a concrete receiver. *)
  102. PROCEDURE Handle*(VAR msg: Message);
  103. BEGIN HALT(301) END Handle;
  104. END Sink;
  105. Group* = OBJECT (** a group of message receivers. *)
  106. (** Add a receiver to a group. *)
  107. PROCEDURE Register*(s: Sink);
  108. BEGIN HALT(301) END Register;
  109. (** Remove a receiver from a group. *)
  110. PROCEDURE Unregister*(s: Sink);
  111. BEGIN HALT(301) END Unregister;
  112. (** Send a message to all receivers currently in the group. *)
  113. PROCEDURE Handle*(VAR msg: Message);
  114. BEGIN HALT(301) END Handle;
  115. END Group;
  116. TYPE
  117. Pointer* = OBJECT (Sink) (** convert incremental movements into absolute positions *)
  118. VAR
  119. cur: PointerMsg;
  120. threshold, speedup: LONGINT;
  121. fixedKeys: SET;
  122. PROCEDURE Update;
  123. VAR p: PointerMsg;
  124. BEGIN
  125. IF cur.x < 0 THEN cur.x := 0
  126. ELSIF cur.x > cur.mx THEN cur.x := cur.mx
  127. END;
  128. IF cur.y < 0 THEN cur.y := 0
  129. ELSIF cur.y > cur.my THEN cur.y := cur.my
  130. END;
  131. IF cur.z < 0 THEN cur.z := 0
  132. ELSIF cur.z > cur.mz THEN cur.z := cur.mz
  133. END;
  134. p := cur; p.keys := p.keys + fixedKeys;
  135. pointer.Handle(p)
  136. END Update;
  137. PROCEDURE SetKeys(keys: SET);
  138. BEGIN {EXCLUSIVE}
  139. fixedKeys := keys; Update
  140. END SetKeys;
  141. PROCEDURE Handle*(VAR m: Message);
  142. VAR dx, dy: LONGINT;
  143. BEGIN {EXCLUSIVE}
  144. IF m IS MouseMsg THEN
  145. WITH m: MouseMsg DO
  146. dx := m.dx; dy := m.dy;
  147. IF (ABS(dx) > threshold) OR (ABS(dy) > threshold) THEN
  148. dx := dx*speedup DIV 10; dy := dy*speedup DIV 10
  149. END;
  150. INC(cur.x, dx); INC(cur.y, dy); INC(cur.z, m.dz);
  151. cur.keys := m.keys;
  152. Update;
  153. END;
  154. ELSIF m IS AbsMouseMsg THEN
  155. WITH m: AbsMouseMsg DO
  156. cur.x := m.x; cur.y := m.y; cur.z := m.z;
  157. cur.keys := m.keys;
  158. Update
  159. END;
  160. END
  161. END Handle;
  162. PROCEDURE SetLimits*(mx, my, mz: LONGINT);
  163. BEGIN {EXCLUSIVE}
  164. cur.mx := mx; cur.my := my; cur.mz := mz;
  165. Update
  166. END SetLimits;
  167. PROCEDURE &Init*(t, s: LONGINT);
  168. BEGIN
  169. threshold := t; speedup := s;
  170. cur.x := 0; cur.y := 0; cur.z := 0;
  171. cur.mx := 1; cur.my := 1; cur.mz := 1;
  172. cur.keys := {}; fixedKeys := {};
  173. mouse.Register(SELF)
  174. END Init;
  175. END Pointer;
  176. TYPE
  177. List = POINTER TO RECORD
  178. next: List;
  179. s: Sink
  180. END;
  181. Broadcaster = OBJECT (Group)
  182. VAR sentinel: List;
  183. PROCEDURE Register*(s: Sink);
  184. VAR n: List;
  185. BEGIN {EXCLUSIVE}
  186. NEW(n); n.s := s; n.next := sentinel.next; sentinel.next := n
  187. END Register;
  188. PROCEDURE Unregister*(s: Sink);
  189. VAR n: List;
  190. BEGIN {EXCLUSIVE}
  191. n := sentinel;
  192. WHILE (n.next # NIL) & (n.next.s # s) DO n := n.next END;
  193. IF n.next # NIL THEN n.next := n.next.next END
  194. END Unregister;
  195. PROCEDURE Handle*(VAR msg: Message);
  196. VAR n: List;
  197. BEGIN {EXCLUSIVE}
  198. n := sentinel.next;
  199. WHILE n # NIL DO n.s.Handle(msg); n := n.next END
  200. END Handle;
  201. END Broadcaster;
  202. TYPE
  203. OberonInput* = OBJECT (Plugins.Plugin)
  204. VAR timer-: Kernel.Timer;
  205. PROCEDURE Mouse*(VAR x, y: INTEGER; VAR keys:SET);
  206. BEGIN
  207. HALT(99) (* abstract *)
  208. END Mouse;
  209. PROCEDURE Read*(VAR ch: CHAR; VAR break: BOOLEAN);
  210. BEGIN
  211. HALT(99) (* abstract *)
  212. END Read;
  213. PROCEDURE Available*(VAR num: INTEGER; VAR break: BOOLEAN);
  214. BEGIN
  215. HALT(99) (* abstract *)
  216. END Available;
  217. PROCEDURE KeyState*(VAR k: SET);
  218. BEGIN
  219. HALT(99) (* abstract *)
  220. END KeyState;
  221. PROCEDURE &Init*;
  222. BEGIN
  223. NEW(timer)
  224. END Init;
  225. END OberonInput;
  226. TYPE
  227. MouseFixer = OBJECT (Sink)
  228. VAR ctrl: BOOLEAN;
  229. PROCEDURE Handle*(VAR m: Message);
  230. VAR new: BOOLEAN;
  231. BEGIN {EXCLUSIVE}
  232. WITH m: KeyboardMsg DO
  233. new := m.flags * Ctrl # {};
  234. IF new # ctrl THEN
  235. ctrl := new;
  236. IF ctrl THEN main.SetKeys({1}) ELSE main.SetKeys({}) END
  237. END
  238. END
  239. END Handle;
  240. PROCEDURE &Init*;
  241. BEGIN
  242. ctrl := FALSE; keyboard.Register(SELF)
  243. END Init;
  244. END MouseFixer;
  245. VAR
  246. keyboard*, mouse*, pointer*: Group;
  247. main*: Pointer;
  248. oberonInput*: Plugins.Registry;
  249. mouseFixer: MouseFixer;
  250. (** Return a default message broadcaster instance. *)
  251. PROCEDURE NewBroadcaster*(): Group;
  252. VAR b: Broadcaster;
  253. BEGIN
  254. NEW(b); NEW(b.sentinel); b.sentinel.next := NIL;
  255. RETURN b
  256. END NewBroadcaster;
  257. PROCEDURE Init;
  258. VAR s: ARRAY 16 OF CHAR; i, threshold, speedup: LONGINT;
  259. BEGIN
  260. Machine.GetConfig("Threshold", s);
  261. i := 0; threshold := Machine.StrToInt(i, s);
  262. IF threshold <= 0 THEN threshold := 5 END;
  263. Machine.GetConfig("Speedup", s);
  264. i := 0; speedup := Machine.StrToInt(i, s);
  265. IF speedup <= 0 THEN speedup := 15 END;
  266. NEW(main, threshold, speedup);
  267. Machine.GetConfig("MB", s);
  268. IF (s = "2") OR (s = "-2") THEN NEW(mouseFixer) END
  269. END Init;
  270. BEGIN
  271. keyboard := NewBroadcaster();
  272. mouse := NewBroadcaster();
  273. pointer := NewBroadcaster();
  274. NEW(oberonInput, "Inputs", "Oberon input drivers");
  275. Init
  276. END Inputs.