kkim@uiucdcsb.cs.uiuc.edu (05/27/87)
I am writing a Desk Accessory which transforms every input character. The transformation is affected by a previous character, a current char, Caps Lock key, shift key, option key, and command key. My DA does *not have its own window*; it is running in the *background* and transformed chars will be passed to an application (e.g. MacWrite). My DA is working a little now. The biggest problem is that ONLY SOME input chars do get transformed; however, there are other input chars which do not get transformed. I will show you a skeleton of my DA in Lightspeed Pascal to give you a concrete idea. ----------------------------------------------------------------- procedure OpenRoutine; begin dCtlStorage:=NewHandle(SizeOf(PrivateStorage)); dCtlFlags:=$6400; {DA can respond to control calls;} {DA needs time for performing periodic actions;} {DA will be locked in memory as soon as it is opened} dCtlDelay:=0; {must be called as often as possible} dCtlEMask:=keyDownMask;{meaningless?} whenSaved:=0;{evtQWhen of the latest keyDown event processed by a DA} end; procedure ControlRoutine; begin for counter:=1 to LIMIT do begin {LIMIT will be explained below} evQHdrPtr:=GetEvQHdr; {get a pointer to the header of the event queue} CurrElem:=evQHdrPtr^.qHead; while (CurrElem <> nil) do if (CurrElem^.evQElem.evtQWhen > whenSaved) then begin {an event which has not been processed by a DA; do transformation} CurrElem^.evQElem.evtQMessage:=transformedChar; whenSaved:=CurrElem^.evQElem.evtQWhen; end; {if} end; {while} end; {for counter} end; procedure CloseRoutine; begin disposHandle(dCtlStorage); end; --------------------------------------------------------------- I test my DA using MacWrite. At first, LIMIT was 1 (i.e. no for loop). The result was that about 2/3 of input chars did not get transformed. The following table will help: LIMIT portion of input chars which did not get transformed 1 2/3 10 1/2 700 1/10 1000 1/15 2000 < 1/30 When LIMIT was greater than about 500, some characters were lost if I typed fast (due to the maximum event queue size). I guess that LIMIT shoud be set to 1 and some other mechanism must be adopted to get around the problem. Does Vertical Retrace Manager have anything to do with it? Could anybody give me clues/hints/comments as to how to CATCH ALL THE KEYDOWN EVENTS IN A DESK ACCESSORY AND TRANSFORM THEM? Thanks in advance. Kyongsok KIM Dept. of Computer Science; Univ. of Illinois at Urbana-Champaign arpanet/csnet: kkim@a.cs.uiuc.edu usenet/uucp : {seismo, pur-ee, ihnp4}!uiucdcs!kkim
tecot@apple.UUCP (Ed Tecot) (06/09/87)
In article <164500033@uiucdcsb> kkim@uiucdcsb.cs.uiuc.edu writes: > > I am writing a Desk Accessory which transforms every input character. >The transformation is affected by a previous character, a current char, >Caps Lock key, shift key, option key, and command key. My DA does *not >have its own window*; it is running in the *background* and transformed >chars will be passed to an application (e.g. MacWrite). > > My DA is working a little now. The biggest problem is that ONLY SOME >input chars do get transformed; however, there are other input chars which >do not get transformed. I will show you a skeleton of my DA in Lightspeed >Pascal to give you a concrete idea. > >... > > When LIMIT was greater than about 500, some characters were lost if >I typed fast (due to the maximum event queue size). I guess that LIMIT >shoud be set to 1 and some other mechanism must be adopted to get around >the problem. Does Vertical Retrace Manager have anything to do with it? > > > Could anybody give me clues/hints/comments as to how to CATCH ALL THE >KEYDOWN EVENTS IN A DESK ACCESSORY AND TRANSFORM THEM? > Your problem is that keyboard (and mouse) events are asynchronous. It is possible that your DA could check the queue, find no events, only to have a user type immediately after that (and before the application calls GetNextEvent.) I recommend that you catch the events as they are posted. Every event is posted using PostEvent. Simply use GetTrapAddress and SetTrapAddress to insert your code. Remember that you will be called at different interrupt levels and therefore you cannot make calls to the memory manager (even indirectly), and that relocatable segments are not usable. _eme