home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / GEM / EVENTHAN.I < prev    next >
Encoding:
Text File  |  1993-05-21  |  22.7 KB  |  3 lines

  1. ⓪ IMPLEMENTATION MODULE EventHandler;
  2. ⓪ (*$L-, Y+*)
  3. ⓪ 
  4. ⓪ (*  Implementation des 'EventHandler's der Megamax Modula-2 Biblothek
  5. ⓪!*
  6. ⓪!*  geschrieben von Manuel Chakravarty          Created: 9.9.87
  7. ⓪!*
  8. ⓪!*  Version 2.2    V#0129
  9. ⓪!*)
  10. ⓪!
  11. ⓪ (* 09.09.87     | Definitionen
  12. ⓪!* 13.09.87     | 'InstallWatchDog' und 'DeInstallWatchDog' implementiert
  13. ⓪!* 21.09.87     | 'commonHandler' und seine Benutzer impl.+ time/msgHdler
  14. ⓪!* 22.09.87     | 'HandleEvents' impl.
  15. ⓪!* 28.09.87     | Message-Install's lösen bei einem 'HandleEvents' jetzt
  16. ⓪!*                autom. eine Abfrage nach Message-Events aus, diese Eve-
  17. ⓪!*                nts werden falls nicht Abgefangen noch mal mittels
  18. ⓪!*                'WriteToAppl' gesendet. 'ShareTime' impl.
  19. ⓪!* 30.09.87     | SysInstall impl.
  20. ⓪!* 07.11.87     | Anpassung an GEM V 0.10
  21. ⓪!* 19.01.88 TT  | levelCounter: deInstall korrgiert, searchList optimiert
  22. ⓪!* 30.03.88     | 'HandleEvents' ruft jetzt bei Msg.events nur noch die
  23. ⓪!*                Proc's auf, die für den aufgetrettenen Msg.event-Typ
  24. ⓪!*                angemeldet sind (einzige Ausnahme 'unspecMessage').
  25. ⓪!* 23.12.88     | 'ReadFromAppl' wird beim message add wirklich nur aufge-
  26. ⓪!*                rufen, falls die Nachricht länger als 16 Byte ist. Außerdem
  27. ⓪!*                wird des HIGH-Wert für die open arrays richtig übergeben.
  28. ⓪!* 01.03.89     | *** Def-Änderung *** auf 2.00. Neu: 'FlushEvents'
  29. ⓪!* 17.08.89     | 'KeyboardProc' um 'keys' erweitert
  30. ⓪!* 15.02.90     | Anpassung an Compilerversion 4.0
  31. ⓪!* 21.05.93 TT  | Reentry bei ShareTime/FlushEvents verhindert.
  32. ⓪!*)
  33. ⓪ 
  34. ⓪ 
  35. ⓪ FROM SYSTEM     IMPORT ASSEMBLER, WORD,
  36. ⓪7ADR;
  37. ⓪ 
  38. ⓪ FROM Storage    IMPORT ALLOCATE, DEALLOCATE;
  39. ⓪ 
  40. ⓪ FROM PrgCtrl    IMPORT EnvlpCarrier, TermCarrier,
  41. ⓪7CatchProcessTerm, SetEnvelope;
  42. ⓪ 
  43. ⓪ FROM ResCtrl    IMPORT RemovalCarrier,
  44. ⓪7CatchRemoval;
  45. ⓪ 
  46. ⓪ FROM MOSGlobals IMPORT OutOfMemory, MemArea;
  47. ⓪ 
  48. ⓪ FROM GrafBase   IMPORT Point, Rectangle,
  49. ⓪7Rect;
  50. ⓪2
  51. ⓪ FROM GEMGlobals IMPORT GemChar, MButtonSet, SpecialKeySet;
  52. ⓪4
  53. ⓪ IMPORT GEMShare;
  54. ⓪ 
  55. ⓪ FROM GEMEnv     IMPORT ApplicationID;
  56. ⓪ 
  57. ⓪ FROM AESEvents  IMPORT unspecMessage, menuSelected, windRedraw, windTopped,
  58. ⓪7windClosed, windFulled, windArrowed, windHSlid,
  59. ⓪7windVSlid, windSized, windMoved, windNewTop, accOpen,
  60. ⓪7accClose, Event, EventSet, ArrowedMode, MessageBuffer,
  61. ⓪7RectEnterMode,
  62. ⓪7MultiEvent;
  63. ⓪ 
  64. ⓪ FROM AESMisc    IMPORT ReadFromAppl, WriteToAppl;
  65. ⓪ 
  66. ⓪ 
  67. ⓪ 
  68. ⓪ TYPE    ptrCarrier      =POINTER TO carrier;
  69. ⓪(carrier         =RECORD
  70. ⓪;proc         :PROC;   (* Da Aufruf per JSR, sind *
  71. ⓪R* die Param. egal.        *)
  72. ⓪;CASE (*messageEvent*):BOOLEAN OF
  73. ⓪=FALSE : |
  74. ⓪=TRUE  : msgType:CARDINAL|
  75. ⓪;END;
  76. ⓪;next         :ptrCarrier;
  77. ⓪;level        :INTEGER;
  78. ⓪;(*future     :LONGWORD;*)
  79. ⓪9END;
  80. ⓪9
  81. ⓪ VAR     keyboardList,buttonList,stRectList,
  82. ⓪(ndRectList,messageList,timerList        :ptrCarrier;
  83. ⓪(
  84. ⓪(watchDogExecuted: BOOLEAN; (*  Semaphore between 'FlushEvents' and
  85. ⓪D*  the watch dog servers. *)
  86. ⓪(flushExecuted   : INTEGER; (*  semaphore f. FlushEvents/ShareTime *)
  87. ⓪(
  88. ⓪(modLevel        : INTEGER;
  89. ⓪(
  90. ⓪(voidI           : INTEGER;
  91. ⓪(
  92. ⓪(
  93. ⓪ (*  commonHandler - Führt Handling für 'keyboard', 'mouseButton', 'firstRect'
  94. ⓪!*                  'secondRect' durch. 'data' sind die Daten, die
  95. ⓪!*                  an die einzelnen Proc's als Parameter übergeben werden
  96. ⓪!*                  sollen. 'list' ist die zu bearbeitende Proc-Liste.
  97. ⓪!*)
  98. ⓪ (*$J-*)
  99. ⓪ PROCEDURE commonHandler(REF data: ARRAY OF WORD; list: ptrCarrier): BOOLEAN;
  100. ⓪ (*$J=*)
  101. ⓪ 
  102. ⓪"BEGIN
  103. ⓪$ASSEMBLER
  104. ⓪(MOVE.L  -(A3),A0        ; 'list' -> A0
  105. ⓪(MOVE.W  -(A3),D1        ; HIGH(data) -> D1
  106. ⓪(MOVE.L  -(A3),A1        ; ADR(data) -> A1
  107. ⓪(CMPA.L  #NIL,A0
  108. ⓪(BEQ     endTRUE         ; Leere List -> RETURN TRUE
  109. ⓪(
  110. ⓪(MOVE.W  #TRUE, watchDogExecuted
  111. ⓪ loop
  112. ⓪(MOVE.W  D1,D2           ; kopiere Param. auf A3-Stack
  113. ⓪(MOVE.L  A1,A2
  114. ⓪ loop2
  115. ⓪(MOVE.W  (A2)+,(A3)+
  116. ⓪(DBF     D2,loop2
  117. ⓪(MOVE.L  carrier.proc(A0),A2 ; Hole Proceduraddresse
  118. ⓪(MOVEM.L D1/A0-A1,-(A7)
  119. ⓪(JSR     (A2)                ; und springe Userproc. an
  120. ⓪(MOVEM.L (A7)+,D1/A0-A1
  121. ⓪(MOVE.L  carrier.next(A0),A0 ; hole Zeiger auf nächstes Listenelement
  122. ⓪(CMPA.L  #NIL,A0
  123. ⓪(BEQ     ende            ; Listenende? => Fertig.
  124. ⓪(TST.W   -(A3)
  125. ⓪(BNE     loop            ; Falls Userproc. keinen Abbruch wünscht weiter
  126. ⓪(MOVE.W  #FALSE,(A3)+
  127. ⓪(BRA     ende
  128. ⓪(
  129. ⓪ endTRUE
  130. ⓪(MOVE.W  #TRUE,(A3)+
  131. ⓪ ende
  132. ⓪$END;
  133. ⓪"END commonHandler;
  134. ⓪(
  135. ⓪ (*$J-*)
  136. ⓪ PROCEDURE keyboardHandler(VAR ch: GemChar; VAR keys: SpecialKeySet): BOOLEAN;
  137. ⓪ (*$J=*)
  138. ⓪ 
  139. ⓪ CONST   noParamB        =8;
  140. ⓪(noParamW        =noParamB DIV 2 - 1; (* -1, da HIGH mit 0 beginnt *)
  141. ⓪ 
  142. ⓪ BEGIN
  143. ⓪"ASSEMBLER
  144. ⓪(LEA     -noParamB(A3),A0
  145. ⓪(MOVE.L  A0,(A3)+
  146. ⓪(MOVE.W  #noParamW,(A3)+
  147. ⓪(MOVE.L  keyboardList,(A3)+
  148. ⓪(JSR     commonHandler
  149. ⓪(MOVE.W  -(A3),D0
  150. ⓪(SUBQ.L  #noParamB,A3
  151. ⓪(MOVE.W  D0,(A3)+
  152. ⓪"END;
  153. ⓪ END keyboardHandler;
  154. ⓪ 
  155. ⓪ (*$J-*)
  156. ⓪ PROCEDURE buttonHandler(clicks:CARDINAL;loc:Point;buts:MButtonSet;
  157. ⓪8specials:SpecialKeySet):BOOLEAN;
  158. ⓪ (*$J=*)
  159. ⓪8
  160. ⓪ CONST   noParamB        =10;
  161. ⓪(noParamW        =noParamB DIV 2 - 1;
  162. ⓪ 
  163. ⓪ BEGIN
  164. ⓪"ASSEMBLER
  165. ⓪(LEA     -noParamB(A3),A0
  166. ⓪(MOVE.L  A0,(A3)+
  167. ⓪(MOVE.W  #noParamW,(A3)+
  168. ⓪(MOVE.L  buttonList,(A3)+
  169. ⓪(JSR     commonHandler
  170. ⓪(MOVE.W  -(A3),D0
  171. ⓪(SUBA.W  #noParamB,A3
  172. ⓪(MOVE.W  D0,(A3)+
  173. ⓪"END;
  174. ⓪ END buttonHandler;
  175. ⓪ 
  176. ⓪ (*$J-*)
  177. ⓪ PROCEDURE stRectHandler(loc:Point;buts:MButtonSet;
  178. ⓪8specials:SpecialKeySet):BOOLEAN;
  179. ⓪ (*$J=*)
  180. ⓪ 
  181. ⓪ CONST   noParamB        =8;
  182. ⓪(noParamW        =noParamB DIV 2 - 1;
  183. ⓪ 
  184. ⓪ BEGIN
  185. ⓪"ASSEMBLER
  186. ⓪(LEA     -noParamB(A3),A0
  187. ⓪(MOVE.L  A0,(A3)+
  188. ⓪(MOVE.W  #noParamW,(A3)+
  189. ⓪(MOVE.L  stRectList,(A3)+
  190. ⓪(JSR     commonHandler
  191. ⓪(MOVE.W  -(A3),D0
  192. ⓪(SUBQ.L  #noParamB,A3
  193. ⓪(MOVE.W  D0,(A3)+
  194. ⓪"END;
  195. ⓪ END stRectHandler;
  196. ⓪ 
  197. ⓪ (*$J-*)
  198. ⓪ PROCEDURE ndRectHandler(loc:Point;buts:MButtonSet;
  199. ⓪8specials:SpecialKeySet):BOOLEAN;
  200. ⓪ (*$J=*)
  201. ⓪ 
  202. ⓪ CONST   noParamB        =8;
  203. ⓪(noParamW        =noParamB DIV 2 - 1;
  204. ⓪ 
  205. ⓪ BEGIN
  206. ⓪"ASSEMBLER
  207. ⓪(LEA     -noParamB(A3),A0
  208. ⓪(MOVE.L  A0,(A3)+
  209. ⓪(MOVE.W  #noParamW,(A3)+
  210. ⓪(MOVE.L  ndRectList,(A3)+
  211. ⓪(JSR     commonHandler
  212. ⓪(MOVE.W  -(A3),D0
  213. ⓪(SUBQ.L  #noParamB,A3
  214. ⓪(MOVE.W  D0,(A3)+
  215. ⓪"END;
  216. ⓪ END ndRectHandler;
  217. ⓪ 
  218. ⓪ (*$J-*)
  219. ⓪ PROCEDURE messageHandler(msg:MessageBuffer):BOOLEAN;
  220. ⓪ (*$J=*)
  221. ⓪ 
  222. ⓪ BEGIN
  223. ⓪"ASSEMBLER
  224. ⓪(LEA     -16(A3),A0      ; ADR(msg) -> A0
  225. ⓪(MOVE.W  (A0),D0         ; msg[0] (type of the message) -> D0
  226. ⓪@; CASE msg[0] OF
  227. ⓪(CMP.W   #menuSelected,D0
  228. ⓪(BEQ     copy2
  229. ⓪(CMP.W   #windRedraw,D0
  230. ⓪(BEQ     copy5
  231. ⓪(CMP.W   #windTopped,D0
  232. ⓪(BEQ     copy1
  233. ⓪(CMP.W   #windClosed,D0
  234. ⓪(BEQ     copy1
  235. ⓪(CMP.W   #windFulled,D0
  236. ⓪(BEQ     copy1
  237. ⓪(CMP.W   #windArrowed,D0
  238. ⓪(BEQ     copy2
  239. ⓪(CMP.W   #windHSlid,D0
  240. ⓪(BEQ     copy2
  241. ⓪(CMP.W   #windVSlid,D0
  242. ⓪(BEQ     copy2
  243. ⓪(CMP.W   #windSized,D0
  244. ⓪(BEQ     copy5
  245. ⓪(CMP.W   #windMoved,D0
  246. ⓪(BEQ     copy5
  247. ⓪(CMP.W   #windNewTop,D0
  248. ⓪(BEQ     copy1
  249. ⓪(CMP.W   #accOpen,D0
  250. ⓪(BEQ     copy1from4
  251. ⓪(CMP.W   #accClose,D0
  252. ⓪(BEQ     copy1
  253. ⓪(
  254. ⓪(MOVEQ   #unspecMessage,D0  ; keine message vom AES
  255. ⓪(LEA     (A0),A1
  256. ⓪(MOVEQ   #7,D1
  257. ⓪(BRA     cont
  258. ⓪(
  259. ⓪ copy1
  260. ⓪(LEA     6(A0),A1        ; ab msg[3]
  261. ⓪(MOVEQ   #0,D1           ; 1 Wort
  262. ⓪(BRA     cont
  263. ⓪(
  264. ⓪ copy1from4
  265. ⓪(LEA     8(A0),A1
  266. ⓪(MOVEQ   #0,D1
  267. ⓪(BRA     cont
  268. ⓪(
  269. ⓪ copy2
  270. ⓪(LEA     6(A0),A1
  271. ⓪(MOVEQ   #1,D1
  272. ⓪(BRA     cont
  273. ⓪ 
  274. ⓪ copy5
  275. ⓪(LEA     6(A0),A1
  276. ⓪(MOVEQ   #4,D1
  277. ⓪(
  278. ⓪ cont
  279. ⓪(MOVEQ   #TRUE,D2        ; init. momentanes Ergebnis
  280. ⓪(MOVE.L  messageList,A2
  281. ⓪(
  282. ⓪ loop
  283. ⓪(CMPA.L  #NIL,A2
  284. ⓪(BEQ     ende            ; Falls Listenende, dann Fertig.
  285. ⓪(CMP.W   carrier.msgType(A2),D0
  286. ⓪(BEQ     typeMatch       ; springe, falls Listenelem.typ = ges. Typ
  287. ⓪(TST.W   carrier.msgType(A2)
  288. ⓪(BNE     skipElem        ; springe, falls Listenelem.typ # unspecMessage
  289. ⓪(MOVEM.L D0-D1/A0-A2,-(A7)
  290. ⓪(MOVE.L  A0,A1           ; Kopierparam. für 'unspecMessage'
  291. ⓪(MOVEQ   #7,D1
  292. ⓪(BRA     loop2
  293. ⓪(
  294. ⓪ typeMatch
  295. ⓪(MOVEM.L D0-D1/A0-A2,-(A7)
  296. ⓪ loop2
  297. ⓪(MOVE.W  (A1)+,(A3)+     ; kopiere Param.
  298. ⓪(DBF     D1,loop2
  299. ⓪(MOVE.L  carrier.proc(A2),A2
  300. ⓪(JSR     (A2)            ; springe Userproc. an
  301. ⓪(MOVEM.L (A7)+,D0-D1/A0-A2
  302. ⓪(MOVE.W  -(A3),D2        ; neues momentanes Ergebnis -> D2
  303. ⓪ skipElem
  304. ⓪(MOVE.L  carrier.next(A2),A2 ; nächstes Listenelem.
  305. ⓪(TST.W   D2
  306. ⓪(BNE     loop            ; nochmal, falls momentanes Ergebnis # FALSE
  307. ⓪(
  308. ⓪(MOVE.W  #TRUE, watchDogExecuted
  309. ⓪ ende
  310. ⓪(MOVE.L  A0,A3           ; A3-Stack korrigieren
  311. ⓪(MOVE.W  D2,(A3)+        ; momentanes Ergebnis zurückgeben
  312. ⓪"END;
  313. ⓪ END messageHandler;
  314. ⓪ 
  315. ⓪ (*$J-*)
  316. ⓪ PROCEDURE timerHandler():BOOLEAN;
  317. ⓪ (*$J=*)
  318. ⓪ 
  319. ⓪ BEGIN
  320. ⓪"ASSEMBLER
  321. ⓪(MOVE.L  timerList,A0
  322. ⓪(CMPA.L  #NIL,A0
  323. ⓪(BEQ     endTRUE         ; Leere List -> RETURN TRUE
  324. ⓪(
  325. ⓪ loop
  326. ⓪(MOVE.L  carrier.proc(A0),A2 ; Hole Proceduraddresse
  327. ⓪(MOVE.L  A0,-(A7)
  328. ⓪(JSR     (A2)                ; und springe Userproc. an
  329. ⓪(MOVE.L  (A7)+,A0
  330. ⓪(MOVE.L  carrier.next(A0),A0 ; hole Zeiger auf nächstes Listenelement
  331. ⓪(CMPA.L  #NIL,A0
  332. ⓪(BEQ     ende            ; Listenende? => Fertig.
  333. ⓪(TST.W   -(A3)
  334. ⓪(BNE     loop            ; Falls Userproc. keinen Abbruch wünscht weiter
  335. ⓪(MOVE.W  #FALSE,(A3)+
  336. ⓪(BRA     ende
  337. ⓪(
  338. ⓪ endTRUE
  339. ⓪(MOVE.W  #TRUE,(A3)+
  340. ⓪ ende
  341. ⓪"END;
  342. ⓪ END timerHandler;
  343. ⓪ 
  344. ⓪ 
  345. ⓪ PROCEDURE InstallWatchDog(VAR handle:WatchDogCarrier;proc:EventProc);
  346. ⓪ 
  347. ⓪ BEGIN
  348. ⓪"ASSEMBLER
  349. ⓪(MOVE.L  -(A3),-(A7)
  350. ⓪(MOVE.L  -(A3),D0
  351. ⓪(MOVE.W  D0,-(A7)
  352. ⓪(SWAP    D0              ; 'proc.event' -> D0
  353. ⓪(CMP.W   #keyboard,D0    ; CASE proc.event OF
  354. ⓪(BEQ     installKey
  355. ⓪(CMP.W   #mouseButton,D0
  356. ⓪(BEQ     installBut
  357. ⓪(CMP.W   #firstRect,D0
  358. ⓪(BEQ.W   installSt
  359. ⓪(CMP.W   #secondRect,D0
  360. ⓪(BEQ.W   installNd
  361. ⓪(CMP.W   #message,D0
  362. ⓪(BEQ.W   installMsg
  363. ⓪(CMP.W   #timer,D0
  364. ⓪(BEQ.W   installTime
  365. ⓪(TST.W   (A7)+           ; an diesen Punkt kommt man theoretisch nie
  366. ⓪(TST.L   (A7)+
  367. ⓪(BRA.W   ende
  368. ⓪(
  369. ⓪ installKey                      ; install keyboard watch dog
  370. ⓪(TST.L   keyboardList
  371. ⓪(BNE     keyActive       ; jump if 'keyboardList#NIL' (already plugged)
  372. ⓪(LEA     keyboardHandler,A0
  373. ⓪(MOVE.L  A0,keyboardPlug ; plug into the 'GEMshare.keyboardPlug'
  374. ⓪(MOVE.W  #TRUE,keyboardPlugActive
  375. ⓪ keyActive
  376. ⓪(MOVE.L  -(A3),A0        ; ADR(handle) -> A0
  377. ⓪(MOVE.W  modLevel,carrier.level(A0)
  378. ⓪(MOVE.L  (A7)+,carrier.proc(A0) ; init. carrier and make it first
  379. ⓪(TST.W   (A7)+                  ; element of the keyboard carrier list
  380. ⓪(MOVE.L  keyboardList,carrier.next(A0)
  381. ⓪(MOVE.L  A0,keyboardList
  382. ⓪(BRA.W   ende
  383. ⓪(
  384. ⓪ installBut                      ; install mouse button watch dog
  385. ⓪(TST.L   buttonList
  386. ⓪(BNE     butActive
  387. ⓪(LEA     buttonHandler,A0
  388. ⓪(MOVE.L  A0,buttonPlug
  389. ⓪(MOVE.W  #TRUE,buttonPlugActive
  390. ⓪ butActive
  391. ⓪(MOVE.L  -(A3),A0
  392. ⓪(MOVE.W  modLevel,carrier.level(A0)
  393. ⓪(MOVE.L  (A7)+,carrier.proc(A0)
  394. ⓪(TST.W   (A7)+
  395. ⓪(MOVE.L  buttonList,carrier.next(A0)
  396. ⓪(MOVE.L  A0,buttonList
  397. ⓪(BRA.W   ende
  398. ⓪(
  399. ⓪ installSt
  400. ⓪(TST.L   stRectList
  401. ⓪(BNE     stActive
  402. ⓪(LEA     stRectHandler,A0
  403. ⓪(MOVE.L  A0,firstRectPlug
  404. ⓪(MOVE.W  #TRUE,firstRectPlugActive
  405. ⓪ stActive
  406. ⓪(MOVE.L  -(A3),A0
  407. ⓪(MOVE.W  modLevel,carrier.level(A0)
  408. ⓪(MOVE.L  (A7)+,carrier.proc(A0)
  409. ⓪(TST.W   (A7)+
  410. ⓪(MOVE.L  stRectList,carrier.next(A0)
  411. ⓪(MOVE.L  A0,stRectList
  412. ⓪(BRA.W   ende
  413. ⓪(
  414. ⓪ installNd
  415. ⓪(TST.L   ndRectList
  416. ⓪(BNE     ndActive
  417. ⓪(LEA     ndRectHandler,A0
  418. ⓪(MOVE.L  A0,secondRectPlug
  419. ⓪(MOVE.W  #TRUE,secondRectPlugActive
  420. ⓪ ndActive
  421. ⓪(MOVE.L  -(A3),A0
  422. ⓪(MOVE.W  modLevel,carrier.level(A0)
  423. ⓪(MOVE.L  (A7)+,carrier.proc(A0)
  424. ⓪(TST.W   (A7)+
  425. ⓪(MOVE.L  ndRectList,carrier.next(A0)
  426. ⓪(MOVE.L  A0,ndRectList
  427. ⓪(BRA     ende
  428. ⓪(
  429. ⓪ installMsg                      ; install message event watch dog
  430. ⓪(TST.L   messageList
  431. ⓪(BNE     msgActive       ; already plugged ?
  432. ⓪(LEA     messageHandler,A0 ; if not plug in
  433. ⓪(MOVE.L  A0,messagePlug
  434. ⓪(MOVE.W  #TRUE,messagePlugActive
  435. ⓪ msgActive
  436. ⓪(MOVE.L  -(A3),A0        ; ADR(handle) -> A0
  437. ⓪(MOVE.W  modLevel,carrier.level(A0)
  438. ⓪(MOVE.W  (A7)+,carrier.msgType(A0) ; save type of message event -> handle
  439. ⓪(MOVE.L  (A7)+,carrier.proc(A0)    ; procedure address -> handle
  440. ⓪(MOVE.L  messageList,carrier.next(A0) ; insert into message list
  441. ⓪(MOVE.L  A0,messageList
  442. ⓪(BRA     ende
  443. ⓪(
  444. ⓪ installTime
  445. ⓪(TST.L   timerList
  446. ⓪(BNE     timeActive
  447. ⓪(LEA     timerHandler,A0
  448. ⓪(MOVE.L  A0,timerPlug
  449. ⓪(MOVE.W  #TRUE,timerPlugActive
  450. ⓪ timeActive
  451. ⓪(MOVE.L  -(A3),A0
  452. ⓪(MOVE.W  modLevel,carrier.level(A0)
  453. ⓪(MOVE.L  (A7)+,carrier.proc(A0)
  454. ⓪(TST.W   (A7)+
  455. ⓪(MOVE.L  timerList,carrier.next(A0)
  456. ⓪(MOVE.L  A0,timerList
  457. ⓪(
  458. ⓪ ende
  459. ⓪"END;
  460. ⓪ END InstallWatchDog;
  461. ⓪ 
  462. ⓪ PROCEDURE SysInstallWatchDog(VAR handle:WatchDogCarrier;proc:EventProc);
  463. ⓪ 
  464. ⓪ BEGIN
  465. ⓪"ASSEMBLER
  466. ⓪(MOVE.L  -12(A3),-(A7)
  467. ⓪(JSR     InstallWatchDog
  468. ⓪(MOVE.L  (A7)+,A0
  469. ⓪(CLR     carrier.level(A0)
  470. ⓪"END;
  471. ⓪ END SysInstallWatchDog;
  472. ⓪ 
  473. ⓪ PROCEDURE DeInstallWatchDog(VAR handle:WatchDogCarrier);
  474. ⓪ 
  475. ⓪ BEGIN
  476. ⓪"ASSEMBLER
  477. ⓪(MOVE.L  -(A3),D1
  478. ⓪(MOVEQ   #5,D0   ; There are 5+1 lists
  479. ⓪(PEA     keyboardList
  480. ⓪(PEA     buttonList
  481. ⓪(PEA     ndRectList
  482. ⓪(PEA     stRectList
  483. ⓪(PEA     messageList
  484. ⓪(PEA     timerList
  485. ⓪ loop
  486. ⓪(MOVE.L  (A7)+,A0
  487. ⓪ loop2
  488. ⓪(MOVE.L  (A0),A1
  489. ⓪(CMPA.L  #NIL,A1
  490. ⓪(BEQ     listEnd
  491. ⓪(CMP.L   A1,D1
  492. ⓪(BEQ     foundHandle
  493. ⓪(LEA     carrier.next(A1),A0
  494. ⓪(BRA     loop2
  495. ⓪ listEnd
  496. ⓪(DBF     D0,loop
  497. ⓪(BRA     ende                    ; handle was not installed
  498. ⓪ 
  499. ⓪ foundHandle
  500. ⓪(LSL.W   #2,D0           ; pop remaining list pointer from the stack
  501. ⓪(ADDA.W  D0,A7           ; A7:=A7+D0*4
  502. ⓪(MOVE.L  carrier.next(A1),(A0)  ; delete 'handle' out of the list
  503. ⓪(TST.L   timerList
  504. ⓪(BNE     cont1
  505. ⓪(CLR.W   timerPlugActive
  506. ⓪ cont1
  507. ⓪(TST.L   messageList
  508. ⓪(BNE     cont2
  509. ⓪(CLR.W   messagePlugActive
  510. ⓪ cont2
  511. ⓪(TST.L   ndRectList
  512. ⓪(BNE     cont3
  513. ⓪(CLR.W   secondRectPlugActive
  514. ⓪ cont3
  515. ⓪(TST.L   stRectList
  516. ⓪(BNE     cont4
  517. ⓪(CLR.W   firstRectPlugActive
  518. ⓪ cont4
  519. ⓪(TST.L   buttonList
  520. ⓪(BNE     cont5
  521. ⓪(CLR.W   buttonPlugActive
  522. ⓪ cont5
  523. ⓪(TST.L   keyboardList
  524. ⓪(BNE     ende
  525. ⓪(CLR.W   keyboardPlugActive
  526. ⓪ ende
  527. ⓪"END;
  528. ⓪ END DeInstallWatchDog;
  529. ⓪ 
  530. ⓪ PROCEDURE HandleEvents (    noClicks  : CARDINAL;
  531. ⓪<butMask,
  532. ⓪<butState  : MButtonSet;
  533. ⓪<moveDirec1: RectEnterMode;
  534. ⓪<rect1Size : Rectangle;
  535. ⓪<moveDirec2: RectEnterMode;
  536. ⓪<rect2Size : Rectangle;
  537. ⓪<time      : LONGCARD;
  538. ⓪8REF procs     : ARRAY OF EventProc;
  539. ⓪<usedProcs : CARDINAL);
  540. ⓪8
  541. ⓪ CONST   procRecSize     = 8; (* Länge des 'eventProc'-Typs *)
  542. ⓪ 
  543. ⓪ VAR     msg             : MessageBuffer;
  544. ⓪(mouseLoc        : Point;
  545. ⓪(buttons         : MButtonSet;
  546. ⓪(keyState        : SpecialKeySet;
  547. ⓪(key             : GemChar;
  548. ⓪(doneClicks, i   : CARDINAL;
  549. ⓪(eventResult     : EventSet;
  550. ⓪(handlerResult   : BOOLEAN;
  551. ⓪(momEvent        : Event;
  552. ⓪(
  553. ⓪(msgAdd          : BOOLEAN;
  554. ⓪(a7Store         : LONGCARD;
  555. ⓪7
  556. ⓪ (*$L+*)
  557. ⓪ BEGIN
  558. ⓪"ASSEMBLER
  559. ⓪8; last used index of 'procs' -> 'usedProcs' and D0
  560. ⓪(MOVE.W  usedProcs(A6),D0
  561. ⓪(MOVE.W  procs+4(A6),D1
  562. ⓪(TST.W   D0
  563. ⓪(BEQ     takeHigh
  564. ⓪(SUBQ.W  #1,D0
  565. ⓪(CMP.W   D0,D1
  566. ⓪(BCC     cont
  567. ⓪ takeHigh
  568. ⓪(MOVE.W  D1,D0
  569. ⓪ cont
  570. ⓪(MOVE.W  D0,usedProcs(A6)
  571. ⓪8; Rufe MultiEvent auf, Ergebnis in 'eventResult'
  572. ⓪(CLR.W   D1              ; registrierte events
  573. ⓪(MOVE.L  procs(A6),A0
  574. ⓪ loop1
  575. ⓪(MOVE.W  EventProc.event(A0),D2
  576. ⓪(BSET    D2,D1           ; registriere den gefundenen Event
  577. ⓪(ADDQ.L  #procRecSize,A0 ; nächstes Arrayelement
  578. ⓪(DBF     D0,loop1
  579. ⓪<; Zusätzlich message event falls nötig
  580. ⓪(CLR.W   msgAdd(A6)
  581. ⓪(BTST    #message,D1
  582. ⓪(BNE     noMsgAdd        ; message event schon gesetzt => springe
  583. ⓪(TST.L   messageList
  584. ⓪(BEQ     noMsgAdd        ; message Liste leer => springe
  585. ⓪(MOVE.W  #TRUE,msgAdd(A6); message add erforderlich
  586. ⓪(BSET    #message,D1
  587. ⓪ noMsgAdd
  588. ⓪ 
  589. ⓪(MOVE.B  D1,(A3)+
  590. ⓪(ADDQ.L  #1, A3          ; possible events auf den Stack
  591. ⓪(LEA     noClicks(A6),A0
  592. ⓪(MOVEQ   #12,D0          ; 'noClicks' bis 'rect2Size' auf den Stack
  593. ⓪ loop2
  594. ⓪(MOVE.W  (A0)+,(A3)+
  595. ⓪(DBF     D0,loop2
  596. ⓪(LEA     msg(A6),A0
  597. ⓪(MOVE.L  A0,(A3)+
  598. ⓪(MOVE.L  time(A6),(A3)+
  599. ⓪(LEA     mouseLoc(A6),A0
  600. ⓪(MOVE.L  A0,(A3)+
  601. ⓪(LEA     buttons(A6),A0
  602. ⓪(MOVE.L  A0,(A3)+
  603. ⓪(LEA     keyState(A6),A0
  604. ⓪(MOVE.L  A0,(A3)+
  605. ⓪(LEA     key(A6),A0
  606. ⓪(MOVE.L  A0,(A3)+
  607. ⓪(LEA     doneClicks(A6),A0
  608. ⓪(MOVE.L  A0,(A3)+
  609. ⓪(LEA     eventResult(A6),A0
  610. ⓪(MOVE.L  A0,(A3)+                ; 'eventResult' als VAR-Parameter
  611. ⓪(JSR     MultiEvent
  612. ⓪(MOVE.B  eventResult(A6),D0
  613. ⓪(
  614. ⓪8; beachte message add
  615. ⓪(TST.W   msgAdd(A6)
  616. ⓪(BEQ.W   noMsgAdd2
  617. ⓪(BTST    #message,D0
  618. ⓪(BEQ.W   noMsgAdd2
  619. ⓪(BCLR    #message,eventResult(A6)
  620. ⓪(MOVEQ   #0,D0
  621. ⓪(MOVE.W  msg+4(A6),D0
  622. ⓪(ADD.L   #16,D0          ; msg[2]+16 (Länge der message) -> D0
  623. ⓪(MOVE.L  A7,A0
  624. ⓪(SUBA.L  D0,A0
  625. ⓪(SUBA.W  #300,A0         ; 300 Byte Sicherheitszone für Stack
  626. ⓪(CMPA.L  A3,A0
  627. ⓪(BCC     enoughStack
  628. ⓪(LEA     a7Store(A6),A0
  629. ⓪(MOVE.L  A0,(A3)+
  630. ⓪(MOVE.L  D0,(A3)+
  631. ⓪(JSR     ALLOCATE
  632. ⓪(MOVE.L  a7Store(A6),A0  ; ADR(buffer) -> A0
  633. ⓪(CLR.L   a7Store(A6)     ; Bedeutet: Benötigter Speicher nicht vom Stack
  634. ⓪(CMPA.L  #NIL,A0
  635. ⓪(BNE     allocOk
  636. ⓪(TRAP    #noErrorTrap
  637. ⓪(DC.W    OutOfMemory
  638. ⓪(BRA.W   noMsgAdd2
  639. ⓪ enoughStack
  640. ⓪(MOVE.L  A7,a7Store(A6)
  641. ⓪(SUBA.L  D0,A7
  642. ⓪(MOVE.L  A7,A0           ; ADR(buffer) -> A0
  643. ⓪ allocOk
  644. ⓪(MOVE.L  msg(A6),(A0)
  645. ⓪(MOVE.L  msg+4(A6),4(A0)
  646. ⓪(MOVE.L  msg+8(A6),8(A0)
  647. ⓪(MOVE.L  msg+12(A6),12(A0)
  648. ⓪(
  649. ⓪(MOVE.L  A0,-(A7)
  650. ⓪(TST.W   msg+4(A6)
  651. ⓪(BEQ     noReadFromAppl
  652. ⓪(
  653. ⓪(JSR     ApplicationID
  654. ⓪(MOVE.L  (A7)+,A0
  655. ⓪(MOVE.L  A0,D0
  656. ⓪(ADD.L   #16,D0
  657. ⓪(MOVE.L  D0,(A3)+
  658. ⓪(MOVE.W  msg+4(A6),(A3)+
  659. ⓪(SUBQ.W  #1,-2(A3)       ; HIGH-Value is "no. elem.s" - 1
  660. ⓪(CLR.W   (A3)+
  661. ⓪(MOVE.L  A0,-(A7)
  662. ⓪(JSR     ReadFromAppl    ; ReadFromAppl(Appl...ID(),buffer[16..],0)
  663. ⓪ 
  664. ⓪ noReadFromAppl
  665. ⓪(JSR     ApplicationID
  666. ⓪(MOVE.L  (A7)+,A0
  667. ⓪(MOVE.L  A0,(A3)+
  668. ⓪(MOVE.W  msg+4(A6),D0
  669. ⓪(ADD.W   #16,D0
  670. ⓪(MOVE.W  D0,(A3)+
  671. ⓪(SUBQ.W  #1,-2(A3)       ; HIGH-Value is "no. elem.s" - 1
  672. ⓪(CLR.W   (A3)+
  673. ⓪(MOVE.L  A0,-(A7)
  674. ⓪(JSR     WriteToAppl     ; WriteToAppl(ApplicationID(),buffer,0)
  675. ⓪(MOVE.L  (A7)+,A0
  676. ⓪(
  677. ⓪(MOVE.L  a7Store(A6),D0
  678. ⓪(BEQ     dealloc
  679. ⓪(MOVE.L  D0,A7
  680. ⓪(BRA     noMsgAdd2
  681. ⓪ dealloc
  682. ⓪(MOVE.L  A0,(A3)+
  683. ⓪(CLR.L   (A3)+
  684. ⓪(JSR     DEALLOCATE
  685. ⓪ noMsgAdd2
  686. ⓪@; call procs
  687. ⓪(CLR.W   i(A6)
  688. ⓪ loop3
  689. ⓪(MOVE.W  i(A6),D0
  690. ⓪(MOVE.W  usedProcs(A6),D1
  691. ⓪(CMP.W   D0,D1
  692. ⓪(BCS.W   ende
  693. ⓪(MOVEQ   #0,D2
  694. ⓪(MOVE.B  eventResult(A6),D2      ; eventResult -> D2
  695. ⓪(BEQ.W   ende
  696. ⓪(MOVE.W  D0,D1
  697. ⓪(MULU    #procRecSize,D1
  698. ⓪(MOVE.L  procs(A6),A0
  699. ⓪(ADDA.W  D1,A0
  700. ⓪(MOVE.W  EventProc.event(A0),D1  ; proc[i].event -> D1
  701. ⓪(MOVE.W  D1,momEvent(A6)         ; momEvent:=proc[i].event
  702. ⓪(BTST    D1,D2
  703. ⓪(BEQ.W   noMatch
  704. ⓪(MOVE.L  2(A0),A1   ; proc[i].proc -> A1 (proc[i].event#message)
  705. ⓪(CMP.W   #keyboard,D1
  706. ⓪(BEQ     keyCall
  707. ⓪(CMP.W   #mouseButton,D1
  708. ⓪(BEQ     butCall
  709. ⓪(CMP.W   #firstRect,D1
  710. ⓪(BEQ     stRCall
  711. ⓪(CMP.W   #secondRect,D1
  712. ⓪(BEQ     ndRCall
  713. ⓪(CMP.W   #message,D1
  714. ⓪(BEQ     msgCall
  715. ⓪(CMP.W   #timer,D1
  716. ⓪(BEQ.W   tmrCall
  717. ⓪(BRA.W   noMatch
  718. ⓪ keyCall
  719. ⓪(LEA     key(A6),A0
  720. ⓪(MOVE.L  A0,(A3)+
  721. ⓪(LEA     keyState(A6),A0
  722. ⓪(MOVE.L  A0,(A3)+
  723. ⓪(JSR     (A1)
  724. ⓪(BRA.W   caseEnd
  725. ⓪ butCall
  726. ⓪(MOVE.W  doneClicks(A6),(A3)+
  727. ⓪(MOVE.L  mouseLoc(A6),(A3)+
  728. ⓪(MOVE.B  buttons(A6),(A3)+
  729. ⓪(ADDQ.L  #1, A3
  730. ⓪(MOVE.B  keyState(A6),(A3)+
  731. ⓪(ADDQ.L  #1, A3
  732. ⓪(JSR     (A1)
  733. ⓪(BRA.W   caseEnd
  734. ⓪ stRCall
  735. ⓪ ndRCall
  736. ⓪(MOVE.L  mouseLoc(A6),(A3)+
  737. ⓪(MOVE.B  buttons(A6),(A3)+
  738. ⓪(ADDQ.L  #1, A3
  739. ⓪(MOVE.B  keyState(A6),(A3)+
  740. ⓪(ADDQ.L  #1, A3
  741. ⓪(JSR     (A1)
  742. ⓪(BRA.W   caseEnd
  743. ⓪ 
  744. ⓪ msgCall                 ; in A0 ist noch ADR(proc[i])
  745. ⓪(MOVE.W  EventProc.msgType(A0),D1
  746. ⓪(
  747. ⓪(; Ist die Proc. vom Typ 'uspecMessage', so bekommt sie den Msg.event
  748. ⓪(; sowieso, egal von welchem Typ er ist.
  749. ⓪(
  750. ⓪(CMP.W   #unspecMessage,D1
  751. ⓪(BEQ     copy8from0
  752. ⓪(
  753. ⓪(; Sonst, muß der Typ des Msg.events gleich dem Typ sein, für den die
  754. ⓪(; Proc. angemeldet ist.
  755. ⓪(
  756. ⓪(CMP.W   msg(A6),D1      ; Proc-Typ = Event-Typ ?
  757. ⓪(BNE.W   noMatch         ; Nein! => Kein Aufruf der Proc.
  758. ⓪(
  759. ⓪(CMP.W   #menuSelected,D1
  760. ⓪(BEQ     copy2
  761. ⓪(CMP.W   #windRedraw,D1
  762. ⓪(BEQ     copy5
  763. ⓪(CMP.W   #windTopped,D1
  764. ⓪(BEQ     copy1
  765. ⓪(CMP.W   #windClosed,D1
  766. ⓪(BEQ     copy1
  767. ⓪(CMP.W   #windFulled,D1
  768. ⓪(BEQ     copy1
  769. ⓪(CMP.W   #windArrowed,D1
  770. ⓪(BEQ     copy2
  771. ⓪(CMP.W   #windHSlid,D1
  772. ⓪(BEQ     copy2
  773. ⓪(CMP.W   #windVSlid,D1
  774. ⓪(BEQ     copy2
  775. ⓪(CMP.W   #windSized,D1
  776. ⓪(BEQ     copy5
  777. ⓪(CMP.W   #windMoved,D1
  778. ⓪(BEQ     copy5
  779. ⓪(CMP.W   #windNewTop,D1
  780. ⓪(BEQ     copy1
  781. ⓪(CMP.W   #accOpen,D1
  782. ⓪(BEQ     copy1from4
  783. ⓪(CMP.W   #accClose,D1
  784. ⓪(BEQ     copy1
  785. ⓪(BRA.W   noMatch
  786. ⓪'
  787. ⓪ copy8from0
  788. ⓪(LEA     msg(A6),A2
  789. ⓪(MOVEQ   #7,D1
  790. ⓪(BRA     doIt
  791. ⓪(
  792. ⓪ copy1
  793. ⓪(LEA     msg+6(A6),A2    ; ab msg[3]
  794. ⓪(MOVEQ   #0,D1           ; 1 Wort
  795. ⓪(BRA     doIt
  796. ⓪(
  797. ⓪ copy1from4
  798. ⓪(LEA     msg+8(A6),A2
  799. ⓪(MOVEQ   #0,D1
  800. ⓪(BRA     doIt
  801. ⓪(
  802. ⓪ copy2
  803. ⓪(LEA     msg+6(A6),A2
  804. ⓪(MOVEQ   #1,D1
  805. ⓪(BRA     doIt
  806. ⓪ 
  807. ⓪ copy5
  808. ⓪(LEA     msg+6(A6),A2
  809. ⓪(MOVEQ   #4,D1
  810. ⓪ doIt
  811. ⓪(MOVE.L  4(A0),A1        ; proc[i].proc -> A1
  812. ⓪ copyLoop
  813. ⓪(MOVE.W  (A2)+,(A3)+
  814. ⓪(DBF     D1,copyLoop
  815. ⓪(JSR     (A1)
  816. ⓪(BRA.W   caseEnd
  817. ⓪ tmrCall
  818. ⓪(JSR     (A1)
  819. ⓪ caseEnd
  820. ⓪(TST.W   -(A3)
  821. ⓪(BNE     noMatch
  822. ⓪(MOVE.W  momEvent(A6),D0
  823. ⓪(BCLR    D0,eventResult(A6)
  824. ⓪ noMatch
  825. ⓪(ADDQ.W  #1,i(A6)
  826. ⓪(BRA.W   loop3
  827. ⓪ ende
  828. ⓪"END;
  829. ⓪ END HandleEvents;
  830. ⓪ (*$L=*)
  831. ⓪ 
  832. ⓪ 
  833. ⓪ (*$L+*)
  834. ⓪ 
  835. ⓪ (*$J-*)
  836. ⓪ PROCEDURE dummy (): BOOLEAN;
  837. ⓪ (*$J=*)
  838. ⓪ 
  839. ⓪"BEGIN
  840. ⓪$RETURN TRUE;
  841. ⓪"END dummy;
  842. ⓪ 
  843. ⓪ PROCEDURE ShareTime (time: LONGCARD);
  844. ⓪"
  845. ⓪"VAR     theProc: EventProc;
  846. ⓪"
  847. ⓪"BEGIN
  848. ⓪$IF flushExecuted <= 2 THEN (* erlaubt 2 Rekursionslevel *)
  849. ⓪&INC (flushExecuted);
  850. ⓪&theProc.event := timer;
  851. ⓪&theProc.timeHdler := dummy;
  852. ⓪&HandleEvents(0, MButtonSet{}, MButtonSet{},
  853. ⓪3lookForEntry, Rect(0,0,0,0), lookForEntry, Rect(0,0,0,0),
  854. ⓪3time, theProc, 0);
  855. ⓪&DEC (flushExecuted);
  856. ⓪$END
  857. ⓪"END ShareTime;
  858. ⓪ 
  859. ⓪ PROCEDURE FlushEvents;
  860. ⓪ 
  861. ⓪"BEGIN
  862. ⓪&REPEAT
  863. ⓪(watchDogExecuted := FALSE;
  864. ⓪(ShareTime (0L);
  865. ⓪&UNTIL NOT watchDogExecuted;
  866. ⓪"END FlushEvents;
  867. ⓪"
  868. ⓪ 
  869. ⓪8(*  misc. managment  *)
  870. ⓪8(*  ===============  *)
  871. ⓪ 
  872. ⓪ PROCEDURE levelCounter(start,child:BOOLEAN; VAR id:INTEGER);
  873. ⓪ 
  874. ⓪"PROCEDURE searchList(list:ptrCarrier);
  875. ⓪"
  876. ⓪$VAR  nlist: ptrCarrier;
  877. ⓪"
  878. ⓪$BEGIN
  879. ⓪&WHILE list # NIL DO
  880. ⓪(nlist:=list^.next;
  881. ⓪(IF list^.level>=modLevel THEN
  882. ⓪*ASSEMBLER
  883. ⓪,MOVE.L  list(A6),(A3)+
  884. ⓪,JSR     DeInstallWatchDog
  885. ⓪*END
  886. ⓪(END;
  887. ⓪(list:= nlist
  888. ⓪&END
  889. ⓪$END searchList;
  890. ⓪"
  891. ⓪"BEGIN
  892. ⓪$IF child THEN
  893. ⓪&IF start THEN INC(modLevel)
  894. ⓪&ELSE
  895. ⓪(searchList(keyboardList);
  896. ⓪(searchList(buttonList);
  897. ⓪(searchList(stRectList);
  898. ⓪(searchList(ndRectList);
  899. ⓪(searchList(messageList);
  900. ⓪(searchList(timerList);
  901. ⓪(DEC(modLevel);
  902. ⓪&END;
  903. ⓪$END;
  904. ⓪"END levelCounter;
  905. ⓪ 
  906. ⓪ PROCEDURE termProc;
  907. ⓪ 
  908. ⓪"BEGIN
  909. ⓪$levelCounter(FALSE,TRUE, voidI);
  910. ⓪"END termProc;
  911. ⓪ 
  912. ⓪ PROCEDURE removalProc;
  913. ⓪"
  914. ⓪"BEGIN
  915. ⓪$(*  Current 'modID = 0'. That means all init.s are released.
  916. ⓪%*)
  917. ⓪$levelCounter (FALSE, TRUE, voidI);
  918. ⓪"END removalProc;
  919. ⓪"
  920. ⓪ VAR     envlpHdl        : EnvlpCarrier;
  921. ⓪(termHdl         : TermCarrier;
  922. ⓪(removalHdl      : RemovalCarrier;
  923. ⓪(wsp             : MemArea;
  924. ⓪ 
  925. ⓪ 
  926. ⓪ BEGIN
  927. ⓪"keyboardList := NIL;
  928. ⓪"buttonList := NIL;
  929. ⓪"stRectList := NIL;
  930. ⓪"ndRectList := NIL;
  931. ⓪"messageList := NIL;
  932. ⓪"timerList := NIL;
  933. ⓪"
  934. ⓪"modLevel := 1;
  935. ⓪"CatchProcessTerm (termHdl, termProc, wsp);
  936. ⓪"SetEnvelope (envlpHdl, levelCounter, wsp);
  937. ⓪"CatchRemoval (removalHdl, removalProc, wsp);
  938. ⓪ END EventHandler.
  939. ⓪ ə
  940. (* $FFF7C95C$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$000051E4$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416E$FFF8416EÇ$0000516E........T.......T......TT.......T.......T.......T.......T.......T.......T.......$00000B9B$0000515E$00005170$0000519D$0000516E$0000519D$000051AF$00005198$FFEEDCC0$0000527D$00005268$00005195$00005170$000005FA$000000D8$FFEEDCC0œÇâ*)
  941.