DIRECTORY Rope, Xl, XTk; X11SelectionOwner: CEDAR DEFINITIONS ~ BEGIN Result: TYPE = {ok, timeout, failed}; Request: TYPE = REF RequestSequence; --state of a particular conversion RequestSequence: TYPE = RECORD [ oh: OwnershipHandle, --describes owner of selection. event: Xl.SelectionRequestEvent, --might be multiple, don't look for target or property. ownerData: REF ¬ NIL, --reserved for owner; ignored internally. refuse: BOOL ¬ FALSE, --option for selection owner to refuse request. anyFailed: BOOL ¬ FALSE, --TRUE in done procedure if any received # ok. transferTQ: Xl.TQ ¬ NIL, -- next: PRIVATE Request ¬ NIL, --queue of requests to prevent multiple isInQueue: PRIVATE BOOL ¬ FALSE, --synchrounous serving of same requestor. isDelayed: PRIVATE BOOL ¬ FALSE, --in case of incompatible requests. index: PRIVATE INT ¬ -1, --state in transfering mulitiple. multiSeq: PRIVATE REF Xl.Card32Sequence ¬ NIL, --private for impl. transferMatch: PRIVATE Xl.Match ¬ NIL, --needed to unregister event catching. timeOutData: PRIVATE REF ¬ NIL, --timer state protected by transferTQ. targets: SEQUENCE length: NAT OF TargetRec ]; TargetRec: TYPE = RECORD [ target: Xl.XAtom, --from request property: Xl.XAtom, --from request response: REF ¬ NIL, --place for the response, or, $Failed type: Xl.XAtom ¬ [0], --of response start: INT ¬ 0, --start unit in response num: INT ¬ 0 --set to INT.LAST--, --number of units used, limited by length... incr: PRIVATE BOOL ¬ FALSE, --using incr protocol unit: PRIVATE INT ¬ 0, --unit size in bytes next: PRIVATE INT ¬ 0, --unit where to start in response remain: PRIVATE INT ¬ 0, --number of units, limited by length... state: PRIVATE REF ¬ NIL, -- received: Result ¬ ok, data: REF ¬ NIL --reserved for owner; ignored by impl ]; RequestProc: TYPE = PROC [request: Request]; GotOwnershipNotifyProc: TYPE = PROC [ --call back on successful AquireOwnership. oh: OwnershipHandle, timeStamp: Xl.TimeStamp, --latest time stamp when selection got aquired. previouslyOwned: BOOL, --whether same widget previously owned selection. previousTime: Xl.TimeStamp --previous time stamp, valid if previouslyOwned. ]; LostOwnershipNotifyProc: TYPE = PROC [ --passed on for a selectionClear event. oh: OwnershipHandle, timeStamp: Xl.TimeStamp, --use it! it is always an error not to do so. event: Xl.SelectionClearEvent ¬ NIL, --set if initiated by an event. previousTime: Xl.TimeStamp --believed last aquired time by this widget. ]; GetTQProc: TYPE = PROC [ --called on a selectionRequest event, running on serviceTQ. oh: OwnershipHandle, event: Xl.SelectionRequestEvent ¬ NIL ] RETURNS [transferTQ: Xl.TQ ¬ NIL]; --NIL causes usage of OwnershipRec.sharedTransferTQ ApplicationClass: TYPE = REF ApplicationClassRec; --neither widget nor connection specific ApplicationClassRec: TYPE = RECORD [ selection: Rope.ROPE, --which this code is supporting. convert: RequestProc, --called on transferTQ; request for selection. done: RequestProc ¬ NIL, --called on transferTQ; acknowledgement of transfer. gotOnwership: GotOwnershipNotifyProc ¬ NIL, --called on initiateTQ. lostOwnership: LostOwnershipNotifyProc ¬ NIL, --called on initiateTQ to announce server lost ownership. Warning: lostOwnership may be called denoting the previous selection. A request for a new ownership does a server roundtrip, while the AquireOwnership proc still holds the initiateTQ lock; therefore the new aquire may come through before the lostOwnership notification does. Watch those time stamps!. getTransferTQ: GetTQProc ¬ NIL, --If available, called on serviceTQ to return a transferTQ used for this transaction. If this procedure is defaulted, uses oh.sharedTransferTQ. checkTime: BOOL ¬ TRUE, --automatically refuse requests with bad time. defaultTimeoutMsec: INT ¬ 12000, --can be overwritten on a per ownership base targets: LIST OF Rope.ROPE ¬ NIL, --useful for TARGETS target classData: REF ¬ NIL --reserved for the client; ignored by impl ]; OwnershipHandle: TYPE = REF OwnershipRec; OwnershipRec: TYPE = RECORD [ w: XTk.Widget, --might be handy for clients (not internally used) ac: ApplicationClass, selection: Xl.XAtom ¬ [0], --internalized on active connection from ac timeoutMsec: INT ¬ 0, --timeout selection requests; initialized from ac ownershipData: REF ¬ NIL, --reserved for the client (not internally used) iHaveIt: BOOL ¬ FALSE, --clients must not change ownedSince: Xl.TimeStamp ¬ [0], --clients must not change initiateTQ: Xl.TQ, sharedTransferTQ: Xl.TQ, --NIL means each requests gets new transferTQ wod: PRIVATE WidgetOData ¬ NIL, --per widget data shared by all selections serviceQueue: PRIVATE Request ¬ NIL, --monitored on sharedTransferTQ, if ~NIL reserved: PRIVATE REF ¬ NIL --prevent recompilation on experiments ]; PreEstablishServiceTQ: PROC [w: XTk.Widget, serviceTQ: Xl.TQ ¬ NIL]; EstablishSelectionOwnerProtocol: PROC [w: XTk.Widget, ac: ApplicationClass, initiateTQ: Xl.TQ ¬ NIL, transferTQ: Xl.TQ ¬ NIL, ownershipData: REF ¬ NIL] RETURNS [oh: OwnershipHandle]; DeEstablishSelectionOwnerProtocol: PROC [oh: OwnershipHandle]; ChangeTimeOut: PROC [oh: OwnershipHandle, timeoutMsec: INT]; AquireOwnership: PROC [oh: OwnershipHandle, time: Xl.TimeStamp] RETURNS [success: BOOL ¬ FALSE]; ReleaseOwnership: PROC [oh: OwnershipHandle, time: Xl.TimeStamp ¬ Xl.currentTime]; WidgetOData: PRIVATE TYPE = REF WidgetODataRec; WidgetODataRec: PRIVATE TYPE; FillSomeTargets: PROC [request: Request, targetIdx: NAT, assignFailed: BOOL ¬ FALSE] RETURNS [success: BOOL]; END. ˆX11SelectionOwner.mesa Copyright Σ 1990, 1991 by Xerox Corporation. All rights reserved. Christian Jacobi, November 12, 1990 5:42 pm PST Christian Jacobi, August 14, 1991 2:02 pm PDT Duties of a selection owner according to ICCCM. Main differences to Xt intrinsics: Increased parallelism. Completely hidden usage of the INCR protocol, because clients ought not know. Show usage of MULTIPLE protocol, because some clients DO want to know. More useful done proc. --Represents state of handling a particular conversion request. --public fields for transfer of data --private internal fields --private, internally useful fields; monitored on transferTQ. --per target data --inputs to selection owners convert proc (setup internally according to request). --outputs from selection owners convert proc (moved to server by impl). --private internal fields (state to implement INCR protocol) --inputs to selection owners done proc (specifying acknowledgements) --space for data of the selection owner; shared in convert and done proc Use for request of conversion and for acknowledgements. --Modifications after per widget data is established may or may not be ignored and is bad style. --Actual procedures for selection value transfer --Feedback procedures for selection ownership. --Clients are expected to give visual feedback whether they own a selection. --Warning: gotOnwership and lostOwnership calls are not necessarily "correctly bracketed". --Other parametrizations. --Represents the per widget / per selection data. --Clients must NOT modify any data as this might cause confusion. --All following fields ought to be un-interesting for clients Establishes ThreadQueue listening for requests on all selections of a particular widget. Optional, but if used it must be called before first call of EstablishSelectionOwnerProtocol. I'm not yet sure whether it is really worthwhile sharing a ThreadQueue for all selections. WARNING: Selection requests with large side effects have to use the INSERT_SELECTION convention. ICCCM 2.6.3.2. As I want to hide this knowledge from selection requestors (Do I want to?) ownership could be established hiddenly) Install ownership duties for a particular selection. This does not actually aquire ownership but registers the procedures necessary to aquire it. Must not be called more then once per widget and selection tuple. Any subset of ThreadQueues in {serviceTQ, initiateTQ, transferTQ, rootTQ} may be equal; choice is only a matter of robustness on errors and limitations to parallelism. A NIL transferTQ means different requests are handled in parallel. Undoes EstablishSelectionOwnerProtocol. ...but only for actions not yet started. Aquires active selection ownership. OwnershipHandle must have been previously established. Do not use Xl.currentTime. Voluntarily releases selection ownership. OwnershipHandle must have been previously established. It is ok but not specially clever to use Xl.currentTime. Conveniant procedure to fill out some standard targets in a request. See the documentation for a list of target types this procedure will handle. request, targetIdx: denote which target this procedure should answer. assignFailed: whether procedure should assign $Failed to response if it can't handle it. Returns success: "procedure new what to do for target". The proposed method how to handle some targets in a non-standard way, is to not call FillSomeTargets for those targets. Κe–(cedarcode) style•NewlineDelimiter ˜code™Kšœ Οeœ7™BK™/K™-K™—šΟk œ˜K˜—KšΟnœžœž œ˜&Kšž˜K˜™/™#K™K™MK™FK™——K˜Kšœžœ˜%K˜Kšœ žœžœΟc"˜Hšœžœžœ˜ K™?K™$Kšœ ˜5Kšœ! 7˜XKšœ žœžœ )˜@Kšœžœžœ /˜FKšœ žœžœ .˜GK™Kšœžœžœ ˜Kšœ=™=Kšœžœ žœ (˜FKšœ žœžœžœ )˜KKšœ žœžœžœ #˜EKšœžœžœ !˜;Kšœ žœžœžœ ˜BKšœžœ žœ &˜MKšœ žœžœžœ &˜GK™Kšœ žœ žœžœ ˜*K˜K˜—šœ žœžœ˜Kšœ* (™RKšœ ˜!Kšœ ˜#K™GKšœ žœžœ %˜>Kšœ  ˜$Kšœžœ ˜)Kšœžœ œ ,˜NK™=Kšœžœžœžœ ˜1Kšœžœžœ ˜,Kšœžœžœ !˜9Kšœžœžœ '˜@Kšœžœžœžœ ˜K™DK˜K™IKšœžœžœ %˜8K˜—K˜šœ žœžœ˜,K™7K™—šœžœžœ *˜PK˜Kšœ /˜HKšœžœ 1˜MKšœ 0˜KK˜K˜—šœžœžœ '˜NK˜Kšœ -˜FKšœ žœ ˜DKšœ ,˜JK˜K˜—šœ žœžœ ;˜TKšœ˜Kšœ"ž˜%Kšœžœžœžœ 3˜X—K˜Kšœžœžœ (˜[šœžœžœ˜$K™`Kšœžœ  ˜7K™0Kšœ .˜EKšœžœ 4˜NK™.K™LKšœ X™ZKšœ'žœ ˜EKšœ)žœ ι˜—Kšœžœ ˜°K™Kšœ žœžœ .˜FKšœžœ  ,˜MKš œ žœžœžœžœ ˜=Kšœ žœžœ *˜@K˜K˜—Kšœžœžœ˜)šœžœžœ˜K™1K™AKšœ 2˜BK˜Kšœ +˜FKšœ žœ 1˜HKšœžœžœ /˜IKšœ žœžœ  Πbc ˜2Kšœ   ‘ ˜9K™=Kšœ˜Kšœ -˜FKšœžœžœ ,˜LKšœžœ žœ (˜MKšœ žœžœžœ &˜CK˜K˜—šŸœžœ$žœ˜DK™·K™[K™εK™—šŸœžœ;žœžœžœžœžœ˜ΆK™ΧKšœμ™μK˜—šŸ!œžœ˜>Kšœ(™(K˜—šŸ œžœ$žœ˜