mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-29 07:29:15 +00:00
5b0f0cc134
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
1686 lines
60 KiB
Plaintext
1686 lines
60 KiB
Plaintext
;______________________________________________________________________________
|
|
;
|
|
; File: TSMExtension.a
|
|
;
|
|
; Contains: Text Services Manager trap dispatcher.
|
|
;
|
|
; Written by: Kenny SC. Tung
|
|
;
|
|
; Copyright: © 1991-1992 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM5> 8/26/92 kc Fix compiler warning.
|
|
; <SM4> 7/7/92 CSS Update from Reality:
|
|
; <49> 7/3/92 KST <JH>: Correct a type error: kIMJustSetCursorBit should really be
|
|
; kSWMJustSetCursorBit.
|
|
; <48> 6/26/92 KST #1031142 <JH>: When the application claims not TSM aware any
|
|
; more, we need to clear all UseInputWindow flags so it will not
|
|
; be reused when another TSM aware app is launched.
|
|
; <47> 6/26/92 KST #1033450,1033456,1031316 <JH>: When XCLOSETSMAWAREAPPLICATION()
|
|
; is called, we better inform Process Manager about it.
|
|
; <46> 6/22/92 KST #1033280,1033495 <JH>: When part code <= inSysWindow, return not
|
|
; over a floating window. (I used to only check inDesk).
|
|
; <45> 6/19/92 KST #1032492 <JH>: When TSM tries to open the resource file using
|
|
; the refcon in the floating window, need to verify its
|
|
; windowkind.
|
|
; <44> 6/17/92 KST #1030843 <JH>: If we click in a popup menu inside of a floating
|
|
; window, HMGetBalloon needs to return true so that balloon will
|
|
; be removed. Also changed the function name from
|
|
; utaIsApplicationTSMAware to utaIsAppTSMAwareAndNotUsingIW to be
|
|
; more precise and descriptive.
|
|
; <43> 6/14/92 KST Changed utaRemoveDocumentID to return the number of TSM
|
|
; documents remained open by the application.
|
|
|
|
; <SM3> 6/11/92 CSS Roll-in Reality Changes. I don't know where Fred left off so here
|
|
; are all the comments:
|
|
; <42> 6/10/92 YK Oops, donÕt do last minutes change.
|
|
; <41> 6/10/92 YK #1031298 <JH>: Add OldJapaneseInputMethodExists. It returns
|
|
; True if the specified old-input method exists.
|
|
; <40> 6/10/92 KST #1031142,1030881 <JH>: Since we removed the docID param from
|
|
; TSMEvent, UseInputWindow has been broken because keydown event
|
|
; is routed to SWM recursively. Fix it with a TSM global keeping
|
|
; track of which doc is using the input window. And added a new
|
|
; private call for SWM -- TSMEventFromSWM. The TSM boot code has
|
|
; been modified so that it can handle multiple TSMinit files.
|
|
; (Global will not be re-allocated).
|
|
; <39> 6/4/92 JH #1031574 <KST>: _HMGetBalloonPatch leaves bits behind when a
|
|
; help window is drawn over the menubar. Checking to see if we are
|
|
; over the menubar or over a systemwindow before we return false.
|
|
; <38> 6/2/92 KST <JH>, Should not check for inContent in HMGetBalloon.
|
|
; <37> 6/2/92 KST <JH>,The previous change has a minor mistake in HMGetBalloon
|
|
; patch.
|
|
; <36> 6/2/92 JH #1028635,1030481,1030631,1030634,1030647 <KST>: Added SystemMenu
|
|
; patch to support system menus for input methods.
|
|
; <35> 5/20/92 KST #1030447 <JH>: Fixed a bug. UseInputWindow did not work if we
|
|
; want to have global effect for the application.
|
|
; <34> 5/14/92 KST #1025797,<JH>: Added one new message selector 'kMsgHelpHELPMgr'
|
|
; to InformTSM. This call is used by __HMScanHWinResource in
|
|
; BalloonPACK.a. Also patched __HMGetBalloonPatch so that Help
|
|
; balloon will not flash in the Finder.
|
|
; <33> 5/4/92 KST #1025252,<JH>: Patched _PaintBehind so that floating windows
|
|
; will be updated correctly when the whole screen is redrawn.
|
|
; <32> 5/2/92 YK Flush the parameter on the stack before return to a caller.
|
|
; <31> 5/1/92 KST #1027482,<JH>: If input method changed cursor in a floating
|
|
; layer, then don't let other application to change the cursor
|
|
; again.
|
|
; <30> 5/1/92 KST #1028301,<JH>: SetTSMDialogState, RestoreTSMDialogState,
|
|
; TSMChangeCursor, TSMRestoreCursor calls are no longer needed and
|
|
; should be removed from the source code.
|
|
; <29> 4/9/92 KST JH,modifying InitTSMApplication to support the fact that SWM is
|
|
; no longer an application but a driver. Adding 2 new messages in
|
|
; InformTSM. Will remove SetDialogState in the next release.
|
|
; <28> 3/27/92 KST Documentation changes.
|
|
; <27> 3/23/92 KST Changes due to the code review.
|
|
; <26> 3/12/92 KST Added a new call "utaGetTSMAwareDocTable".
|
|
; <25> 3/6/92 KST Removed debugger code. Will grow internal table when overflow.
|
|
; <24> 3/4/92 KST Get trap address of SetCursor at INIT time.
|
|
; <23> 3/3/92 KST Added 2 new calls: "TSMChangeCursor", and "TSMRestoreCursor".
|
|
; <22> 3/2/92 KST Added a private TSM call "NewTSMDocument4SWM".
|
|
; <21> 2/28/92 KST Added 2 new calls "SetTSMDialogState", and
|
|
; "RestoreTSMDialogState".
|
|
; <20> 2/27/92 KST In utKillTSMAwareApplication, if the app is not TSM aware, we'll
|
|
; send an AE to SWM ask it to close its input window. If it is TSM
|
|
; aware, we'll set tsmKillApplicationP flag to true.
|
|
; <19> 2/11/92 DCL Changed the name of TSMEqu.[aph] to TextServices.[aph] for
|
|
; better read-ability.
|
|
; <18> 2/10/92 KST InformTSM's msgChangeToOldJIM now takes a parameter -- FEPID.
|
|
; <SM2> 4/22/92 FM Bring up to date with RealityÉ
|
|
; <17> 2/1/92 KST We don't have a global flag in TSM globals to indicate using
|
|
; bottom-line window.
|
|
; <16> 1/31/92 YK Added FindServiceWindow.
|
|
; <15> 1/29/92 KST Removed "xIsApplicationTSMAware" call. Also inform Process
|
|
; Manager whether it should start sending events to SWM when SWM
|
|
; informTSM with its PSN.
|
|
; <14> 1/16/92 KST Add a new message to InformTSM: kMsgChangeToOldJIM.
|
|
; <13> 1/11/92 KST TSM globals are initially cleared.
|
|
; <12> 1/10/92 KST Inform Process Manager if the application is TSM aware.
|
|
; <11> 1/9/92 KST Changed SetDefaultInputMethod selector back to 13 so that we can
|
|
; build TSM INIT with d13.
|
|
; <10> 1/8/92 KST Removed CleanUpTSMAwareApp routine. CleanUpTSMApp is now a
|
|
; message to InformTSM.
|
|
; <9> 1/4/92 KST Add a new routine "CloseTextService". Also "OpenTextService" now
|
|
; returns component instance to the caller.
|
|
; <8> 12/31/91 KST Added "CleanUpTSMAwareApplication" and "InformTSM" new calls.
|
|
; Check saved resource for "Use Input Window" global flag at boot
|
|
; time.
|
|
; <7> 12/20/91 KST Making progress toward Alpha. Changed "inline" to "TSM", and
|
|
; added new calls.
|
|
; <6> 12/10/91 KST Adding a new "InlineAwareRegister" call.
|
|
; <5> 12/10/91 KST Disable the Gestalt call for now.
|
|
; <4> 12/10/91 KST Added boot time initialization code, and to use "TSMPrivate.a".
|
|
; <3> 11/26/91 KST Low level TSM routines are now dispatched directly to the
|
|
; Component Manager.
|
|
; <2> 11/23/91 KST Check in the first time for Cube-E.
|
|
;
|
|
;
|
|
;______________________________________________________________________________
|
|
|
|
|
|
|
|
|
|
;______________________________________________________________________________
|
|
;
|
|
; File: "TSMDispatch.a"
|
|
;
|
|
; Written by Kenny SC. Tung
|
|
;
|
|
; Modification History:
|
|
; 21Nov91 KSCT New today.
|
|
;______________________________________________________________________________
|
|
|
|
|
|
|
|
|
|
PRINT OFF
|
|
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'Processes.a'
|
|
INCLUDE 'MFPrivate.a'
|
|
INCLUDE 'LinkedPatchMacros.a'
|
|
INCLUDE 'GestaltEqu.a'
|
|
INCLUDE 'LayerEqu.a'
|
|
|
|
INCLUDE 'TextServices.a'
|
|
INCLUDE 'TSMPrivate.a'
|
|
|
|
INCLUDE 'Balloons.a'
|
|
INCLUDE 'BalloonsPriv.a'
|
|
INCLUDE 'ScriptPriv.a'
|
|
|
|
PRINT ON
|
|
|
|
CASE OBJ
|
|
|
|
IF &type('TSMDebug') = 'UNDEFINED' THEN
|
|
TSMDebug EQU 0
|
|
ENDIF
|
|
|
|
|
|
IF &type('BuildTSMInit') = 'UNDEFINED' THEN
|
|
BuildTSMInit EQU 0 ; this is only defined when building INIT
|
|
ENDIF
|
|
|
|
|
|
;______________________________________________________________________________
|
|
; Input: D0.W low byte = trap index,
|
|
; high byte = # of parameters in words.
|
|
; Note:
|
|
;______________________________________________________________________________
|
|
TSMDISPATCH Proc export ; dispatch code
|
|
|
|
MOVEQ #0,D1
|
|
MOVE.W D0,D1 ; D1 = trap index
|
|
TST.W D1 ; Check the trap dispatch
|
|
BLT.S @1 ; Negative traps are trouble
|
|
CMP.W #kMaxTSMSelector,D1 ; Compare against our known limits
|
|
BLS.S @2 ; Continue if all seems well
|
|
|
|
@1 MOVEQ #0,D1
|
|
MOVE.W D0,D1
|
|
LSR.W #8,D1 ; D1 = # of parameters in words
|
|
LSL.W #1,D1 ; convert to bytes
|
|
MOVEQ #ParamErr,D0 ; Indicate parameter error
|
|
MOVEA.L (SP)+,A0 ; get return address
|
|
LEA (A7,D1),SP ; pop param
|
|
MOVE.W D0,(SP) ; function result
|
|
JMP (A0) ; Terminate this call
|
|
|
|
@2 ;; D1 = trap index.
|
|
EXT.W D1 ;
|
|
ASL.W #1,D1 ; each entry is 4 bytes
|
|
MOVE.W TSMTrapTable(D1.W),d0 ; get the address of the entry point
|
|
JMP TSMTrapTable(D0.W) ;jump to it
|
|
|
|
MACRO
|
|
JT &entry
|
|
IMPORT &entry
|
|
DC.W &entry - TSMTrapTable
|
|
ENDM
|
|
TSMTrapTable
|
|
|
|
JT XNEWTSMDOCUMENT ; 0 initialize TSM aware document
|
|
JT XDELETETSMDOCUMENT ; 1
|
|
JT XACTIVATETSMDOCUMENT ; 2
|
|
JT XDEACTIVATETSMDOCUMENT ; 3
|
|
JT XTSMEVENT ; 4
|
|
JT XTSMMENUSELECT ; 5
|
|
JT XSETTSMCURSOR ; 6
|
|
JT XFIXTSMDOCUMENT ; 7
|
|
JT XGETSERVICELIST ; 8
|
|
JT XOPENTEXTSERVICE ; 9
|
|
JT XCLOSETEXTSERVICE ; 10 <04Jan91 #9>
|
|
JT XSENDAETOCLIENT ; 11
|
|
|
|
|
|
JT XSETDEFAULTINPUTMETHOD ; 12
|
|
JT XGETDEFAULTINPUTMETHOD ; 13 (D)
|
|
JT XSETTEXTSERVICELANGUAGE ; 14 (E)
|
|
JT XGETTEXTSERVICELANGUAGE ; 15
|
|
JT XUSEINPUTWINDOW ; 16
|
|
JT XNEWSERVICEWINDOW ; 17
|
|
JT XCLOSESERVICEWINDOW ; 18
|
|
JT XGETFRONTSERVICEWINDOW ; 19
|
|
|
|
JT XINITTSMAWAREAPPLICATION ; 20
|
|
JT XCLOSETSMAWAREAPPLICATION ; 21
|
|
JT XINFORMTSM ; 22
|
|
|
|
JT XFINDSERVICEWINDOW ; 23
|
|
JT XNEWTSMDOCUMENT4SWM ; 24 <02Mar92 #22>
|
|
JT XTSMEVENTFROMSWM ; 25 <03Jun92 #39>
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
; __________________________________________________________________________
|
|
; Function: xInitTSMAwareApplication()
|
|
; Application registers itself as TSM aware.
|
|
; Input: none.
|
|
; Output: D0.W = error code (memFullErr, tsmNotAnAppErr, tsmAlreadyRegisteredErr)
|
|
; Register usage: Use D0,D1,A0,A1
|
|
;
|
|
; Side Effect: If application registers itself the first time, a table to
|
|
; record open document IDs is allocated if it is not allocated.
|
|
; ___________________________________________________________________________
|
|
XINITTSMAWAREAPPLICATION PROC EXPORT
|
|
Import utaTSMAwareApplicationP
|
|
Export xInitTSMAwareDriver
|
|
WITH PSNRecord
|
|
|
|
SUBA.W #10, sp ; allocate storage for PSN (8 bytes) and result
|
|
PEA 2(sp) ; push address of PSN storage
|
|
_GetSystemClientProcess ; get PSN with which to associate the file
|
|
TST.W (sp)+ ; on error, PSN == kNoProcess
|
|
BNE.S noProcess
|
|
|
|
xInitTSMAwareDriver
|
|
;; Verify if we have registered this app already ...
|
|
MOVE.L highLongOfPSN(SP),D0 ; get high half of PSN
|
|
MOVE.L lowLongOfPSN(SP),D1 ; get low half of PSN
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BNE.S registered ; yes, punt =>
|
|
;; PSN on top of stack. Locate a free entry and store.
|
|
BSR getFreePSNEntry ; get a free entry in A1
|
|
BNE.S cleanSPExit ; punt on error (D0 set)
|
|
;; Record this application in the PSN table (A1) ...
|
|
|
|
IF TSMDebug THEN ; debug begin
|
|
CMP.W #kPSNTableSignature,psnTableSignature(A1) ; valid table?
|
|
BEQ.S TableOK ; yes
|
|
_debugger
|
|
TableOK
|
|
ENDIF ; end
|
|
|
|
MOVE.L (sp)+,psnHighID(A1) ; pop and save high half of PSN
|
|
MOVE.L (sp)+,psnLowID(A1) ; pop and save low half of PSN
|
|
CLR.W psnDoWeReallyUseIW(A1) ; don't use float input window
|
|
MOVEA.L psnDocsTablePtr(A1),A0 ; get the addr
|
|
MOVE.L A0,D0 ; is there a table?
|
|
BNE.S hasTable ; if yes, recycle it (clear counter)
|
|
MOVE.L #kDocTableDefSize,D0 ; doc ID table size
|
|
_NewPtr ,sys ,clear ; from system heap
|
|
BEQ.S newTable ; OK ->
|
|
MOVE.W #memFullErr,D0 ; set error code
|
|
BRA.S cleanSPExit ; no memory, sorry
|
|
|
|
newTable
|
|
MOVE.W #kDefTableEntryN,docTableEntryN(A0) ; total entry number of the table
|
|
MOVE.L A0,psnDocsTablePtr(A1) ; save the table in PSN record
|
|
hasTable
|
|
CLR.W docIDCount(A0) ; clear counter
|
|
|
|
;; Inform Process Manager that this application is TSM aware ...
|
|
LEA psnHighID(A1),A0 ; PSN addr
|
|
CLR.W -(SP) ; room for result
|
|
MOVE.L A0,-(SP) ; PSN
|
|
MOVE.W #$FFFF,-(SP) ; flag = true
|
|
_InlineAware
|
|
ADDA.W #2,SP ; ignore error
|
|
|
|
MOVEQ #0,D0 ; return no error
|
|
|
|
ret
|
|
MOVE.W D0,4(SP) ; return error in Pascal style
|
|
RTS
|
|
|
|
noProcess
|
|
MOVE.W #tsmNotAnAppErr,D0
|
|
cleanSPExit
|
|
LEA 8(SP),SP ; reset sp (for PSN record)
|
|
BRA.S ret
|
|
registered
|
|
MOVE.W #tsmAlreadyRegisteredErr,D0
|
|
BRA.S cleanSPExit
|
|
|
|
|
|
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Function: getFreePSNEntry
|
|
; Internal routine called by xInitTSMAwareApplication only.
|
|
; Output: A1.L = pointer to PSN record if D0 = 0,
|
|
; D0.W = noErr if found one free slot
|
|
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
getFreePSNEntry ; private routine
|
|
|
|
MOVEA.L ExpandMem,A0
|
|
MOVEA.L ExpandMemRec.emTSMGlobals(A0),A0 ; get TSM global in A0
|
|
MOVEA.L TSMVarsRec.tsmIAPSNTablePtr(A0),A0 ; get PSN table
|
|
MOVE.W iaAppCount(A0),D0 ; D0.W = total apps registered
|
|
MOVE.W iaTotalPSNEntryN(A0),D1 ; D1.W = total entries
|
|
CMP.W D1,D0 ; any free slot?
|
|
BHS.S @full ; no
|
|
@again
|
|
LEA iaPSNStart(A0),A1 ; A1 = first PSN record
|
|
|
|
@tryNext
|
|
TST.L psnHighID(A1) ; is this free?
|
|
BNE.S @4 ; No
|
|
TST.L psnLowID(A1) ; is this free?
|
|
BEQ.S @foundOne ; yes, both slots are zero
|
|
@4
|
|
ADDA.W #kPSNEntrySize,A1 ; points to the next one
|
|
BRA.S @tryNext
|
|
|
|
@foundOne ADD.W #1,iaAppCount(A0) ; bump app counter
|
|
MOVEQ #0,D0 ; no error
|
|
RTS
|
|
|
|
@full ;; all full, need to grow the array
|
|
|
|
;; PSN table is full, (too many TSM aware application? Good !!!), need to grow the table ...
|
|
|
|
MOVEA.L A0,A1 ; A1 = old PSN table
|
|
ADDQ #kDefTableEntryN,D1 ; increment total entry
|
|
MOVE.L D1,D0
|
|
LSL.L #kLog2PSNEntrySize,D0 ; total bytes
|
|
ADD.L #iaPSNStart,D0 ; plus header = new size to allocate
|
|
_NewPtr ,sys ,clear ; allocate a larger table from system heap
|
|
BNE.S @noMem ; no memory, we are in trouble
|
|
|
|
;; A0 = new PSN table, A1 = old PSN table, D1 = new total entry.
|
|
MOVE.W iaTotalPSNEntryN(A1),D0 ; D0.W = original total entries
|
|
LSL.L #kLog2PSNEntrySize,D0 ; convert to bytes
|
|
ADD.L #iaPSNStart,D0 ; plus header = old size to copy
|
|
EXG A1,A0 ; A0 is the source
|
|
_BlockMove ; copy A0 => A1
|
|
|
|
;; A0 is the old table, we can release it now ...
|
|
_DisposePtr ; free mem
|
|
|
|
MOVEA.L ExpandMem,A0 ; we come here when buffer is full
|
|
MOVEA.L ExpandMemRec.emTSMGlobals(A0),A0 ; get TSM global in A0
|
|
MOVE.L A1,TSMVarsRec.tsmIAPSNTablePtr(A0) ; save new table in TSM global
|
|
MOVE.W D1,iaTotalPSNEntryN(A1) ; update (NEW) total entries
|
|
EXG A1,A0 ; A0 is now the new PSN table
|
|
BRA.S @again ; try again
|
|
@noMem
|
|
MOVE.W #memFullErr,D0 ; return error
|
|
RTS
|
|
|
|
ENDWITH
|
|
ENDP ; xInitTSMAwareApplication END
|
|
|
|
|
|
|
|
; _________________________________________________________________________
|
|
; Function: OSErr utaRecordDocumentID(aHandle, &PSNRecord)
|
|
; Internal C routine --
|
|
; Record the document ID in PSN table for the application.
|
|
; Each application keeps track of all open document IDs.
|
|
; Called by 'xNewTSMDocument'.
|
|
; Output: noErr = no error
|
|
; Register usage: Use D0,D1,A0,A1
|
|
;
|
|
; Side effect:
|
|
; Grow the document table if it is full.
|
|
; _________________________________________________________________________
|
|
|
|
utaRecordDocumentID PROC EXPORT
|
|
IMPORT utaTSMAwareApplicationP
|
|
WITH PSNRecord
|
|
; 0(SP) -> return addr
|
|
docIDParam equ 4 ; 4(SP) -> aHandle = valid document ID
|
|
psnParam equ 8 ; 8(SP) -> ptr(PSNRecord)
|
|
|
|
|
|
MOVEA.L psnParam(SP),A0 ; A0 = ptr(PSNRecord)
|
|
MOVE.L highLongOfPSN(A0),D0 ; get high half of PSN
|
|
MOVE.L lowLongOfPSN(A0),D1 ; get low half of PSN
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BEQ.S @notAwareReturn ; no, it is not TSM aware? !!
|
|
@1
|
|
;; It is registered, A1 = ptr(PSNRecord) ...
|
|
MOVE.L psnDocsTablePtr(A1),D0 ; D0 = ptr(doc ID table)
|
|
BEQ.S @notAwareReturn ; if no table
|
|
MOVEA.L D0,A0
|
|
MOVE.W docIDCount(A0),D0 ; D0.W = total ID recorded
|
|
MOVE.W docTableEntryN(A0),D1 ; D1.W = total entries
|
|
CMP.W D1,D0 ; any free slot?
|
|
BHS.S @full ; no
|
|
LEA docIDStart(A0),A1 ; A1 = first ID
|
|
@loop
|
|
TST.L (A1)+ ; is this slot free?
|
|
BNE.S @loop ; no
|
|
|
|
MOVE.L docIDParam(SP),-(A1) ; save the ID in the free slot
|
|
ADD.W #1,docIDCount(A0) ; increment count
|
|
MOVEQ #0,D0 ; OK
|
|
@Exit
|
|
RTS
|
|
|
|
@notAwareReturn
|
|
MOVE.W #tsmNeverRegisteredErr,D0 ; return error
|
|
BRA.S @Exit
|
|
|
|
|
|
|
|
@full ; all full, need to grow the array
|
|
;; document table is full, need to grow the table ...
|
|
|
|
ADDQ #kDefTableEntryN,D1 ; increment total entry
|
|
MOVE.L D1,D0
|
|
LSL.L #kLog2DocEntrySize,D0 ; entry * 4
|
|
ADD.L #docIDStart,D0 ; plus header
|
|
_NewPtr ,sys ,clear ; allocate a larger table from system heap
|
|
BNE.S @noMem ; no memory, it's OK
|
|
;; A0 = new doc table, A1 = ptr(PSNRecord), D0.L = new table size, D1 = new total entry.
|
|
MOVE.L A2,-(SP) ; free A2
|
|
MOVEA.L A1,A2 ; A2 = ptr(PSNRecord)
|
|
MOVE.L psnDocsTablePtr(A2),A1 ; A1 = ptr(old table)
|
|
MOVE.L A0,psnDocsTablePtr(A2) ; save the new table
|
|
|
|
;; A0 = new doc table, A1 = old doc table,
|
|
MOVE.W docTableEntryN(A1),D0 ; D0.W = original total entries
|
|
LSL.L #kLog2DocEntrySize,D0 ; entry * 4
|
|
ADD.L #docIDStart,D0 ; plus header
|
|
EXG A1,A0 ; A0 is the source
|
|
_BlockMove ; copy A0 => A1
|
|
|
|
;; A0 is the old table, we can release it now ...
|
|
_DisposePtr ; free mem
|
|
|
|
MOVE.W D1,docTableEntryN(A1) ; update (NEW) total entries
|
|
MOVEA.L A2,A1 ; A1 = ptr(PSNRecord)
|
|
MOVEA.L (SP)+,A2 ; restore A2
|
|
BRA.S @1 ; try again
|
|
@noMem
|
|
MOVE.W #memFullErr,D0 ; return error
|
|
RTS
|
|
|
|
ENDWITH
|
|
ENDP ; utaRecordDocumentID END
|
|
|
|
|
|
; _________________________________________________________________________
|
|
; Function: OSErr utaRemoveDocumentID(handle, countPtr, psnRecordPtr);
|
|
; Internal routine -- Remove the document ID in process's doc ID table.
|
|
; Called by 'xDeleteTSMDocument' only.
|
|
; The caller of this routine should close all open text services!
|
|
; Input: Handle is a valid document ID
|
|
; Output: count = number of TSM documents remained
|
|
; psnRecordPtr = psn Record Ptr (meaningful only if count = 0)
|
|
; Register usage: Use D0,D1,A0,A1
|
|
; C calling convention .....
|
|
; _________________________________________________________________________
|
|
|
|
; 0(SP) -> return addr
|
|
; 4(SP) -> handle (ID)
|
|
; 8(SP) -> ptr(short) ; count
|
|
;12(SP) -> ptr(psn record) ; meaningful only if count = 0 !!!!!!!!!!!!!
|
|
|
|
utaRemoveDocumentID PROC EXPORT
|
|
IMPORT utaTSMAwareApplicationP
|
|
WITH PSNRecord, TSMDocumentRecord
|
|
|
|
MOVEA.L 4(SP),A0 ; A0 = handle
|
|
MOVEA.L (A0),A0 ; A0 = doc ID pointer
|
|
MOVE.L iDocPSNID1(A0),D0 ; get high half of PSN
|
|
MOVE.L iDocPSNID2(A0),D1 ; get low half of PSN
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BEQ.S @err ; no, it is not TSM aware? !!
|
|
|
|
;; It is registered, A1 = ptr(PSNRecord) ...
|
|
MOVE.L psnDocsTablePtr(A1),D0 ; D0 = ptr(doc ID table)
|
|
BEQ.S @err ; if no table
|
|
MOVEA.L D0,A0 ; A0 = ptr(doc ID table)
|
|
MOVE.W docIDCount(A0),D0 ; D0.W = total ID recorded
|
|
BEQ.S @stackOK ; br if empty (A1 = ptr(PSNRecord))
|
|
|
|
MOVE.L A1,-(SP) ; save ptr
|
|
MOVE.W docTableEntryN(A0),D0 ; D0.W = total entry
|
|
LEA docIDStart(A0),A1 ; A1 = first ID
|
|
MOVE.L 8(SP),D1 ; D1 = document ID to delete
|
|
@loop
|
|
TST.W D0 ; more to search?
|
|
BLE.S @notFound ; no (should never happen)
|
|
SUBQ #1,D0 ; one less to search
|
|
CMP.L (A1)+,D1 ; is this the one?
|
|
BNE.S @loop ; no
|
|
|
|
CLR.L -(A1) ; found, clear it
|
|
SUB.W #1,docIDCount(A0) ; decrement count
|
|
MOVEA.L (SP)+,A1 ; A1 = ptr(PSNRecord)
|
|
|
|
@stackOK
|
|
MOVE.W docIDCount(A0),D0 ; D0.W = total ID recorded
|
|
MOVEA.L 8(SP),A0 ; A0 = ptr to short
|
|
MOVE.W D0,(A0) ; return count remaining
|
|
MOVEA.L 12(SP),A0 ; A0 = ptr to psn record
|
|
MOVE.L A1,(A0) ; return psn record ptr
|
|
MOVEQ #0,D0 ; perfect
|
|
RTS
|
|
|
|
@notFound
|
|
ADDQ.W #4,SP ; pop ptr
|
|
@err
|
|
MOVE.W #tsmNeverRegisteredErr,D0 ; not TSM aware
|
|
RTS
|
|
|
|
ENDWITH
|
|
ENDP ; utaRemoveDocumentID END
|
|
|
|
|
|
; _____________________________________________________________________________________
|
|
; Function: OSErr utaUpdateAppFlagInPSNTable(&PSNRecord, useFloatWindowP);
|
|
; Internal routine -- update the 'psnAppUseInputWindowP' flag in the PSN table.
|
|
; Called by 'xActivateTSMDocument', and 'xUseInputWindow'.
|
|
; Input: Handle is a valid document ID
|
|
; Output: none
|
|
; Register usage: Use D0,D1,D2,A0,A1
|
|
; Modification history:
|
|
; 20May92 KST A boolean passed in by C compiler is 4 bytes !! When xUseInputWindow
|
|
; calls this routine and pass us the Boolean flag, I used MOVE.B to get
|
|
; the flag, which got garbage from the stack. <#35>
|
|
; _____________________________________________________________________________________
|
|
|
|
utaUpdateAppFlagInPSNTable PROC EXPORT
|
|
IMPORT utaTSMAwareApplicationP
|
|
WITH PSNRecord
|
|
|
|
; 0(SP) -> return addr
|
|
psnParam equ 4 ; 4(SP) -> ptr(PSNRecord)
|
|
useFWParam equ 8 ; 8(SP) -> useFloatWindow flag
|
|
|
|
|
|
MOVEA.L psnParam(SP),A0 ; A0 = ptr(PSNRecord)
|
|
MOVE.L highLongOfPSN(A0),D0 ; get high half of PSN
|
|
MOVE.L lowLongOfPSN(A0),D1 ; get low half of PSN
|
|
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BEQ.S @neverRegister ; no, it is not TSM aware? !!
|
|
|
|
;; It is registered, A1 = ptr(PSNRecord) ...
|
|
MOVE.L useFWParam(SP),D2 ; get flag with .L <#35>
|
|
MOVE.B D2,psnAppUseInputWindowP(A1); change the APP. flag in PSN record
|
|
|
|
MOVE.W #$FFFF,D0 ; true (inline aware)
|
|
TST.W psnDoWeReallyUseIW(A1) ; is the document using input window?
|
|
BEQ.S @3 ; no (inline aware)
|
|
MOVEQ #0,D0 ; D0 = false (not inline aware)
|
|
|
|
@3
|
|
;; Inform Process Manager that this application is TSM aware or not...
|
|
MOVEA.L psnParam(SP),A0 ; A0 = ptr(PSNRecord)
|
|
CLR.W -(SP) ; room for result
|
|
MOVE.L A0,-(SP) ; PSN
|
|
MOVE.B D0,-(SP) ; Boolean flag
|
|
_InlineAware
|
|
ADDA.W #2,SP
|
|
MOVEQ #0,D0 ; no error
|
|
@5
|
|
RTS
|
|
@neverRegister
|
|
MOVE.W #tsmNeverRegisteredErr,D0 ; not TSM aware
|
|
BRA.S @5
|
|
|
|
ENDWITH
|
|
ENDP ; utaUpdateAppFlagInPSNTable END
|
|
|
|
|
|
|
|
; _________________________________________________________________________
|
|
; Function: void utaUpdateDocFlagInPSNTable(idocID);
|
|
; Internal routine -- update the 'psnDocUseInputWindowP' flag in the PSN table.
|
|
; Called by 'xActivateTSMDocument', and 'xUseInputWindow'.
|
|
; Input: Handle is a valid document ID
|
|
; Output: none
|
|
; Register usage: Use D0,D1,D2,A0,A1
|
|
; _________________________________________________________________________
|
|
|
|
; 0(SP) -> return addr
|
|
; 4(SP) -> handle (ID)
|
|
|
|
utaUpdateDocFlagInPSNTable PROC EXPORT
|
|
IMPORT utaTSMAwareApplicationP
|
|
WITH PSNRecord, TSMDocumentRecord
|
|
|
|
MOVEA.L 4(SP),A0 ; A0 = handle
|
|
MOVEA.L (A0),A0 ; A0 = doc ID pointer
|
|
MOVE.L iDocPSNID1(A0),D0 ; get high half of PSN
|
|
MOVE.L iDocPSNID2(A0),D1 ; get low half of PSN
|
|
MOVE.B iDocUseInputWindowP(A0),D2 ; get flag when we dereferenced the handle
|
|
|
|
BSR utaTSMAwareApplicationP ; is it already registered ? (D2 preserved)
|
|
BEQ.S @8 ; no, it is not TSM aware? !!
|
|
|
|
;; It is registered, A1 = ptr(PSNRecord), D2.B = flag ...
|
|
MOVE.B D2,psnDocUseInputWindowP(A1); change the doc falg in PSN record
|
|
|
|
MOVE.W #$FFFF,D0 ; true (inline aware)
|
|
TST.W psnDoWeReallyUseIW(A1) ; is the document using input window?
|
|
BEQ.S @3 ; no (inline aware)
|
|
MOVEQ #0,D0 ; D0 = false (not inline aware)
|
|
|
|
@3
|
|
;; Inform Process Manager that this application is TSM aware or not...
|
|
LEA psnHighID(A1),A0 ; PSN addr
|
|
CLR.W -(SP) ; room for result
|
|
MOVE.L A0,-(SP) ; PSN
|
|
MOVE.B D0,-(SP) ; Boolean flag
|
|
_InlineAware
|
|
ADDA.W #2,SP
|
|
MOVEQ #0,D0 ; no error
|
|
|
|
@8 RTS
|
|
|
|
ENDWITH
|
|
ENDP ; utaUpdateDocFlagInPSNTable END
|
|
|
|
|
|
|
|
; _________________________________________________________________________
|
|
; Function: utaTSMAwareApplicationP
|
|
; Internal routine -- Verify if the application is TSM aware.
|
|
; Input: D0.L = high half of PSN. (I don't believe we've designed PSN as 8 bytes !!!)
|
|
; D1.L = low half of PSN
|
|
; Output: D0.W = true (non-zero) if the app is TSM aware, A1 = ptr(PSNRecord)
|
|
; D0.W = false (zero) if the app is not TSM aware.
|
|
; and condition code set.
|
|
; Register usage: Use D0,D1,A0,A1. D2 must be preserved.
|
|
;
|
|
; Side Effect: If D0 = true, return pointer to my internal PSN record in A1
|
|
; _________________________________________________________________________
|
|
utaTSMAwareApplicationP PROC EXPORT
|
|
WITH PSNRecord
|
|
|
|
|
|
MOVE.L D3,-(SP) ; free D3
|
|
|
|
;; make sure PSN is not 0 ...
|
|
MOVE.L D0,D3
|
|
OR.L D1,D3 ; valid PSN
|
|
BEQ.S @tsmAwareExit ; no, both id are 0
|
|
|
|
MOVEA.L ExpandMem,A0
|
|
MOVEA.L ExpandMemRec.emTSMGlobals(A0),A0 ; get TSM global in A0
|
|
MOVEA.L TSMVarsRec.tsmIAPSNTablePtr(A0),A0 ; get PSN table
|
|
MOVEQ #0,D3
|
|
MOVE.W iaAppCount(A0),D3 ; D3.W = total apps registered
|
|
BEQ.S @notFound ; none
|
|
MOVE.W iaTotalPSNEntryN(A0),D3 ; D3.L = total entries
|
|
BEQ.S @notFound ; should not happen, just in case
|
|
LEA iaPSNStart(A0),A1 ; A1 = first PSN record
|
|
SUBQ #1,D3
|
|
@loop
|
|
CMP.L psnHighID(A1),D0 ; same id?
|
|
BNE.S @5 ; no
|
|
CMP.L psnLowID(A1),D1 ; same id?
|
|
BEQ.S @found ; yes
|
|
|
|
@5
|
|
ADDA.W #kPSNEntrySize,A1 ; points to the next one
|
|
DBRA D3,@loop ; no array overflow check
|
|
@notFound
|
|
MOVEQ #0,D0 ; not TSM aware
|
|
@tsmAwareExit
|
|
MOVE.L (SP)+,D3 ; restore D3
|
|
TST.W D0 ; set CCR
|
|
RTS
|
|
|
|
@found
|
|
MOVEQ #1,D0 ; TSM aware
|
|
|
|
IF TSMDebug THEN
|
|
CMP.W #kPSNTableSignature,psnTableSignature(A1) ; valid table?
|
|
BEQ.S @20 ; yes
|
|
_debugger
|
|
@20
|
|
ENDIF
|
|
|
|
BRA.S @tsmAwareExit
|
|
ENDWITH
|
|
|
|
ENDP ; utaTSMAwareApplicationP
|
|
|
|
|
|
|
|
; _____________________________________________________________________________________________
|
|
; Function: xCloseTSMAwareApplication()
|
|
; Application deregisters itself when quit.
|
|
; Input: ProcessSerialNumberPtr.
|
|
; Output: D0.W = error code (memFullErr, tsmNotAnAppErr, openDocumentsErr)
|
|
; Register usage: Use D0,D1,A0,A1
|
|
;
|
|
; ¥¥ Note: xCloseTSMAwareApplication can't close the application if there is any document open.
|
|
; utKillTSMAwareApplication will close the document and then close the application.
|
|
;
|
|
; ¥¥ utCloseAppCommon code is shared by InformTSM's @KillTSMApp.
|
|
; Do not change the calling convention without changing @KillTSMApp !!
|
|
; _____________________________________________________________________________________________
|
|
XCLOSETSMAWAREAPPLICATION PROC EXPORT
|
|
IMPORT utaTSMAwareApplicationP, utDeleteCleanUpTSMDocument
|
|
EXPORT utCloseAppCommon
|
|
WITH PSNRecord
|
|
|
|
;; Verify if we have registered this application ...
|
|
SUBA.W #10,SP ; allocate storage for PSN (8 bytes) and result
|
|
PEA 2(SP) ; push address of PSN storage
|
|
_GetSystemClientProcess ; get PSN with which to associate the file
|
|
MOVE.W (SP)+,D0 ; on error, PSN == kNoProcess
|
|
BNE.W closeRet ; punt
|
|
MOVEQ #0,D2 ; clear flag (no force close)
|
|
|
|
utCloseAppCommon ; shared by utKillTSMAwareApplication
|
|
;; If you change the stack frame for this code, be sure to change utKillTSMAwareApplication
|
|
;; If D2 <> 0, then force to close all documents and exit. (called from InformTSM).
|
|
;; If D2 == 0 and there is open document, then return error.
|
|
;; Verify if we have registered this app already ...
|
|
|
|
MOVE.L 0(SP),D0 ; get high half of PSN
|
|
MOVE.L 4(SP),D1 ; get low half of PSN
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BEQ.S @notTSMaware ; no, it is not TSM aware
|
|
|
|
;; It is registered, A1 = ptr(PSNRecord) ...
|
|
|
|
MOVE.L psnDocsTablePtr(A1),D0 ; get document ID table
|
|
BEQ.S @docsClosed ; stop if nil
|
|
MOVEA.L D0,A0 ; A0 = document ID table
|
|
MOVE.W docIDCount(A0),D0 ; any open document?
|
|
BEQ.S @docsClosed ; no, OK =>
|
|
TST.W D2 ; is this a force close?
|
|
BEQ.S docsOpenErr ; no, can't continue
|
|
|
|
;; This is a force close but there is open document, so let's close the documents for the app.
|
|
;; D2 is free register now ...
|
|
MOVE.L A1,-(SP) ; save PSNRecord pointer
|
|
MOVEQ #0,D0 ; clear 32 bits
|
|
MOVE.W docTableEntryN(A0),D0 ; total number of entry
|
|
SUBQ #1,D0 ; for DBRAing
|
|
LEA docIDStart(A0),A0 ; A0 = points to the first ID
|
|
|
|
@loop ;; need to preserve A0/D0
|
|
MOVE.L (A0)+,D1 ; D1 = doc ID
|
|
BEQ.S @1 ; empty
|
|
|
|
CLR.L -4(A0) ; clear the table entry too
|
|
MOVEM.L D0/A0,-(SP) ; save D0/A0 across the call
|
|
|
|
MOVE.L D1,-(SP) ; push parameter -> ID
|
|
JSR utDeleteCleanUpTSMDocument ; delete and clean up the document <#47>
|
|
ADDA.W #4,SP ; pop param
|
|
|
|
MOVEM.L (SP)+,D0/A0 ; restore D0/A0
|
|
@1 DBRA D0,@loop
|
|
|
|
MOVEA.L (SP)+,A1 ; restore PSNRecord pointer
|
|
MOVEA.L psnDocsTablePtr(A1),A0 ; A0 = document ID table
|
|
;; the document ID table is not released, we just clear the counter for re-use
|
|
MOVE.W #0,docIDCount(A0) ; clear counter, all closed
|
|
@docsClosed
|
|
|
|
CLR.L psnHighID(A1) ; mark this PSN slot to be free
|
|
CLR.L psnLowID(A1)
|
|
CLR.L psnAppUseInputWindowP(A1) ; clear UseInputWindow flags so it will not be reused <#48>
|
|
|
|
MOVEA.L ExpandMem,A0
|
|
MOVEA.L ExpandMemRec.emTSMGlobals(A0),A0 ; get TSM global in A0
|
|
MOVEA.L TSMVarsRec.tsmIAPSNTablePtr(A0),A0 ; get PSN table
|
|
SUB.W #1,iaAppCount(A0) ; decrease app counter
|
|
|
|
;; now, inform Process Manager that this process is not TSM aware any more ....
|
|
|
|
CLR.W -(SP) ; room for result
|
|
PEA 2(SP) ; PSN
|
|
CLR.W -(SP) ; flag = flase
|
|
_InlineAware ; not aware
|
|
ADDA.W #2,SP ; ignore error
|
|
|
|
MOVEQ #0,D0 ; return no error
|
|
BRA.S closeRet
|
|
|
|
@notTSMaware
|
|
MOVE.W #tsmNeverRegisteredErr,D0 ; return error
|
|
BRA.S closeRet
|
|
|
|
docsOpenErr ; can't close because there is open documents
|
|
MOVE.W #tsmDocumentOpenErr,D0 ; return error
|
|
closeRet
|
|
LEA 8(SP),SP ; restore sp
|
|
MOVE.W D0,4(SP) ; return error in Pascal style
|
|
RTS
|
|
ENDWITH
|
|
|
|
ENDP ; XCLOSETSMAWAREAPPLICATION END
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; Function: pascal OSErr utaGetTSMAwareDocTable(ProcessSerialNumberPtr, docTablePtr)
|
|
; Verify if the application is TSM aware.
|
|
; If the USEINPUTWINDOW flag is set, we treat the app as non-TSM aware!
|
|
; If the app is TSM aware, then return its document table pointer in docTablePtr.
|
|
; If error, then docTablePtr has undefined value.
|
|
; Input: ProcessSerialNumberPtr.
|
|
; docTablePtr = pointer to docTable.
|
|
; Output: D0.W = error code (memFullErr, temNeverRegisteredErr, tsmUseInputWindowErr),
|
|
; D0.W = noErr if it is TSM aware.
|
|
; Register usage: Use D0,D1,A0,A1
|
|
; _______________________________________________________________________________
|
|
UTAGETTSMAWAREDOCTABLE PROC EXPORT
|
|
Import UTAISAPPTSMAWAREANDNOTUSINGIW
|
|
WITH PSNRecord
|
|
|
|
MOVEA.L 8(SP),A1 ; get ProcessSerialNumberPtr
|
|
CLR.W -(SP)
|
|
MOVE.L A1,-(SP) ; push ProcessSerialNumberPtr
|
|
JSR UTAISAPPTSMAWAREANDNOTUSINGIW ; get doc table ptr
|
|
MOVE.W (SP)+,D0 ; is it TSM aware or use input window?
|
|
BNE.S @5 ; no
|
|
MOVEA.L 4(SP),A0 ; get pointer to docTable
|
|
MOVE.L psnDocsTablePtr(A1),(A0) ; return docTable
|
|
|
|
@5
|
|
MOVEA.L (SP)+,A0 ; get return address
|
|
LEA 8(SP),SP ; restore sp
|
|
MOVE.W D0,(SP) ; return error in Pascal style
|
|
JMP (A0)
|
|
|
|
ENDWITH
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; Function: utaGetTSMAppRecordPtr(ProcessSerialNumber *PSNRecord, TSMAppsRecord **appRecordPtr);
|
|
; Verify if the application is TSM aware.
|
|
; If the USEINPUTWINDOW flag is set, we treat the app as non-TSM aware!
|
|
; If the app is TSM aware, then return its document table pointer in docTablePtr.
|
|
; If error, then docTablePtr has undefined value.
|
|
; Input: ProcessSerialNumberPtr.
|
|
; docTablePtr = pointer to docTable.
|
|
; Output: D0.W = error code (memFullErr, temNeverRegisteredErr, tsmUseInputWindowErr),
|
|
; D0.W = noErr if it is TSM aware.
|
|
; Register usage: Use D0,D1,A0,A1
|
|
; _______________________________________________________________________________
|
|
UTAGETTSMAPPRECORDPTR PROC EXPORT
|
|
Import utaTSMAwareApplicationP
|
|
WITH PSNRecord
|
|
|
|
MOVEA.L 8(SP),A1 ; get ProcessSerialNumberPtr
|
|
MOVE.L highLongOfPSN(A1),D0 ; get high half of PSN
|
|
MOVE.L lowLongOfPSN(A1),D1 ; get low half of PSN
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BEQ.S @5 ; no, it is not TSM aware
|
|
|
|
MOVEA.L 4(SP),A0 ; get pointer to psn record
|
|
MOVE.L A1,(A0) ; return record
|
|
MOVEQ #0,D0 ; return noErr
|
|
@return
|
|
MOVEA.L (SP)+,A0 ; get return address
|
|
LEA 8(SP),SP ; restore sp
|
|
MOVE.W D0,(SP) ; return error in Pascal style
|
|
JMP (A0)
|
|
|
|
|
|
@5
|
|
MOVE.W #tsmNeverRegisteredErr,D0 ; return error
|
|
BRA.S @return
|
|
|
|
ENDWITH
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; Function: pascal OSErr utaGetAppsUseInputWindowFlag(ProcessSerialNumberPtr, booleanPtr)
|
|
; Verify if the application is TSM aware.
|
|
; If the USEINPUTWINDOW flag is set, we treat the app as non-TSM aware!
|
|
; Input: ProcessSerialNumberPtr.
|
|
; Output: D0.W = error code (memFullErr, temNeverRegisteredErr, tsmUseInputWindowErr),
|
|
; D0.W = noErr if it is TSM aware and not using input window.
|
|
; A1.L = ptr(PSNRecord table entry)
|
|
; Register usage: Use D0,D1,A0,A1
|
|
; _______________________________________________________________________________
|
|
UTAGETAPPSUSEINPUTWINDOWFLAG PROC EXPORT
|
|
Import utaTSMAwareApplicationP
|
|
|
|
retaddr equ 0
|
|
booleanPtr equ 4
|
|
psnPtr equ 8
|
|
|
|
|
|
MOVEA.L psnPtr(SP),A1 ; get ProcessSerialNumberPtr
|
|
MOVE.L highLongOfPSN(A1),D0 ; get high half of PSN
|
|
MOVE.L lowLongOfPSN(A1),D1 ; get low half of PSN
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BEQ.S @5 ; no, it is not TSM aware
|
|
MOVE.B PSNRecord.psnAppUseInputWindowP(A1),D1; get the byte
|
|
@3
|
|
MOVEQ #0,D0 ; return noErr
|
|
MOVEA.L (SP)+,A0 ; get return address
|
|
MOVEA.L (SP)+,A1 ; get boolean address
|
|
MOVE.B D1,(A1) ; return flag
|
|
MOVE.L A0,(SP) ; remove parameter
|
|
MOVE.W D0,4(SP) ; return error in Pascal style
|
|
RTS
|
|
|
|
@5
|
|
MOVE.W #tsmNeverRegisteredErr,D0 ; return error
|
|
BRA.S @3
|
|
|
|
ENDP
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; Function: pascal OSErr utaIsAppTSMAwareAndNotUsingIW(ProcessSerialNumberPtr)
|
|
; Verify if the application is TSM aware and use input window or not.
|
|
; If the USEINPUTWINDOW flag is set, we treat the app as non-TSM aware!
|
|
; Input: ProcessSerialNumberPtr.
|
|
; Output: D0.W = error code (memFullErr, temNeverRegisteredErr, tsmUseInputWindowErr),
|
|
; D0.W = tsmUseInputWindowErr means the app is TSM aware !!!!
|
|
; D0.W = noErr if it is TSM aware and not using input window.
|
|
; A1.L = ptr(PSNRecord table entry)
|
|
; Register usage: Use D0,D1,A0,A1
|
|
; _______________________________________________________________________________
|
|
UTAISAPPTSMAWAREANDNOTUSINGIW PROC EXPORT
|
|
Import utaTSMAwareApplicationP
|
|
|
|
;; Verify if we have registered this application ...
|
|
MOVEA.L 4(SP),A1 ; get ProcessSerialNumberPtr
|
|
MOVE.L highLongOfPSN(A1),D0 ; get high half of PSN
|
|
MOVE.L lowLongOfPSN(A1),D1 ; get low half of PSN
|
|
BSR utaTSMAwareApplicationP ; is it already registered?
|
|
BEQ.S @5 ; no, it is not TSM aware
|
|
|
|
;; It is registered, A1 = ptr(PSNRecord)
|
|
TST.W psnDoWeReallyUseIW(A1) ; is the document using input window?
|
|
BNE.S @7 ; yes, if any of the 2 flags is set, return error
|
|
MOVEQ #noErr,D0 ; no error
|
|
@3
|
|
MOVEA.L (SP)+,A0 ; get return address
|
|
MOVE.L A0,(SP) ; remove parameter
|
|
MOVE.W D0,4(SP) ; return error in Pascal style
|
|
RTS
|
|
|
|
@5
|
|
MOVE.W #tsmNeverRegisteredErr,D0 ; return error
|
|
BRA.S @3
|
|
|
|
@7
|
|
MOVE.W #tsmUseInputWindowErr,D0 ; return error
|
|
BRA.S @3
|
|
|
|
|
|
ENDP ; xIsApplicationTSMAware END
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; Function: pascal OSErr xInformTSM(msgNumber, msgParamPtr)
|
|
; Inform TSM with some messages
|
|
; Input:
|
|
; Output: noErr if all OK
|
|
; Register usage: Use D0,D1,D2,A0,A1
|
|
; Stack frame:
|
|
; SP => 00(SP).L -> return addr
|
|
; 04(SP).L -> msgParamPtr
|
|
; 08(SP).W -> msgSelector
|
|
; 10(SP).W -> msgResult
|
|
; _______________________________________________________________________________
|
|
XINFORMTSM PROC EXPORT
|
|
Import utCloseAppCommon, utChangeToOldJIM, utInformPMgr, utSuspendResumeApp
|
|
|
|
msgParamPtr equ 4
|
|
msgSelector equ 8
|
|
msgResult equ 10
|
|
|
|
|
|
MOVE.W msgSelector(SP),D0 ; get selector
|
|
BEQ @noopExit ; no op
|
|
MOVEA.L msgParamPtr(SP),A1 ; get param ptr(script/id) <06Feb92 #18>
|
|
|
|
CMP.W #kMsgBkgAppsPSN,D0 ; is SWM passing me the PSN?
|
|
BEQ.S @getSWMsPSN ; yes
|
|
CMP.W #kMsgKillTSMApp,D0 ; kill the application?
|
|
BEQ.S @KillTSMApp ; yes
|
|
|
|
CMP.W #kMsgSuspendApp,D0 ; suspend the non-TSM aware application?
|
|
BEQ.S @SuspendApp ; yes
|
|
|
|
CMP.W #kMsgResumeApp,D0 ; resume the non-TSM aware application?
|
|
BEQ.S @ResumeApp ; yes
|
|
|
|
CMP.W #kMsgHelpHELPMgr,D0 ; kMsgHelpHELPMgr?
|
|
BEQ.W @tsmHelpMgrPatch ; yes
|
|
|
|
CMP.W #kMsgChangeToOldJIM,D0 ; change to old JIM
|
|
BNE.W @bad ; no
|
|
|
|
|
|
|
|
; _______________________________________________________________
|
|
; Function: void utChangeToOldJIM()
|
|
; User wants to switch to old input method (for Japanese script only)
|
|
; Input: none
|
|
; A1 = param record pointer
|
|
; Output: noErr if all OK
|
|
; tsmTSNotOpenErr = JIM is not open.
|
|
; _______________________________________________________________
|
|
|
|
MOVE.L A1,-(SP) ; pass the parameter <06Feb92 #18>
|
|
JSR utChangeToOldJIM ; for Japanese script only
|
|
TST.L (SP)+ ; pop param <06Feb92 #18>
|
|
BRA.S @noopExit ; and exit
|
|
|
|
|
|
; _______________________________________________________________
|
|
; Function: void SuspendApp()
|
|
; User wants to switch to old input method (for Japanese script only)
|
|
; Input: none
|
|
; A1 = param record pointer
|
|
; Output: noErr if all OK
|
|
; tsmTSNotOpenErr = JIM is not open.
|
|
; _______________________________________________________________
|
|
@SuspendApp
|
|
MOVE.L #kTSMSuspend,-(SP) ; pass the parameter
|
|
|
|
@SuspendResume
|
|
JSR utSuspendResumeApp ; suspend/resume
|
|
TST.L (SP)+ ; pop param
|
|
BRA.S @noopExit ; and exit
|
|
|
|
@ResumeApp
|
|
MOVE.L #kTSMResume,-(SP) ; pass the parameter
|
|
BRA.S @SuspendResume
|
|
|
|
|
|
|
|
; _______________________________________________________________
|
|
; Function: utKillTSMAwareApplication(ProcessSerialNumberPtr)
|
|
; Called from Patches:MiscPatches.a
|
|
; Input: ProcessSerialNumberPtr.
|
|
; A1 = param record pointer
|
|
; Output: noErr if all OK
|
|
;
|
|
; Modification history:
|
|
; 25Feb92 KST If the app is not TSM aware, we'll send an AE to SWM
|
|
; ask it to close its input window.
|
|
; 27Feb92 KST Set tsmKillApplicationP flag to signal we're killing the
|
|
; TSM aware application, and the menu is already killed !!
|
|
; 27Mar92 KST If the app is not TSM aware, we'll not be called.
|
|
; _______________________________________________________________
|
|
@KillTSMApp
|
|
|
|
;; When 'utCloseAppCommon' is called, it expects D2 is used as a flag,
|
|
;; and the stack frame looks like this:
|
|
;
|
|
; SP --> highLongOfPSN (long)
|
|
; lowLongOfPSN (long)
|
|
; return address (long)
|
|
; (high addr) result (word)
|
|
;
|
|
; ¥¥ Do not change this without changing XCLOSETSMAWAREAPPLICATION !!
|
|
|
|
MOVEA.L ExpandMem,A0
|
|
MOVEA.L ExpandMemRec.emTSMGlobals(A0),A0; get TSM global in A0
|
|
ST.B TSMVarsRec.tsmKillApplicationP(A0) ; set flag <#20>
|
|
|
|
MOVEQ #1,D2 ; set flag, force close the app
|
|
SUBA.W #2,SP ; room for result
|
|
PEA @return2Here ; return address
|
|
MOVE.L lowLongOfPSN(A1),D1 ; get low half of PSN
|
|
MOVE.L D1,-(SP) ; push low PSN
|
|
MOVE.L highLongOfPSN(A1),D1 ; get high half of PSN
|
|
MOVE.L D1,-(SP) ; push hign PSN
|
|
JMP utCloseAppCommon ; use common code, D2 is the flag
|
|
@return2Here
|
|
ADDA.W #2,SP ; ignore error
|
|
MOVEA.L ExpandMem,A0
|
|
MOVEA.L ExpandMemRec.emTSMGlobals(A0),A0; get TSM global in A0
|
|
CLR.B TSMVarsRec.tsmKillApplicationP(A0) ; clear flag <#20>
|
|
|
|
MOVEQ #0,D0 ; always success
|
|
BRA.S @noopExit ; and exit
|
|
|
|
; _______________________________________________________________
|
|
; Function: getSWMsPSN(SWM's ProcessSerialNumberPtr)
|
|
; Input: ProcessSerialNumberPtr.
|
|
; A1 = param record pointer
|
|
; Output: noErr if all OK
|
|
; _______________________________________________________________
|
|
@getSWMsPSN
|
|
Import xInitTSMAwareDriver
|
|
|
|
MOVEA.L ExpandMem,A0
|
|
MOVEA.L ExpandMemRec.emTSMGlobals(A0),A0; get TSM global in A0
|
|
MOVE.L highLongOfPSN(A1),D1 ; get high ID
|
|
MOVE.L D1,TSMVarsRec.tsmSWMHighPSN(A0) ; save in TSM global
|
|
MOVE.L lowLongOfPSN(A1),D1 ; get low ID
|
|
MOVE.L D1,TSMVarsRec.tsmSWMLowPSN(A0) ; save in TSM global
|
|
|
|
|
|
JSR utInformPMgr ; set up flag
|
|
|
|
MOVEA.L msgParamPtr(SP),A0 ; get param ptr which points at the PSN
|
|
MOVEA.L (SP),A1 ; get return addr
|
|
SUBQ #2,SP ; get 2 more bytes on the
|
|
MOVE.L highLongOfPSN(A0),highLongOfPSN(SP)
|
|
MOVE.L lowLongOfPSN(A0),lowLongOfPSN(SP)
|
|
MOVE.L A1,8(SP) ; move the return address
|
|
JMP xInitTSMAwareDriver ; return through InitTSMAware
|
|
|
|
|
|
@noopExit ; exit point shared by all InformTSM subfunctions
|
|
|
|
MOVEA.L (SP),A1 ; get return addr
|
|
LEA 10(SP),SP ; pop off params
|
|
MOVE.W D0,(SP) ; result
|
|
JMP (A1) ; return to caller
|
|
|
|
MOVEQ #0,D0 ; always success
|
|
BRA.S @noopExit ; and exit
|
|
|
|
@bad ; bad selector
|
|
MOVE.W #paramErr,D0 ; return error
|
|
BRA.S @noopExit
|
|
|
|
|
|
|
|
|
|
; _______________________________________________________________
|
|
; Function: tsmHelpMgrPatch
|
|
; Input:
|
|
; A1 = param record pointer
|
|
; Output: 1. return noErr if the mouse is over a floating window and,
|
|
; 2. also return that windowptr in tsmHelpWindowPtr, and
|
|
; 3. if the mouse is over content region, we'll try to open the
|
|
; resource file and return the refnum in tsmHelpRefnum.
|
|
; (If the window is a system floating window and refcon <> nil).
|
|
; Side effect:
|
|
; If we return noErr, then tsmHelpWindowPtr must contains a floating window,
|
|
; because Help Manager will later swap the layer to floating layer.
|
|
;
|
|
; (6) parameter for kMsgHelpHELPMgr -- record of 10 bytes:
|
|
; tsmHelpRefnum EQU 0 ; > 0 if we opened IM's resource file
|
|
; tsmHelpWindowPtr EQU 2 ; nil if no floating window
|
|
; tsmHelpSavedLayer EQU 6 ; temp. storage for Help Manager to swap the layer
|
|
; tsmHelpRecSize EQU tsmHelpSavedLayer+4
|
|
; _______________________________________________________________
|
|
@tsmHelpMgrPatch
|
|
MOVEM.L A2/A3,-(SP) ; save A2/A3
|
|
CLR.W tsmHelpRefnum(A1) ; clear Refnum
|
|
CLR.L tsmHelpWindowPtr(A1) ; clear WindowPtr
|
|
MOVEA.L A1,A2 ; A2 = param ptr
|
|
|
|
|
|
SUBQ #2,-(SP) ; room for result
|
|
MOVE.L Mouse,-(SP) ; pass the global mouse on stack
|
|
PEA tsmHelpWindowPtr(A2) ; pass WindowPtr
|
|
_FindServiceWindow
|
|
MOVE.W (SP)+,D0 ; over our window?
|
|
BEQ.S @helpErrReturn ; no
|
|
|
|
CMP.W #inSysWindow,D0 ; in system item, menubar <#46>
|
|
BLE.S @helpErrReturn ; exit if yes, not over a floater <#46>
|
|
|
|
CMP.W #inContent,D0 ; in content?
|
|
BNE.S @windowHasNoInstance ; no, just swap the layer
|
|
|
|
MOVEA.L tsmHelpWindowPtr(A2),A3 ; save the window ptr in A3
|
|
|
|
;; OK, the mouse is over a floating window so open the resource file so that
|
|
;; Help Manager can dig out the Balloon resource ...
|
|
;; But first, let's check if the window is a system floating window and refcon <> nil. <#45>
|
|
;; from here on, we return noErr to indicate the mouse is over a floater ...
|
|
|
|
CMP.W #systemFloatKind,WindowRecord.windowKind(A3) ; is this floater belonging to a text service <#45>
|
|
BNE.S @windowHasNoInstance ; if not, don't try to open its resource file <#45>
|
|
|
|
MOVE.L WindowRecord.refcon(A3),D0 ; is there an Instance?
|
|
BEQ.S @windowHasNoInstance ; if not, then don't try to open anything
|
|
|
|
SUBQ #2,-(SP) ; room for result
|
|
MOVE.L D0,-(SP) ; the Component instance
|
|
;; need special case for SWM
|
|
|
|
_OpenComponentResFile
|
|
MOVE.W (SP)+,D0 ; is it open?
|
|
BLE.S @helpErrReturn ; no
|
|
MOVE.W D0,tsmHelpRefnum(A2) ; return the RefNum
|
|
|
|
@windowHasNoInstance
|
|
MOVEQ #0,D0 ; OK
|
|
BRA.S @helpPopStack
|
|
|
|
@helpErrReturn
|
|
CLR.W tsmHelpRefnum(A2) ; clear Refnum
|
|
CLR.L tsmHelpWindowPtr(A2) ; clear WindowPtr
|
|
MOVE.W #paramErr,D0 ; return error
|
|
|
|
@helpPopStack
|
|
MOVEM.L (SP)+,A2/A3 ; restore A2/A3
|
|
BRA.S @noopExit
|
|
|
|
|
|
|
|
ENDP ; XINFORMTSM END
|
|
|
|
; END InformTSM
|
|
|
|
|
|
|
|
|
|
;; Begin patches ...
|
|
|
|
IF not BuildTSMInit THEN
|
|
|
|
; _______________________________________________________________________________
|
|
; SetCursor Patch
|
|
;
|
|
; Applications such as Finder periodically set the cursor. This is a problem
|
|
; if IM changes the cursor over floating window. The cursor will now flash
|
|
; because 2 parties compete changing the cursor. This patch will temporarily
|
|
; disable the SetCursor call if IM or SWM changed the cursor.
|
|
; _______________________________________________________________________________
|
|
|
|
__SetCursorPatch PatchProc _SetCursor,(Plus,SE,II,Portable,IIci)
|
|
|
|
move.l ExpandMem,a0 ; good old ExpandMem again
|
|
move.l ExpandMemRec.emTSMGlobals(a0),a0 ; our global ptr into a0
|
|
|
|
btst #kIMJustSetCursorBit,TSMVarsRec.tsmPatchFlags(a0) ; should we let SetCursor calls through?
|
|
bne.s @JustRTS ; flag is on nobody can set the cursor until it clears
|
|
|
|
;; kSWMJustSetCursorBit is set in SWM driver ....
|
|
btst #kSWMJustSetCursorBit,TSMVarsRec.tsmPatchFlags(a0) ; should we let SetCursor calls through?
|
|
bne.s @JustRTS ; flag is on nobody can set the cursor until it clears
|
|
|
|
jmpOld ; flag is clear go ahead and set the cursor
|
|
nop ; <sm5>
|
|
@JustRTS
|
|
move.l (sp)+,a0 ; pop return address <32>
|
|
addq #4,sp ; flush the parameter on the stack <32>
|
|
jmp (a0) ; return to the caller. <32>
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; PaintBehind Patch
|
|
; AfterDark redraws the screen with FrontWindow(), and grayrgn. This however,
|
|
; does not draw the floating windows. This patch will paint from IM layer if
|
|
; theWindow = frontwindow, and theRegion = GrayRgn.
|
|
; _______________________________________________________________________________
|
|
|
|
__PaintBehindPatch PatchProc _PaintBehind,(Plus,SE,II,Portable,IIci)
|
|
|
|
theRetAddr EQU 0 ; satck frame for this call
|
|
theRegion EQU 4
|
|
theWindow EQU 8
|
|
|
|
|
|
SUBA.W #4,SP
|
|
_FrontWindow
|
|
MOVE.L (SP)+,D0
|
|
CMP.L theWindow(SP),D0 ; draw from the front window?
|
|
BNE.S @NeverMind ; no
|
|
|
|
MOVEA.L GrayRgn,A0 ; get the GRAY region handle
|
|
MOVEA.L (A0),A0 ; dereference it
|
|
LEA rgnBBox+bottom(A0),A0 ; A0 points to bottom
|
|
MOVEA.L theRegion(SP),A1 ; get the region
|
|
MOVEA.L (A1),A1 ; dereference it
|
|
LEA rgnBBox+top(A1),A1 ; A1 points to top
|
|
|
|
;; Note: Pyro always pass the region with -1, -1, bottom+1, right+1,
|
|
;; and this is why I don't branch with BNE or BEQ ...
|
|
|
|
TST.W (A1)+ ; top should be 0
|
|
BGT.S @NeverMind ; if > 0, then don't do anything special
|
|
TST.W (A1)+ ; left should be 0
|
|
BGT.S @NeverMind ; if > 0, then don't do anything special
|
|
|
|
;; A1 points to bottom of rect
|
|
|
|
MOVE.W (A1)+,D0
|
|
CMP.W (A0)+,D0 ; paint the whole desktop?
|
|
BLT.S @NeverMind ; no
|
|
MOVE.W (A1),D0
|
|
CMP.W (A0),D0 ; paint the whole desktop?
|
|
BLT.S @NeverMind ; no
|
|
|
|
;; Here, we assume the guy is trying to paint the whole screen, let's paint the floating windows too.
|
|
;; Dean said: "Just paint from input method's floating layer". -- (04May92)
|
|
;; I tried paint from the root layer, Balloon window's contents doesn't get redraw anyway.
|
|
|
|
SUBA.W #6,SP
|
|
PEA 2(SP)
|
|
_GetFrontServiceWindow
|
|
MOVE.W (SP)+,D0 ; any error?
|
|
BNE.S @NeverMind ; br if error
|
|
MOVE.L (SP)+,D0 ; get the front floating window
|
|
BEQ.S @NeverMind ; br if no floating window
|
|
MOVE.L D0,theWindow(SP) ; paint from the root
|
|
|
|
@NeverMind
|
|
jmpOld ; flag is clear go ahead and set the cursor
|
|
|
|
|
|
|
|
ENDPROC
|
|
|
|
__SystemMenuPatch PatchProc _SystemMenu,(Plus,SE,II,Portable,IIci)
|
|
import CHANGEMENURESULTFORINPUTMETHOD
|
|
|
|
move.l 4(sp),d0 ;get menuresult
|
|
swap d0 ;make the high word low
|
|
cmp.w #-kTSMSystemMenuID,d0 ;is this us?
|
|
bne.s @NotTSMMenu ;
|
|
swap d0 ;put the high word back
|
|
move.l d0,-(sp) ;move it onto the stack
|
|
pea (sp) ;push the address
|
|
jsr CHANGEMENURESULTFORINPUTMETHOD ;and send it to the input method
|
|
addq #4,sp ;get rid of space for menuresult
|
|
rts ;return to caller
|
|
@NotTSMMenu
|
|
jmpOld ;not ours so forget about it
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
; ____________________________________________________________________________________
|
|
; __HMGetBalloonPatch Patch
|
|
; Again, applications such as Finder periodically redraw the Help balloon. This is
|
|
; a problem if there is a help balloon over the floating window. The balloon window
|
|
; will flash because app tries to remove the Balloon and paint one of its own.
|
|
; Trashes D0/A0/A1 -- these are free registers, right?
|
|
; ____________________________________________________________________________________
|
|
|
|
__HMGetBalloonPatch PatchProc _Pack14,(Plus,SE,II,Portable,IIci)
|
|
|
|
cmp.w #kHMGetBalloons,d0 ; is this IsBalloon?
|
|
beq.s @DoGetBalloonPatch ; yes so do it
|
|
nop ; <sm5>
|
|
jmpOld ; it wasn't kHMIsBalloon so call the real Pack14
|
|
|
|
@DoGetBalloonPatch
|
|
|
|
subq #2,sp ; room on the stack
|
|
jsrOld ; and jump to the old one
|
|
move.b (sp)+,d0 ; get resut
|
|
move.b d0,4(sp) ; and put in on the stack
|
|
beq.s @returnOldResult ; no balloon, so return the result to original caller
|
|
|
|
;
|
|
; OK so a ballon is up see if the last window we helped was a floating window
|
|
; we do that by getting the parent of the last window helped
|
|
; and seeing if that parent equals the IMlayer. This patch is for Finder because
|
|
; Finder does not know/care the floating window and draw its own Balloon.
|
|
;
|
|
|
|
; Now check if we are clicked inside of a floating window ... <#44>
|
|
|
|
SUBQ #6,SP ; room for result
|
|
MOVE.L Mouse,-(SP) ; pass the global mouse on stack
|
|
PEA 6(SP) ; pass WindowPtr
|
|
_FindServiceWindow
|
|
MOVE.W (SP)+,D0 ; over our window?
|
|
ADDQ.W #4,SP ; restore the stack
|
|
BEQ.S @returnOldResult ; no
|
|
|
|
CMP.W #inSysWindow,D0 ; in system item, menubar? <#39>
|
|
BLE.S @returnOldResult ; exit if yes, return the original result <#39>
|
|
|
|
MOVEA.L ExpandMem,A1 ; A1 = ExpandMem <#44>
|
|
MOVE.L ExpandMemRec.emTSMGlobals(A1),D0 ; get TSM global <#44>
|
|
BEQ.S @noTSM ; br if no TSM <#44>
|
|
MOVEA.L D0,A0 ; A0 = TSM global <#44>
|
|
|
|
;; If we are inside of PopUpMenuSelect, then say the balloon is on so that a previous balloon will be removed correctly.
|
|
BTST #kInTSMPopUpMenuSelectCall,TSMVarsRec.tsmPatchFlags(A0) ; are we in PopUpMenuSelect? <#44>
|
|
BNE.S @returnOldResult ; flag is on so return the original result <#44>
|
|
|
|
@noTSM
|
|
;; If we are inside of MenuSelect, then say the balloon is on so that a previous balloon will be removed correctly.
|
|
;; Note Help Manager already patched out __MenuSelect and set a flag in emHelpGlobals, so we'll just use that one !!
|
|
MOVE.L ExpandMemRec.emHelpGlobals(A1),A0 ; A0 = HelpMgr global ptr <#47>
|
|
TST.B hmgInMenuSelectFlag(A0) ; are we in MenuSelect? <#47>
|
|
BNE.S @returnOldResult ; yes so return the original result <#47>
|
|
|
|
;; end change of #44, #47
|
|
|
|
|
|
MOVE.B #0,4(sp) ; pretend no help windows are up by slamming the result to 0
|
|
|
|
@returnOldResult
|
|
RTS ; and return
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
|
|
; ____________________________________________________________________________________
|
|
; __PopUpMenuSelect Patch <#44>
|
|
; If there is a popup menu in the floating window and with HelpMgr on, need to
|
|
; return the original result from HMGetBalloon so that balloon will be removed.
|
|
; ____________________________________________________________________________________
|
|
|
|
__PopUpMenuSelect PatchProc _PopUpMenuSelect,(Plus,SE,II,Portable,IIci)
|
|
|
|
retAddr EQU 8 ; saved 2 registers
|
|
|
|
MOVEM.L A0-A1,-(SP) ; free A0/A1
|
|
MOVEA.L ExpandMem,A1
|
|
MOVE.L ExpandMemRec.emTSMGlobals(A1),D1 ; get TSM global
|
|
BEQ.S @noEntry ; br if no TSM
|
|
MOVEA.L D1,A1 ; A1 = TSM global
|
|
BSET #kInTSMPopUpMenuSelectCall,TSMVarsRec.tsmPatchFlags(A1) ; say we're in PopupMenuSelect
|
|
MOVE.L retAddr(SP),D1 ; return address
|
|
MOVE.L D1,TSMVarsRec.tsmPopUpReturnAddr(A1) ; save the return address
|
|
LEA @return2Here,A0 ; return to here
|
|
MOVE.L A0,retAddr(SP)
|
|
|
|
;; OK, now to prevent from text services to receive an update event from SWM driver,
|
|
;; we need to tell SWM not to route events to TSM/text services ...
|
|
MOVE.W TSMVarsRec.tsmSWMDrvrRefNum(A1),D1 ; get refnum
|
|
BEQ.S @noEntry ; br if no SWM
|
|
NOT.W D1 ; unit entry := -1 * (refNum + 1)
|
|
cmp.w UnitNtryCnt,D1 ; is there an entry of this number?
|
|
bhs.s @noEntry ; no, so return NIL
|
|
LSL.W #2,D1 ; index := entry * 4
|
|
MOVE.L UTableBase,A1 ; unit I/O table [pointer]
|
|
MOVEA.L 0(A1,D1.W),A1 ; return DCtlHandle
|
|
MOVEA.L (A1),A1 ; dereference the handle
|
|
MOVEA.L dCtlStorage(A1),A1 ; get storage handle
|
|
MOVEA.L (A1),A1 ; dereference the handle
|
|
|
|
ST swmdrvrRecordMenuIsDown(A1) ; set the byte to true
|
|
@noEntry
|
|
MOVEM.L (SP)+,A0-A1 ; restore A0/A1
|
|
|
|
jmpOld ; and jump to the old one
|
|
|
|
@return2Here
|
|
|
|
MOVEA.L ExpandMem,A1
|
|
MOVE.L ExpandMemRec.emTSMGlobals(A1),A1 ; get TSM global
|
|
BCLR #kInTSMPopUpMenuSelectCall,TSMVarsRec.tsmPatchFlags(A1) ; we're not in PopupMenuSelect
|
|
MOVE.L TSMVarsRec.tsmPopUpReturnAddr(A1),D1 ; get the return address
|
|
MOVE.L D1,-(SP) ; return to caller
|
|
|
|
|
|
MOVE.W TSMVarsRec.tsmSWMDrvrRefNum(A1),D1 ; get refnum
|
|
BEQ.S @exit ; br if no SWM
|
|
NOT.W D1 ; unit entry := -1 * (refNum + 1)
|
|
cmp.w UnitNtryCnt,d1 ; is there an entry of this number?
|
|
bhs.s @exit ; no, so return NIL
|
|
LSL.W #2,D1 ; index := entry * 4
|
|
MOVE.L UTableBase,A1 ; unit I/O table [pointer]
|
|
MOVEA.L 0(A1,D1.W),A1 ; return DCtlHandle
|
|
MOVEA.L (A1),A1 ; dereference the handle
|
|
MOVEA.L dCtlStorage(A1),A1 ; get storage handle
|
|
MOVEA.L (A1),A1 ; dereference the handle
|
|
CLR.B swmdrvrRecordMenuIsDown(A1) ; clear the byte
|
|
|
|
@exit
|
|
|
|
RTS
|
|
|
|
ENDPROC
|
|
|
|
|
|
ENDIF ; end if building INIT
|
|
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; pascal short Gestalt(OSType selector, long responsePtr)
|
|
; Define a new Gestalt call to return TSM's version.
|
|
; _______________________________________________________________________________
|
|
|
|
TSMGestalt PROC EXPORT
|
|
|
|
MOVE.L 4(A7),A0 ; Return result to caller (responsePtr)
|
|
MOVE.L #TSMVersion,(A0) ; get version number
|
|
MOVE.L (SP)+,A0 ; Get return address
|
|
ADDQ #8,A7 ; Nuke some parameters
|
|
CLR.W (A7) ; no error
|
|
JMP (A0) ; return
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
|
|
|
|
;============================================================================================
|
|
;
|
|
; InstallProc for the Text Services Manager -- allocate memory for globals.
|
|
;
|
|
;============================================================================================
|
|
|
|
TSMGRINSTALL proc export
|
|
WITH PSNRecord
|
|
|
|
|
|
|
|
MOVEA.L ExpandMem,A1
|
|
MOVE.L ExpandMemRec.emTSMGlobals(A1),D0 ; get TSM global
|
|
MOVEA.L D0,A1 ; clear A1 flag
|
|
BEQ.S @noGlobal ; not initialized
|
|
MOVE.W TSMVarsRec.tsmRecSize(A1),D0 ; record size
|
|
CMP.W #TSMVarsRec.TSMVarsRecSize,D0 ; are they the same size?
|
|
BEQ.W @return ; yes, reuse it
|
|
|
|
|
|
@noGlobal
|
|
;; allocate TSM global, and save it in ExpandMem ...
|
|
;; A1 <> nil if we have allocated the globals already.
|
|
;; all fields are initially cleared (0 or flase) !
|
|
MOVE.L #TSMVarsRec.TSMVarsRecSize,D0
|
|
_NewPtr ,Sys ,Clear ; allocate global from system heap
|
|
BNE.W @cantboot ; fatal error
|
|
|
|
;; A0 = new record, A1 = old record, copy A1 => A0,
|
|
MOVE.L A1,D0 ; do we have an old one?
|
|
BEQ.S @noOldRecord ; no
|
|
MOVEQ #0,D0
|
|
MOVE.W TSMVarsRec.tsmRecSize(A1),D0 ; old record size
|
|
EXG A0,A1 ; A0 = old record
|
|
_BlockMove ; A0 => A1 (preserved)
|
|
_DisposePtr ; free the old one
|
|
MOVEA.L ExpandMem,A0
|
|
MOVE.W #TSMVarsRec.TSMVarsRecSize,TSMVarsRec.tsmRecSize(A1) ; new record size
|
|
MOVE.L A1,ExpandMemRec.emTSMGlobals(A0) ; save the new TSM global in ExpandMem
|
|
BRA.S @return ; OK
|
|
|
|
@noOldRecord
|
|
MOVE.W #TSMVarsRec.TSMVarsRecSize,TSMVarsRec.tsmRecSize(A0)
|
|
MOVE.B #0, TSMVarsRec.tsmMajorVersion(A0) ; 0.1
|
|
MOVE.B #kTSMVersion, TSMVarsRec.tsmMinorVersion(A0) ; not released yet
|
|
MOVE.W #kUnknownScript,TSMVarsRec.tsmCurrentSLRec.fScript(A0) ; current script = unknown
|
|
MOVE.W #kUnknownLanguage,TSMVarsRec.tsmCurrentSLRec.fLanguage(A0) ; current language = unknown
|
|
|
|
MOVE.L #$4B534354,TSMVarsRec.tsmDebugSignature(A0)
|
|
|
|
MOVEA.L ExpandMem,A1
|
|
MOVE.L A0,ExpandMemRec.emTSMGlobals(A1) ; save TSM global in ExpandMem
|
|
MOVE.L A0,A1 ; save global in A1
|
|
|
|
;; allocate TSM aware PSN table, and save it in TSM global ...
|
|
MOVE.L #kPSNTableDefSize,D0 ; allocate TSM aware PSN table
|
|
_NewPtr ,Sys ,Clear ; from system heap
|
|
BNE.S @cantboot2 ; fatal error
|
|
|
|
MOVE.L A0,TSMVarsRec.tsmIAPSNTablePtr(A1) ; save the table addr in global too
|
|
MOVE.W #kDefTableEntryN,D0
|
|
MOVE.W D0,iaTotalPSNEntryN(A0) ; total entry number of the table
|
|
; LEA iaPSNStart(A0),A0 ; A0 points to the start of the array
|
|
; SUBQ.W #1,D0 ; for dbra
|
|
@loop1
|
|
; MOVE.W #kPSNTableSignature,psnTableSignature(A0) ; valid table signature
|
|
; ADDA.W #kPSNEntrySize,A0 ; next record
|
|
; DBRA D0,@loop1
|
|
; can't update default IM in TSM globals because we can't save the component, just description. too bad.
|
|
|
|
MOVE.L #gestaltTSMgrVersion,D0 ; selector to d0
|
|
import TSMGestalt
|
|
lea TSMGestalt,A0 ; get our function pointer into A0
|
|
_NewGestalt ; install it
|
|
|
|
MOVEQ #0,D0 ; all done
|
|
@return
|
|
RTS
|
|
|
|
@cantboot2
|
|
MOVE.L A1,A0
|
|
_DisposePtr ; free global
|
|
MOVEA.L ExpandMem,A0
|
|
CLR.L ExpandMemRec.emTSMGlobals(A0) ; clear TSM global
|
|
|
|
@cantboot
|
|
MOVEQ #dsMemFullErr,D0 ; no mem error
|
|
_SysError
|
|
BRA.S @return
|
|
|
|
ENDWITH
|
|
ENDPROC ; TSMgrInstall END
|
|
|
|
|
|
|
|
;============================================================================================
|
|
;
|
|
; old input method support.
|
|
;
|
|
;============================================================================================
|
|
|
|
|
|
; _______________________________________________________________________________
|
|
; pascal Boolean OldJapaneseInputMethodExists( short fepID);
|
|
;
|
|
; return true if the old Input Method which has the given id is installed.
|
|
; _______________________________________________________________________________
|
|
|
|
|
|
ojimRecord RECORD {a6link},decr
|
|
boolResult ds.w 1 ; activate result.
|
|
fepID ds.w 1 ; interface routine ID number.
|
|
return ds.l 1 ; return address.
|
|
a6link ds.l 1 ; old a6 register.
|
|
ojimRecord equ * ; size of local variables.
|
|
ENDR
|
|
|
|
OLDJAPANESEINPUTMETHODEXISTS PROC EXPORT
|
|
WITH ojimRecord,intfRecord,ScriptSystemGlobals,SMgrRecord
|
|
|
|
link a6,#ojimRecord
|
|
clr.w boolResult(a6) ; assume not found.
|
|
GetSmgrCore a0 ; load script manager core.
|
|
move.l smgrEntry+(smJapanese*4)(a0),d0 ; load doubleTalkRecord for Japanese.
|
|
beq.s @exit ; not installed. (something wrong)
|
|
move.l d0,a0
|
|
|
|
move.l intfArray(a0),d0 ; get the array handle.
|
|
ble.s @exit ; nil or negative -> something wrong.
|
|
move.l d0,a1 ; Load table handle.
|
|
move.l (a1),a1 ; Load table pointer.
|
|
move.l (a1)+,d0 ; Load table length.
|
|
move.w fepID(a6),d1 ; Load search id number.
|
|
bra.s @1 ; enter loop at bottom
|
|
@0
|
|
move.l (a1)+,a0 ; load table entry.
|
|
cmp.w (a0),d1 ; same id number?
|
|
beq.s @foundID ; yes -> we found it!
|
|
@1 dbra d0,@0 ; do the next entry.
|
|
bra.s @exit
|
|
@foundID
|
|
move.w #$0100,boolResult(a6) ; return (Pascal) true.
|
|
@exit
|
|
unlk a6
|
|
move.l (sp)+,a0 ; pop the return address.
|
|
addq #2,sp ; pop the Integer arguments.
|
|
jmp (a0) ; return to the caller.
|
|
|
|
ENDWITH
|
|
ENDPROC
|
|
|
|
END
|