DIRECTORY Basics, BasicTime, Process, Rope, Xl, XlDispatch, XlPrivate, XlPrivateResources, XlPrivateTypes, XlKeyButPrivate, XlPrivateErrorHandling, XlService; XlImplRequests: CEDAR MONITOR LOCKS c USING c: Connection IMPORTS Basics, BasicTime, Process, Rope, Xl, XlDispatch, XlPrivate, XlPrivateErrorHandling, XlPrivateResources, XlKeyButPrivate, XlService EXPORTS Xl, XlPrivate, XlPrivateTypes SHARES XlDispatch, XlPrivate, XlPrivateResources ~ BEGIN OPEN Xl, XlPrivate; ROPE: TYPE ~ Rope.ROPE; ConnectionPrivateImplRec: TYPE ~ XlPrivateTypes.ConnectionPrivateImplRec; <> ConnectionPrivate: PUBLIC TYPE ~ XlPrivateTypes.ConnectionPrivateImplRec; GetWindowAttributes: PUBLIC PROC [c: Connection, window: Window] RETURNS [at: RepliedAttributes] = { reply: Reply; action: PROC [c: Connection] = { BInit[c, 3, 0, 2]; BPutDrawable[c, window]; reply ¬ FinishWithReply[c]; }; DoWithLocks[c, action, NIL]; CheckReply[reply]; at.backingStore ¬ VAL[ERead8[reply]]; Skip[reply, 6]; at.visual.visualID ¬ ERead32[reply]; at.class ¬ VAL[ERead16[reply]]; at.bitGravity ¬ VAL[ERead8[reply]]; at.winGravity ¬ VAL[ERead8[reply]]; at.backingPlanes ¬ ERead32[reply]; at.backingPixel ¬ ERead32[reply]; at.saveUnder ¬ ERead8[reply]#0; at.isInstalled ¬ ERead8[reply]#0; at.mapState ¬ VAL[ERead8[reply]]; at.overrideRedirect ¬ ERead8[reply]#0; at.colorMap.colorMapID ¬ ERead32[reply]; at.allEventMask ¬ LOOPHOLE[ERead32[reply]]; at.yourEventMask ¬ LOOPHOLE[ERead32[reply]]; at.doNotPropagateMask ¬ LOOPHOLE[ERead32[reply]]; DisposeReply[c, reply]; }; ChangeWindowAttributes: PUBLIC PROC [c: Connection, window: Window, attributes: Attributes, details: Details] ~ { action: PROC [c: Connection] = { mask, n: CARD32; IF ~UnspecifiedEvents[attributes.eventMask] THEN { eventMask: SetOfEvent ¬ XlDispatch.EnforcedSetOfEvent[c, window, attributes.eventMask]; attributes.eventMask ¬ eventMask; }; TRUSTED {[mask, n] ¬ MakeMask[@attributes]}; IF n>0 THEN { BInit[c, 2, 0, 3+n]; BPutDrawable[c, window]; BPut32[c, mask]; TRUSTED {BPutAttributes[c, @attributes]}; FinishWithDetails[c, details]; }; }; DoWithLocks[c, action, details]; }; ConfigureWindow: PUBLIC PROC [c: Connection, window: Window, geometry: Geometry, sibling: Window ¬ nullWindow, stackMode: StackModeExtra ¬ dontChange, details: Details] = { action: PROC [c: Connection] ~ { BInit[c, 12, 0, 3+filled]; BPutDrawable[c, window]; BPut16[c, bitmask]; BSkip[c, 2]; FOR i: INT IN [0..filled) DO IBPut32[c, vals[i]]; ENDLOOP; FinishWithDetails[c, details]; }; Low: PROC [i: INT32] RETURNS [c: CARD32] = INLINE { c ¬ Basics.LowHalf[LOOPHOLE[i]]; }; CheckI16: PROC [i: INT32] = INLINE { IF i>LAST[INT16] OR iLAST[CARD16] THEN ERROR }; bitmask: CARD16 ¬ 0; vals: ARRAY [0..8) OF CARD32; filled: INT ¬ 0; IF window=nullWindow THEN ERROR; IF geometry.pos.x#dontUse THEN { CheckI16[geometry.pos.x]; vals[filled] ¬ Low[geometry.pos.x]; filled ¬ filled + 1; bitmask ¬ bitmask+1; }; IF geometry.pos.y#dontUse THEN { CheckI16[geometry.pos.y]; vals[filled] ¬ Low[geometry.pos.y]; filled ¬ filled + 1; bitmask ¬ bitmask+2; }; IF geometry.size.width>0 THEN { CheckC16[geometry.size.width]; vals[filled] ¬ geometry.size.width; filled ¬ filled + 1; bitmask ¬ bitmask+4; }; IF geometry.size.height>0 THEN { CheckC16[geometry.size.height]; vals[filled] ¬ geometry.size.height; filled ¬ filled + 1; bitmask ¬ bitmask+8; }; IF geometry.borderWidth>=0 THEN { CheckC16[geometry.borderWidth]; vals[filled] ¬ geometry.borderWidth; filled ¬ filled + 1; bitmask ¬ bitmask+010H; }; IF sibling#nullWindow THEN { vals[filled] ¬ WindowId[sibling]; filled ¬ filled + 1; bitmask ¬ bitmask+020H; }; IF stackMode#dontChange THEN { vals[filled] ¬ ORD[stackMode]; filled ¬ filled + 1; bitmask ¬ bitmask+040H; }; IF filled#0 THEN DoWithLocks[c, action, details]; }; NewWindow: PROC [c: Connection] RETURNS [w: Window] = { id: CARD32 ¬ XlPrivateResources.NewResourceID[c]; w ¬ ToWindow[c, id]; XlDispatch.InitWindow[c, w]; }; CreateWindow: PUBLIC PROC [c: Connection, matchList: MatchList, parent: Window ¬ nullWindow, geometry: Geometry, class: WindowClass ¬ copyFromParent, visual: Visual ¬ nullVisual, depth: INTEGER ¬ -1, attributes: Attributes, details: Details] RETURNS [w: Window ¬ nullWindow] ~ { action: PROC [c: Connection] ~ { mask, cnt: CARD32; w ¬ NewWindow[c]; IF matchList#NIL THEN attributes.eventMask.structureNotify ¬ TRUE; TRUSTED { [mask, cnt] ¬ MakeMask[@attributes] }; FOR l: MatchList ¬ matchList, l.rest WHILE l#NIL DO XlDispatch.InternalAddMatch[c, w, l.first, attributes.eventMask]; ENDLOOP; IF depth<0 OR depth>255 THEN depth ¬ 0; BInit[c, 1, depth, cnt+8]; BPutDrawable[c, w]; -- id for the new window BPutDrawable[c, parent]; -- parent window BPutPoint[c, geometry.pos]; BPutSize[c, geometry.size]; BPutINT32as16[c, geometry.borderWidth]; BPut16[c, ORD[class]]; BPutVisual[c, visual]; BPut32[c, mask]; TRUSTED {BPutAttributes[c, @attributes]}; FinishWithDetails[c, details]; }; IF geometry.borderWidth<0 OR geometry.borderWidth>1000 THEN geometry.borderWidth ¬ 0; IF parent=nullWindow THEN parent ¬ DefaultRoot[c]; --first screen IF geometry.size.width<=0 THEN geometry.size.width ¬ 200; IF geometry.size.height<=0 THEN geometry.size.height ¬ 50; DoWithLocks[c, action, details]; }; BPutSetOfEvent: PUBLIC <> PROC [c: Connection, s: SetOfEvent] = { s.reservedforDisableEvents ¬ FALSE; XlPrivate.IBPut32[c, LOOPHOLE[s]]; }; BPutAttributes: PROC [c: Connection, p: LONG POINTER TO Attributes] = TRUSTED { IF ~IllegalPixmap[p.backgroundPixmap] THEN BPutPixmap[c, p.backgroundPixmap]; IF p.backgroundPixel#illegalPixel THEN BPut32[c, p.backgroundPixel]; IF ~IllegalPixmap[p.borderPixmap] THEN BPutPixmap[c, p.borderPixmap]; IF p.borderPixel#illegalPixel THEN BPut32[c, p.borderPixel]; IF p.bitGravity#illegal THEN BPut32[c, ORD[p.bitGravity]]; IF p.winGravity#illegal THEN BPut32[c, ORD[p.winGravity]]; IF p.backingStore#illegal THEN BPut32[c, ORD[p.backingStore]]; IF p.backingPlanes#undefinedBackingPlanes THEN BPut32[c, ORD[p.backingPlanes]]; IF p.backingPixel#illegalPixel THEN BPut32[c, p.backingPixel]; IF p.overrideRedirect#illegal THEN BPut32[c, ORD[p.overrideRedirect]]; IF p.saveUnder#illegal THEN BPut32[c, ORD[p.saveUnder]]; IF ~UnspecifiedEvents[p.eventMask] THEN BPutSetOfEvent[c, p.eventMask]; IF ~UnspecifiedEvents[p.doNotPropagateMask] THEN BPutSetOfEvent[c, p.doNotPropagateMask]; IF ~IllegalColorMap[p.colorMap] THEN BPutColorMap[c, p.colorMap]; IF ~IllegalCursor[p.cursor] THEN BPutCursor[c, p.cursor]; }; MakeMask: PROC [p: LONG POINTER TO Attributes] RETURNS [m, c: CARD32¬0] = TRUSTED { IF ~IllegalPixmap[p.backgroundPixmap] THEN {m ¬ m + 01H; c ¬ c + 1}; IF p.backgroundPixel#illegalPixel THEN {m ¬ m + 02H; c ¬ c + 1}; IF ~IllegalPixmap[p.borderPixmap] THEN {m ¬ m + 04H; c ¬ c + 1}; IF p.borderPixel#illegalPixel THEN {m ¬ m + 08H; c ¬ c + 1}; IF p.bitGravity#illegal THEN {m ¬ m + 010H; c ¬ c + 1}; IF p.winGravity#illegal THEN {m ¬ m + 020H; c ¬ c + 1}; IF p.backingStore#illegal THEN {m ¬ m + 040H; c ¬ c + 1}; IF p.backingPlanes#undefinedBackingPlanes THEN {m ¬ m + 080H; c ¬ c + 1}; IF p.backingPixel#illegalPixel THEN {m ¬ m + 0100H; c ¬ c + 1}; IF p.overrideRedirect#illegal THEN {m ¬ m + 0200H; c ¬ c + 1}; IF p.saveUnder#illegal THEN {m ¬ m + 0400H; c ¬ c + 1}; IF ~UnspecifiedEvents[p.eventMask] THEN {m ¬ m + 0800H; c ¬ c + 1}; IF ~UnspecifiedEvents[p.doNotPropagateMask] THEN {m ¬ m + 01000H; c ¬ c + 1}; IF ~IllegalColorMap[p.colorMap] THEN {m ¬ m + 02000H; c ¬ c + 1}; IF ~IllegalCursor[p.cursor] THEN {m ¬ m + 04000H; c ¬ c + 1}; }; CreatePixmap: PUBLIC PROC [c: Connection, drawable: Drawable ¬ nullDrawable, size: Size, depth: BYTE, details: Details] RETURNS [p: Pixmap ¬ nullPixmap] ~ { NewPixmap: PROC [c: Connection, id: CARD32] RETURNS [p: Pixmap] = { p ¬ ToPixmap[c, id] }; action: PROC [c: Connection] = { id: ID ¬ XlPrivateResources.NewResourceID[c]; p ¬ NewPixmap[c, id]; BInit[c, 53, depth, 4]; BPutPixmap[c, p]; -- id for the new pixmap BPutDrawable[c, drawable]; BPutSize[c, size]; FinishWithDetails[c, details] }; DoWithLocks[c, action, details]; }; FreePixmap: PUBLIC ENTRY PROC [c: Connection, pixmap: Pixmap, details: Details] = { err: ErrorNotifyEvent; BInit[c, 54, 0, 2]; BPutPixmap[c, pixmap]; err ¬ XlPrivate.FinishWithDetailsNoErrors[c, details]; IF err#NIL THEN RETURN WITH ERROR XError[err]; }; white: PUBLIC REF READONLY RGBRec ¬ NEW[RGBRec ¬ [65535, 65535, 65535]]; black: PUBLIC REF READONLY RGBRec ¬ NEW[RGBRec ¬ [0, 0, 0]]; CreateColorMap: PUBLIC PROC [c: Connection, visual: Visual, window: Window, allocAll: BOOL ¬ FALSE, details: Details] RETURNS [colorMap: ColorMap ¬ nullColorMap] = { action: PROC [c: Connection] = { colorMap ¬ [XlPrivateResources.NewResourceID[c]]; BInit[c, 78, IF allocAll THEN 1 ELSE 0, 4]; BPutColorMap[c, colorMap]; BPutDrawable[c, window]; BPutVisual[c, visual]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; FreeColorMap: PUBLIC PROC [c: Connection, colorMap: ColorMap, details: Details] = { action: PROC [c: Connection] = { BInit[c, 79, 0, 2]; BPutColorMap[c, colorMap]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; CopyColorMapAndFree: PUBLIC PROC [c: Connection, free: ColorMap, details: Details] RETURNS [colorMap: ColorMap ¬ nullColorMap] = { action: PROC [c: Connection] = { colorMap ¬ [XlPrivateResources.NewResourceID[c]]; BInit[c, 80, 0, 3]; BPutColorMap[c, colorMap]; BPutColorMap[c, free]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; InstallColorMap: PUBLIC PROC [c: Connection, colorMap: ColorMap, details: Details] = { action: PROC [c: Connection] = { BInit[c, 81, 0, 2]; BPutColorMap[c, colorMap]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; UnInstallColorMap: PUBLIC PROC [c: Connection, colorMap: ColorMap, details: Details] = { action: PROC [c: Connection] = { BInit[c, 82, 0, 2]; BPutColorMap[c, colorMap]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; ListInstalledColorMaps: PUBLIC PROC [c: Connection, window: Window] RETURNS [REF READONLY ColorMaps] = { reply: Reply; leng: CARD; maps: REF ColorMaps; action: PROC [c: Connection] = { BInit[c, 83, 0, 2]; BPutDrawable[c, window]; reply ¬ FinishWithReply[c]; }; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; leng ¬ ERead16[reply]; maps ¬ NEW[ColorMaps[leng]]; Skip[reply, 22]; FOR i: CARD IN [0..leng) DO maps[i] ¬ [ERead32[reply]]; ENDLOOP; DisposeReply[c, reply]; RETURN [maps]; }; AllocColor: PUBLIC PROC [c: Connection, colorMap: ColorMap, color: RGBRec] RETURNS [pixel: Pixel, usedColor: RGBRec] = { action: PROC [c: Connection] = { BInit[c, 84, 0, 4]; BPutColorMap[c, colorMap]; BPutRGBRec[c, color]; BPut16[c, 0]; reply ¬ FinishWithReply[c]; }; reply: Reply; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; usedColor.red ¬ ERead16[reply]; usedColor.green ¬ ERead16[reply]; usedColor.blue ¬ ERead16[reply]; Skip[reply, 2]; pixel ¬ ERead32[reply]; DisposeReply[c, reply]; }; AllocNamedColor: PUBLIC PROC [c: Connection, colorMap: ColorMap, name: ROPE] RETURNS [pixel: Pixel, exactColor, usedColor: RGBRec] = { action: PROC [c: Connection] = { BInit[c, 85, 0, 3+(leng+3)/4]; BPutColorMap[c, colorMap]; BPut16[c, leng]; BPut16[c, 0]; BPutPaddedRope[c, name]; reply ¬ FinishWithReply[c]; }; reply: Reply; leng: INT ¬ Rope.Length[name]; IF leng>c.info.maxRequestLengthBytes THEN ERROR; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; pixel ¬ ERead32[reply]; exactColor.red ¬ ERead16[reply]; exactColor.green ¬ ERead16[reply]; exactColor.blue ¬ ERead16[reply]; usedColor.red ¬ ERead16[reply]; usedColor.green ¬ ERead16[reply]; usedColor.blue ¬ ERead16[reply]; DisposeReply[c, reply]; }; AllocColorCells: PUBLIC PROC [c: Connection, colorMap: ColorMap, colors, planes: CARD16, contiguos: BOOL¬FALSE] RETURNS [pixels: REF Card32Sequence, masks: REF Card32Sequence] = { action: PROC [c: Connection] = { BInit[c, 86, ToCBool[contiguos], 3]; BPutColorMap[c, colorMap]; BPut16[c, colors]; BPut16[c, planes]; reply ¬ FinishWithReply[c]; }; reply: Reply; n, m: CARD16; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; n ¬ ERead16[reply]; m ¬ ERead16[reply]; Skip[reply, 20]; pixels ¬ NEW[Card32Sequence[n]]; FOR i: INT IN [0..n) DO pixels[i] ¬ ERead32[reply]; ENDLOOP; masks ¬ NEW[Card32Sequence[m]]; FOR i: INT IN [0..m) DO masks[i] ¬ ERead32[reply]; ENDLOOP; DisposeReply[c, reply]; }; AllocColorPlanes: PUBLIC PROC [c: Connection, colorMap: ColorMap, colors, reds, greens, blues: CARD16, contiguos: BOOL¬FALSE] RETURNS [pixels: REF Card32Sequence, redMask, greenMask, blueMask: CARD32] = { action: PROC [c: Connection] = { BInit[c, 87, ToCBool[contiguos], 4]; BPutColorMap[c, colorMap]; BPut16[c, colors]; BPut16[c, reds]; BPut16[c, greens]; BPut16[c, blues]; reply ¬ FinishWithReply[c]; }; reply: Reply; n: CARD16; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; n ¬ ERead16[reply]; Skip[reply, 2]; redMask ¬ ERead32[reply]; greenMask ¬ ERead32[reply]; blueMask ¬ ERead32[reply]; Skip[reply, 8]; pixels ¬ NEW[Card32Sequence[n]]; FOR i: INT IN [0..n) DO pixels[i] ¬ ERead32[reply]; ENDLOOP; DisposeReply[c, reply]; }; FreeColors: PUBLIC PROC [c: Connection, colorMap: ColorMap, pixels: LIST OF CARD32, planeMask: CARD32, details: Details] ~ { action: PROC [c: Connection] ~ { BInit[c, 88, 0, 3+cnt]; BPutColorMap[c, colorMap]; BPut32[c, planeMask]; FOR i: INT IN [0..cnt) DO BPut32[c, pl.first]; IF pl#NIL THEN pl ¬ pl.rest ENDLOOP; FinishWithDetails[c, details]; }; cnt: INT ¬ 0; pl: LIST OF CARD32 ¬ NIL; --no infinite loops... FOR l: LIST OF CARD32 ¬ pixels, l.rest WHILE l#NIL DO pl ¬ CONS[l.first, pl]; cnt ¬ cnt+1; IF cnt>c.info.maxRequestLength THEN ERROR; ENDLOOP; DoWithLocks[c, action, details]; }; StoreColors: PUBLIC PROC [c: Connection, colorMap: ColorMap, items: LIST OF ColorItem, details: Details] ~ { action: PROC [c: Connection] ~ { BInit[c, 89, 0, 2+3*cnt]; BPutColorMap[c, colorMap]; FOR i: INT IN [0..cnt) DO used: BYTE ¬ 0; IF pl.first.doRed THEN used ¬ used+1; IF pl.first.doGreen THEN used ¬ used+2; IF pl.first.doBlue THEN used ¬ used+4; BPut32[c, pl.first.pixel]; BPutRGBRec[c, pl.first.rgb]; BPut8[c, used]; BPut8[c, 0]; pl ¬ pl.rest ENDLOOP; FinishWithDetails[c, details]; }; cnt: INT ¬ 0; pl: LIST OF ColorItem ¬ NIL; --no infinite loops... FOR l: LIST OF ColorItem ¬ items, l.rest WHILE l#NIL DO pl ¬ CONS[l.first, pl]; cnt ¬ cnt+1; IF cnt>c.info.maxRequestLength THEN ERROR; ENDLOOP; DoWithLocks[c, action, details]; }; StoreNamedColor: PUBLIC PROC [c: Connection, colorMap: ColorMap, pixel: Pixel, name: ROPE, doRed, doGreen, doBlue: BOOL, details: Details] ~ { len: INT ¬ Rope.Length[name]; used: BYTE ¬ 0; action: PROC [c: Connection] = { BInit[c, 90, used, 4+(len+3)/4]; BPutColorMap[c, colorMap]; BPut32[c, pixel]; BPut16[c, len]; BPut16[c, 0]; BPutPaddedRope[c, name]; FinishWithDetails[c, details]; }; IF len>=c.info.maxRequestLengthBytes THEN XlPrivateErrorHandling.RaiseClientError[c, $toolong]; IF doRed THEN used ¬ used+1; IF doGreen THEN used ¬ used+2; IF doBlue THEN used ¬ used+4; DoWithLocks[c, action, details]; }; QueryColors: PUBLIC PROC [c: Connection, colorMap: ColorMap, pixels: LIST OF CARD32] RETURNS [rgbl: LIST OF RGBRec ¬ NIL] = { action: PROC [c: Connection] = { BInit[c, 91, 0, 2+cnt]; BPutColorMap[c, colorMap]; FOR i: INT IN [0..cnt) DO IBPut32[c, pl.first]; IF pl#NIL THEN pl ¬ pl.rest; ENDLOOP; reply ¬ FinishWithReply[c]; }; n: CARD16; reply: Reply; cnt: INT ¬ 0; pl: LIST OF Pixel ¬ NIL; FOR l: LIST OF Pixel ¬ pixels, l.rest WHILE l#NIL DO pl ¬ CONS[l.first, pl]; cnt ¬ cnt+1; IF cnt>c.info.maxRequestLength THEN ERROR; ENDLOOP; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; n ¬ ERead16[reply]; Skip[reply, 22]; FOR i: INT IN [0..n) DO rgb: RGBRec; rgb.red ¬ ERead16[reply]; rgb.green ¬ ERead16[reply]; rgb.blue ¬ ERead16[reply]; [] ¬ ERead16[reply]; rgbl ¬ CONS[rgb, rgbl]; ENDLOOP; DisposeReply[c, reply]; }; LookupColor: PUBLIC PROC [c: Connection, colorMap: ColorMap, name: ROPE] RETURNS [exact, used: RGBRec] = { reply: Reply; action: PROC [c: Connection] = { BInit[c, 92, 0, 3+(leng+3)/4]; BPutColorMap[c, colorMap]; BPut16[c, leng]; BPut16[c, 0]; BPutPaddedRope[c, name]; reply ¬ FinishWithReply[c]; }; leng: INT ¬ Rope.Length[name]; IF leng >= c.info.maxRequestLengthBytes THEN ERROR; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; exact.red ¬ ERead16[reply]; exact.green ¬ ERead16[reply]; exact.blue ¬ ERead16[reply]; used.red ¬ ERead16[reply]; used.green ¬ ERead16[reply]; used.blue ¬ ERead16[reply]; DisposeReply[c, reply]; }; BPutRGB: --INTERNAL-- PROC [c: Connection, rgb: REF READONLY RGBRec] = { IF rgb=NIL THEN rgb ¬ black; BPutRGBRec[c, rgb­]; }; BPutRGBRec: --INTERNAL-- PROC [c: Connection, rgb: RGBRec] = { IBPut16[c, rgb.red]; IBPut16[c, rgb.green]; IBPut16[c, rgb.blue]; }; NewCursor: PROC [c: Connection, id: CARD32] RETURNS [Cursor] = { XlPrivateResources.Attach[c, id, $mutableCursor]; RETURN [ [id] ]; }; CreateCursor: PUBLIC PROC [c: Connection, source: Pixmap, mask: Pixmap ¬ nullPixmap, hotP: Point, foreground: REF READONLY RGBRec ¬ black, background: REF READONLY RGBRec ¬ white, details: Details] RETURNS [cursor: Cursor ¬ nullCursor] = { action: PROC [c: Connection] = { cursor ¬ NewCursor[c, XlPrivateResources.NewResourceID[c]]; BInit[c, 93, 0, 8]; BPutCursor[c, cursor]; BPutPixmap[c, source]; BPutPixmap[c, mask]; BPutRGB[c, IF foreground=NIL THEN black ELSE foreground]; BPutRGB[c, IF background=NIL THEN white ELSE background]; BPutPoint[c, hotP]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; CreateGlyphCursor: PUBLIC PROC [c: Connection, sourceFont: Font, maskFont: Font ¬ nullFont, sourceChar: CARD16, maskChar: CARD16, foreground: REF READONLY RGBRec ¬ black, background: REF READONLY RGBRec ¬ white, details: Details] RETURNS [cursor: Cursor ¬ nullCursor] = { sourceFontId, maskFontId: ID; action: PROC [c: Connection] = { cursor ¬ NewCursor[c, XlPrivateResources.NewResourceID[c]]; BInit[c, 94, 0, 8]; BPutCursor[c, cursor]; BPut32[c, sourceFontId]; BPut32[c, maskFontId]; BPut16[c, sourceChar]; BPut16[c, maskChar]; BPutRGB[c, IF foreground=NIL THEN black ELSE foreground]; BPutRGB[c, IF background=NIL THEN white ELSE background]; FinishWithDetails[c, details]; }; IF sourceFont=NIL THEN XlPrivateErrorHandling.RaiseClientError[c, $font]; sourceFontId ¬ Xl.FontId[sourceFont]; maskFontId ¬ IF maskFont=NIL THEN nullID ELSE Xl.FontId[maskFont]; DoWithLocks[c, action, details]; }; ReColorCursor: PUBLIC PROC [c: Connection, cursor: Cursor, foreground: REF READONLY RGBRec ¬ black, background: REF READONLY RGBRec ¬ white, details: Details] = { action: PROC [c: Connection] = { BInit[c, 96, 0, 5]; BPutCursor[c, cursor]; BPutRGB[c, IF foreground=NIL THEN black ELSE foreground]; BPutRGB[c, IF background=NIL THEN white ELSE background]; FinishWithDetails[c, details]; }; IF XlPrivateResources.Fetch[c, cursor]#$mutableCursor THEN ERROR; --I do not believe in recoloring cursors owned by different applications is worthwhile... However, if somebody needs that operation I will remove the test as the possible dammage is really quite limited. DoWithLocks[c, action, details]; }; FreeCursor: PUBLIC PROC [c: Connection, cursor: Cursor, details: Details] = { action: PROC [c: Connection] = { BInit[c, 95, 0, 2]; BPutCursor[c, cursor]; FinishWithDetails[c, details]; XlPrivateResources.InternalFreeResourceID[c, cursor]; }; IF XlPrivateResources.Fetch[c, cursor]#$mutableCursor THEN ERROR; --I do not believe freeing cursors owned by different applications is worthwhile allowing... XlPrivateResources.Detach[c, cursor]; DoWithLocks[c, action, details]; }; BPutPointerEvents: PROC [c: Connection, ev: SetOfPointerEvent] = { events: CARD32 ~ LOOPHOLE[PointerEvents[ev]]; BPutINT32as16[c, LOOPHOLE[events]]; }; Grabber: TYPE = REF GrabberRec; <>GrabberRec: PUBLIC TYPE = RECORD [ identity: REF BasicTime.GMT, waiters: CONDITION ¬ [], isGrabbed: BOOL ¬ FALSE, didTimeOut: BOOL ¬ FALSE, timeout: INT ¬ 6, timeStamp: TimeStamp ¬ currentTime, unGrabber: InternalUngrabProcType ]; flushNowDetails: Details ¬ NEW[DetailsRec ¬ [flush: now]]; InternalUngrabProcType: TYPE = --INTERNAL-- PROC [c: Connection, timeStamp: TimeStamp, details: Details <>]; StartTimer: INTERNAL PROC [c: Connection, grabber: Grabber] = { IF grabber#NIL THEN { grabber.identity ¬ NEW[BasicTime.GMT ¬ BasicTime.Now[]]; grabber.isGrabbed ¬ TRUE; grabber.didTimeOut ¬ FALSE; NOTIFY grabber.waiters; --get rid of old processes [performance hack] TRUSTED {Process.Detach[FORK TimerProcess[c, grabber, grabber.identity]]}; }; }; TimerProcess: ENTRY PROC [c: Connection, grabber: Grabber, grabIdentity: REF BasicTime.GMT] = { ENABLE UNWIND => NULL; DO WAIT grabber.waiters; IF ~c.alive THEN RETURN; --connection is no more alive IF ~grabber.isGrabbed THEN RETURN; --server is no more grabbed IF grabber.identity#grabIdentity THEN RETURN; --server is grabbed by different client IF BasicTime.Period[from: grabIdentity­, to: BasicTime.Now[]]>1 THEN { IF InternalSomeImportantDown[c] THEN grabIdentity­ ¬ BasicTime.Now[] --key down; restart timer ELSE { IF BasicTime.Period[from: grabIdentity­, to: BasicTime.Now[]]>grabber.timeout THEN { grabber.unGrabber[c, grabber.timeStamp, flushNowDetails]; grabber.didTimeOut ¬ TRUE; BROADCAST grabber.waiters; RETURN; } } }; ENDLOOP; }; GrabPointer: PUBLIC PROC [c: Connection, window: Window, ownerEvents: BOOL, eventMask: SetOfPointerEvent, pointerMode: Synchronicity, keyboardMode: Synchronicity, confine: Window, cursor: Cursor, timeStamp: TimeStamp ¬ currentTime] RETURNS [status: GrabStatus ¬ success] = { action: INTERNAL PROC [c: Connection] = { reply: Reply; BInit[c, 26, ToCBool[ownerEvents], 6]; BPutDrawable[c, window]; BPutPointerEvents[c, eventMask]; BPut8[c, ORD[pointerMode]]; BPut8[c, ORD[keyboardMode]]; BPutDrawable[c, confine]; BPutCursor[c, cursor]; BPutTime[c, timeStamp]; reply ¬ FinishWithReply[c]; status ¬ VAL[Get8[reply, 1]]; IF status=success THEN { cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; IF cPriv.pointerGrabber=NIL THEN { cPriv.pointerGrabber ¬ NEW[GrabberRec]; cPriv.pointerGrabber.unGrabber ¬ InternalUngrabPointer; TRUSTED {Process.InitializeCondition[@cPriv.pointerGrabber.waiters, 1]}; }; StartTimer[c, cPriv.pointerGrabber]; }; }; DoWithLocks[c, action, NIL]; }; InternalUngrabPointer: --INTERNAL-- PROC [c: Connection, timeStamp: TimeStamp, details: Details] = { BInit[c, 27, 0, 2]; BPutTime[c, timeStamp]; FinishWithDetails[c, details]; IF details=NIL THEN [] ¬ XlPrivate.HardFlushBuffer[c]; }; UngrabPointer: PUBLIC PROC [c: Connection, timeStamp: TimeStamp, details: Details] = { action: PROC [c: Connection] = {InternalUngrabPointer[c, timeStamp, details]}; DoWithLocks[c, action, details]; }; ChangeActivePointerGrab: PUBLIC PROC [c: Connection, eventMask: SetOfPointerEvent, cursor: Cursor ¬ [0], timeStamp: TimeStamp ¬ currentTime, details: Details ¬ NIL] = { action: PROC [c: Connection] = { BInit[c, 30, 0, 4]; BPutCursor[c, cursor]; BPutTime[c, timeStamp]; BPutPointerEvents[c, eventMask]; BSkip[c, 2]; FinishWithDetails[c, details]; IF details=NIL THEN XlPrivate.HardFlushBuffer[c]; }; DoWithLocks[c, action, details]; }; GrabButton: PUBLIC PROC [c: Connection, grabWindow: Window, confineWindow: Window ¬ nullWindow, modifiers: SetOfKeyButMask, button: BYTE ¬ 0, ownerEvents: BOOL, eventMask: SetOfPointerEvent, pointerMode: Synchronicity, keyboardMode: Synchronicity, cursor: Cursor ¬ [0], details: Details] = { action: PROC [c: Connection] = { BInit[c, 28, ToCBool[ownerEvents], 6]; BPutDrawable[c, grabWindow]; BPutPointerEvents[c, eventMask]; BPut8[c, ORD[pointerMode]]; BPut8[c, ORD[keyboardMode]]; BPutDrawable[c, confineWindow]; BPutCursor[c, cursor]; BPut8[c, button]; BPut8[c, 0]; BPut16[c, XlKeyButPrivate.SetToWire[modifiers]]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; UngrabButton: PUBLIC PROC [c: Connection, window: Window, modifiers: SetOfKeyButMask, button: BYTE ¬ 0, details: Details] = { action: PROC [c: Connection] = { BInit[c, 29, button, 3]; BPutDrawable[c, window]; BPut16[c, XlKeyButPrivate.SetToWire[modifiers]]; BSkip[c, 0]; FinishWithDetails[c, details]; IF details=NIL THEN XlPrivate.HardFlushBuffer[c, TRUE]; }; DoWithLocks[c, action, details]; }; keyboardGrabCheck: ROPE = "_Cedar_KeyboardGrabCheck"; keyboardGrab: REF ¬ NEW[INT]; propertyEvents: EventFilter = CreateEventFilter[propertyNotify]; KeyboardUnWedgeProc: EventProcType = { WITH event SELECT FROM pne: PropertyNotifyEvent => { cPriv: REF ConnectionPrivateImplRec ~ event.connection.cPriv; IF pne.atom#cPriv.keyboardGrabAtom THEN RETURN; --safety IF pne.atom.a=0 THEN RETURN; --safety IF FirstRoot[event.connection]#pne.window THEN RETURN; --safety IF pne.state=deleted THEN { PutConnectionProp[event.connection, keyboardGrab, NIL]; --propagate notify waiting guy RETURN; --essential }; IF cPriv.keyboardGrabbed THEN { UngrabKeyboard[event.connection, currentTime]; DeleteProperty[event.connection, pne.window, pne.atom]; --notify waiting guy Flush[event.connection]; }; }; ENDCASE => {}; }; InstallKeyboardUnWedger: PROC [c: Connection] = { cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; IF cPriv.keyboardGrabAtom.a=0 THEN { a: XAtom ¬ MakeAtom[c, keyboardGrabCheck]; cPriv.keyboardGrabAtom ¬ a; AddDispatch[c, FirstRoot[c], NEW[MatchRep ¬ [proc: KeyboardUnWedgeProc, handles: propertyEvents, tq: CreateTQ[$keyboardUnWedger]]]]; }; }; GrabKeyboard: PUBLIC PROC [c: Connection, grabWindow: Window, ownerEvents: BOOL, pointerMode: Synchronicity, keyboardMode: Synchronicity, time: TimeStamp] RETURNS [status: GrabStatus ¬ success] = { action: PROC [c: Connection] = { cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; reply: Reply; BInit[c, 31, ToCBool[ownerEvents], 4]; BPutDrawable[c, grabWindow]; BPutTime[c, time]; BPut8[c, ORD[pointerMode]]; BPut8[c, ORD[keyboardMode]]; BPut16[c, 0]; reply ¬ FinishWithReply[c]; status ¬ VAL[Get8[reply, 1]]; IF status=success THEN { cPriv.keyboardGrabbed ¬ TRUE; XlService.PutServiceProp[c, keyboardGrab, c] }; }; InstallKeyboardUnWedger[c]; DoWithLocks[c, action, NIL]; }; UngrabKeyboard: PUBLIC PROC [c: Connection, time: TimeStamp, details: Details ¬ NIL] = { action: PROC [c: Connection] = { cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; BInit[c, 32, 0, 2]; BPutTime[c, time]; FinishWithDetails[c, details]; IF time=currentTime THEN { cPriv.keyboardGrabbed ¬ FALSE; XlService.PutServiceProp[c, keyboardGrab, NIL]; }; }; DoWithLocks[c, action, details]; }; ForcedUngrabKeyboard: PUBLIC PROC [c: Connection] = { time: BasicTime.GMT ¬ BasicTime.Now[]; cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; InstallKeyboardUnWedger[c]; ChangeProperty[c: c, w: FirstRoot[c], property: cPriv.keyboardGrabAtom, type: cPriv.keyboardGrabAtom, mode: replace, data: keyboardGrabCheck]; Flush[c]; WHILE GetConnectionProp[c, keyboardGrab]#NIL DO IF BasicTime.Period[from: time, to: BasicTime.Now[]]>5 THEN RETURN; Process.PauseMsec[100]; ENDLOOP; }; GrabKey: PUBLIC PROC [c: Connection, grabWindow: Window, modifiers: SetOfKeyButMask, key: KeyCode, ownerEvents: BOOL, pointerMode: Synchronicity, keyboardMode: Synchronicity, details: Details] = { action: PROC [c: Connection] = { BInit[c, 33, ToCBool[ownerEvents], 4]; BPutDrawable[c, grabWindow]; BPut16[c, XlKeyButPrivate.SetToWire[modifiers]]; BPut8[c, ORD[key]]; BPut8[c, ORD[pointerMode]]; BPut8[c, ORD[keyboardMode]]; BSkip[c, 3]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; UngrabKey: PUBLIC PROC [c: Connection, window: Window, modifiers: SetOfKeyButMask, key: KeyCode, details: Details] = { action: PROC [c: Connection] = { BInit[c, 34, ORD[key], 3]; BPutDrawable[c, window]; BPut16[c, XlKeyButPrivate.SetToWire[modifiers]]; BSkip[c, 2]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; AllowEvents: PUBLIC PROC [c: Connection, mode: AllowEventsMode, time: TimeStamp, details: Details] = { action: PROC [c: Connection] = { BInit[c, 35, ORD[mode], 2]; BPutTime[c, time]; FinishWithDetails[c, details]; IF details=NIL THEN [] ¬ XlPrivate.HardFlushBuffer[c]; }; DoWithLocks[c, action, details]; }; AddDispatch: PUBLIC PROC [c: Connection, window: Window, match: Match, generate: SetOfEvent ¬ unspecifiedEvents, details: Details ¬ NIL] = { XlDispatch.AddMatch[c, window, match, generate, details]; }; AddDispatchJunk: PUBLIC PROC [c: Connection, match: Match] = { XlDispatch.AddMatchForUnregistered[c, match] }; ClearArea: PUBLIC PROC [c: Connection, window: Window, pos: Point, size: Size, exposures: BOOL, details: Details] ~ { action: PROC [c: Connection] = { BInit[c, 61, ToCBool[exposures], 4]; BPutDrawable[c, window]; BPutRect[c, pos, size]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; InternalSomeImportantDown: INTERNAL PROC [c: Connection] RETURNS [down: BOOL] = { reply: Reply ¬ InternalQueryPointer[c, nullWindow]; down ¬ Get8[reply, 24]#0 OR Get8[reply, 25]#0; DisposeReply[c, reply]; }; InternalQueryPointer: --INTERNAL-- PROC [c: Connection, window: Window] RETURNS [reply: Reply] = { BInit[c, 38, 0, 2]; IF window=nullWindow THEN window ¬ DefaultRoot[c]; BPutDrawable[c, window]; reply ¬ FinishWithReply[c]; }; QueryPointer: PUBLIC PROC [c: Connection, window: Window ¬ nullWindow] RETURNS [qr: PointerReply] = { reply: Reply; action: PROC [c: Connection] = {reply ¬ InternalQueryPointer[c, window]}; DoWithLocks[c, action, NIL]; CheckReply[reply]; qr.sameScreen ¬ ERead8[reply]#0; Skip[reply, 6]; qr.root ¬ ToWindow[c, ERead32[reply]]; qr.child ¬ ToWindow[c, ERead32[reply]]; qr.rootP.x ¬ ERead16[reply]; qr.rootP.y ¬ ERead16[reply]; qr.pos.x ¬ ERead16[reply]; qr.pos.y ¬ ERead16[reply]; qr.mask ¬ [ERead16[reply]]; DisposeReply[c, reply]; }; WarpPointer: PUBLIC PROC [c: Connection, dstWindow: Window, dstPos: Point, srcWindow: Window, srcPos: Point, srcSize: Size, details: Details] = { action: PROC [c: Connection] = { BInit[c, 41, 0, 6]; BPutDrawable[c, srcWindow]; BPutDrawable[c, dstWindow]; BPutPoint[c, srcPos]; BPutSize[c, srcSize]; BPutPoint[c, dstPos]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; GetMotionEvents: PUBLIC PROC [c: Connection, window: Window, start, stop: TimeStamp] RETURNS [tc: REF TimeCoords ¬ NIL] = { action: PROC [c: Connection] = { BInit[c, 39, 0, 4]; BPutDrawable[c, window]; BPutTime[c, start]; BPutTime[c, stop]; reply ¬ FinishWithReply[c]; }; reply: Reply; tcLeng: CARD; replyExtLeng: CARD; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 3]; replyExtLeng ¬ ERead32[reply]; tcLeng ¬ ERead32[reply]; Skip[reply, 20]; IF (tcLeng > c.info.motionBufferSize) OR (tcLeng*2 > replyExtLeng) THEN { XlPrivateErrorHandling.RaiseServerError[c, $GetMotionEvents, reply]; tcLeng ¬ 0; }; tc ¬ NEW[TimeCoords[tcLeng]]; FOR i: CARD IN [0..tcLeng) DO tc[i].time ¬ [ERead32[reply]]; tc[i].p.x ¬ INT32[LOOPHOLE[ERead16[reply], INT16]]; tc[i].p.y ¬ INT32[LOOPHOLE[ERead16[reply], INT16]]; ENDLOOP; DisposeReply[c, reply]; }; QueryBestSize: PUBLIC PROC [c: Connection, class: BestSizeClass, drawable: Drawable, size: Size] RETURNS [best: Size] = { reply: Reply; action: PROC [c: Connection] = { BInit[c, 97, ORD[class], 3]; BPutDrawable[c, drawable]; BPutSize[c, size]; reply ¬ FinishWithReply[c]; }; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; best.width ¬ ERead16[reply]; best.height ¬ ERead16[reply]; DisposeReply[c, reply]; }; TranslateCoordinates: PUBLIC PROC [c: Connection, srcWindow, dstWindow: Window, srcPos: Point] RETURNS [trans: TranslateRec] = { reply: Reply; action: PROC [c: Connection] = { BInit[c, 40, 0, 4]; BPutDrawable[c, srcWindow]; BPutDrawable[c, dstWindow]; BPutPoint[c, srcPos]; reply ¬ FinishWithReply[c]; }; DoWithLocks[c, action, NIL]; CheckReply[reply]; trans.sameScreen ¬ ERead8[reply]#0; Skip[reply, 6]; trans.child ¬ ToWindow[c, ERead32[reply]]; trans.pos.x ¬ LONG[LOOPHOLE[ERead16[reply], INT16]]; trans.pos.y ¬ LONG[LOOPHOLE[ERead16[reply], INT16]]; DisposeReply[c, reply]; }; InternalUngrabServer: --INTERNAL-- PROC [c: Connection, timeStamp: TimeStamp, details: Details] = { BInit[c, 37, 0, 1]; FinishWithDetails[c, details]; IF details=NIL THEN [] ¬ XlPrivate.HardFlushBuffer[c]; }; UngrabServer: PUBLIC PROC [c: Connection, details: Details] = { action: PROC [c: Connection] ~ { cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; InternalUngrabServer[c, currentTime, details]; cPriv.serverGrabber.isGrabbed ¬ FALSE; }; DoWithLocks[c, action, details]; }; GrabServer: PUBLIC PROC [c: Connection, details: Details] = { cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; gr: REF GrabberRec ¬ cPriv.serverGrabber; action: INTERNAL PROC [c: Connection] ~ { cPriv: REF ConnectionPrivateImplRec ~ c.cPriv; IF cPriv.serverGrabber=NIL THEN TRUSTED { cPriv.serverGrabber ¬ NEW[GrabberRec]; cPriv.serverGrabber.unGrabber ¬ InternalUngrabServer; TRUSTED {Process.InitializeCondition[@cPriv.serverGrabber.waiters, 2]}; }; BInit[c, 36, 0, 1]; FinishWithDetails[c, details]; StartTimer[c, cPriv.serverGrabber]; }; IF gr#NIL AND gr.isGrabbed THEN XlPrivateErrorHandling.RaiseClientError[c, $GrabWhileGrabbed]; DoWithLocks[c, action, details]; }; GetGeometry: PUBLIC PROC [c: Connection, drawable: Drawable] RETURNS [g: GeometryRec] = { action: PROC [c: Connection] ~ { BInit[c, 14, 0, 2]; BPutDrawable[c, drawable]; reply ¬ FinishWithReply[c]; }; reply: Reply; DoWithLocks[c, action, NIL]; CheckReply[reply]; g.depth ¬ Read8[reply]; Skip[reply, 6]; g.root ¬ ToWindow[c, ERead32[reply]]; g.geometry.pos.x ¬ ERead16[reply]; g.geometry.pos.y ¬ ERead16[reply]; g.geometry.size.width ¬ ERead16[reply]; g.geometry.size.height ¬ ERead16[reply]; g.geometry.borderWidth ¬ ERead16[reply]; DisposeReply[c, reply]; }; QueryTree: PUBLIC PROC [c: Connection, window: Window] RETURNS [treeInfo: REF TreeInfoRec] = { action: PROC [c: Connection] ~ { BInit[c, 15, 0, 2]; BPutDrawable[c, window]; reply ¬ FinishWithReply[c]; }; reply: Reply; n: CARD16; root, parent: Window; DoWithLocks[c, action, NIL]; CheckReply[reply]; Skip[reply, 7]; root ¬ ToWindow[c, ERead32[reply]]; parent ¬ ToWindow[c, ERead32[reply]]; n ¬ ERead16[reply]; Skip[reply, 14]; treeInfo ¬ NEW[TreeInfoRec[n]]; treeInfo.root ¬ root; treeInfo.parent ¬ parent; FOR i: NAT IN [0..n) DO treeInfo.children[i] ¬ ToWindow[c, ERead32[reply]]; ENDLOOP; DisposeReply[c, reply]; }; CirculateWindow: PUBLIC PROC [c: Connection, window: Window, direction: CirculateDirection, details: Details] = { action: PROC [c: Connection] = { BInit[c, 13, ORD[direction], 2]; BPutDrawable[c, window]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; ReparentWindow: PUBLIC PROC [c: Connection, window: Window, newParent: Window, pos: Point, details: Details] = { action: PROC [c: Connection] = { BInit[c, 7, 0, 4]; BPutDrawable[c, window]; BPutDrawable[c, newParent]; BPutPoint[c, pos]; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; SendClientMessage32: PUBLIC PROC [c: Connection, destination: Window, propagate: BOOL, eventMask: SetOfEvent, window: Window, type: XAtom, data: ARRAY [0..5) OF CARD32, details: Details] = { action: PROC [c: Connection] = { BInit[c, 25, ToCBool[propagate], 11]; BPutDrawable[c, destination]; BPut32[c, LOOPHOLE[eventMask]]; BPut8[c, ORD[EventCode[clientMessage]]]; BPut8[c, 32]; BPut16[c, 0]; --sequence number BPutDrawable[c, window]; BPut32[c, type.a]; FOR i: [0..5) IN [0..5) DO BPut32[c, data[i]] ENDLOOP; FinishWithDetails[c, details]; }; DoWithLocks[c, action, details]; }; SendEvent: PUBLIC PROC [c: Connection, destination: Window, propagate: BOOL, eventMask: SetOfEvent, eventBody: EventRep, details: Details] = { action: PROC [c: Connection] = { BInit[c, 25, ToCBool[propagate], 11]; BPutDrawable[c, destination]; BPutSetOfEvent[c, eventMask]; BPut8[c, ORD[EventCode[eventBody.type]]]; TRUSTED { WITH ev: eventBody SELECT FROM keyPress, keyRelease => { BPut8[c, ORD[ev.keyCode]]; BSkip[c, 2]; --sequence number BPutTime[c, ev.timeStamp]; BPutDrawable[c, ev.root]; BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.child]; BPutPoint[c, ev.rootP]; BPutPoint[c, ev.pos]; BPut16[c, XlKeyButPrivate.SetToWire[ev.state]]; BPutBool[c, ev.sameScreen]; BPut8[c, 0]; --unused }; buttonPress, buttonRelease => { BPut8[c, ORD[ev.button]]; BSkip[c, 2]; --sequence number BPutTime[c, ev.timeStamp]; BPutDrawable[c, ev.root]; BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.child]; BPutPoint[c, ev.rootP]; BPutPoint[c, ev.pos]; BPut16[c, XlKeyButPrivate.SetToWire[ev.state]]; BPutBool[c, ev.sameScreen]; BPut8[c, 0]; --unused }; unmapNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.window]; BPutBool[c, ev.fromConfigure]; BSkip[c, 19]; }; motionNotify => { BPut8[c, ORD[ev.detail]]; BSkip[c, 2]; --sequence number BPutTime[c, ev.timeStamp]; BPutDrawable[c, ev.root]; BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.child]; BPutPoint[c, ev.rootP]; BPutPoint[c, ev.pos]; BPut16[c, XlKeyButPrivate.SetToWire[ev.state]]; BPutBool[c, ev.sameScreen]; BSkip[c, 1]; }; enterNotify, leaveNotify => { BPut8[c, ORD[ev.detail]]; BSkip[c, 2]; --sequence number BPutTime[c, ev.timeStamp]; BPutDrawable[c, ev.root]; BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.child]; BPutPoint[c, ev.rootP]; BPutPoint[c, ev.eventP]; BPut16[c, XlKeyButPrivate.SetToWire[ev.state]]; BPut8[c, ORD[ev.mode]]; BPut8[c, ORD[ev.sameScreen]*2+ORD[ev.focus]]; }; focusIn, focusOut => { BPut8[c, ORD[ev.detail]]; BSkip[c, 2]; --sequence number BPutDrawable[c, ev.eventWindow]; BPut8[c, ORD[ev.mode]]; BSkip[c, 23]; }; keymapNotify => { FOR i: [1..31] IN [1..31] DO BPut8[c, ev.keys[i]] ENDLOOP; }; expose => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.window]; BPutRect[c, ev.pos, ev.size]; --pos is INT16 instead of CARD16, happens to run fine BPut16[c, ev.count]; BSkip[c, 14]; }; graphicsExposure => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.drawable]; BPutRect[c, ev.pos, ev.size]; --pos is INT16 instead of CARD16, happens to run fine BPut16[c, ev.minorOpcode]; BPut16[c, ev.count]; BPut8[c, ev.majorOpcode]; BSkip[c, 11]; }; noExposure => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.drawable]; BPut16[c, ev.minorOpcode]; BPut8[c, ev.majorOpcode]; BSkip[c, 21]; }; visibilityNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.window]; BPut8[c, ORD[ev.state]]; BSkip[c, 23]; }; createNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.parent]; BPutDrawable[c, ev.window]; BPutRect[c, ev.geometry.pos, ev.geometry.size]; BPutINT32as16[c, ev.geometry.borderWidth]; BPutBool[c, ev.overrideRedirect]; BSkip[c, 9]; }; destroyNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.window]; BSkip[c, 20]; }; mapNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.window]; BPutBool[c, ev.overrideRedirect]; BSkip[c, 19]; }; mapRequest => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.parent]; BPutDrawable[c, ev.window]; BSkip[c, 20]; }; reparentNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.window]; BPutDrawable[c, ev.parent]; BPutPoint[c, ev.pos]; BPutBool[c, ev.overrideRedirect]; BSkip[c, 11]; }; configureNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.window]; BPutDrawable[c, ev.aboveSibling]; BPutRect[c, ev.geometry.pos, ev.geometry.size]; BPutINT32as16[c, ev.geometry.borderWidth]; BPut8[c, ev.overrideRedirect]; BSkip[c, 5]; }; configureRequest => { BPut8[c, ORD[ev.stackMode]]; BSkip[c, 2]; --sequence number BPutDrawable[c, ev.parent]; BPutDrawable[c, ev.window]; BPutDrawable[c, ev.sibling]; BPutRect[c, ev.geometry.pos, ev.geometry.size]; BPutINT32as16[c, ev.geometry.borderWidth]; BPut16[c, ev.valueMask]; BSkip[c, 4]; }; gravityNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.window]; BPutPoint[c, ev.pos]; BSkip[c, 16]; }; resizeRequest => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.window]; BPutSize[c, ev.size]; BSkip[c, 20]; }; circulateNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.eventWindow]; BPutDrawable[c, ev.window]; BSkip[c, 4]; --unused window BPut8[c, ORD[ev.place]]; BSkip[c, 15]; }; circulateRequest => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.parent]; BPutDrawable[c, ev.window]; BSkip[c, 4]; --unused BPut8[c, ORD[ev.place]]; BSkip[c, 15]; }; propertyNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.window]; BPut32[c, Xl.AtomId[ev.atom]]; BPutTime[c, ev.timeStamp]; BPut8[c, ORD[ev.state]]; BSkip[c, 15]; }; selectionClear => { BSkip[c, 3]; --unused and sequence number BPutTime[c, ev.timeStamp]; BPutDrawable[c, ev.owner]; BPut32[c, Xl.AtomId[ev.selection]]; BSkip[c, 16]; }; selectionRequest => { BSkip[c, 3]; --unused and sequence number BPutTime[c, ev.timeStamp]; BPutDrawable[c, ev.owner]; BPutDrawable[c, ev.requestor]; BPut32[c, Xl.AtomId[ev.selection]]; BPut32[c, Xl.AtomId[ev.target]]; BPut32[c, Xl.AtomId[ev.property]]; BSkip[c, 4]; }; selectionNotify => { BSkip[c, 3]; --unused and sequence number BPutTime[c, ev.timeStamp]; BPutDrawable[c, ev.requestor]; BPut32[c, Xl.AtomId[ev.selection]]; BPut32[c, Xl.AtomId[ev.target]]; BPut32[c, Xl.AtomId[ev.property]]; BSkip[c, 8]; }; colorMapNotify => { BSkip[c, 3]; --unused and sequence number BPutDrawable[c, ev.window]; BPutColorMap[c, ev.colorMap]; BPutBool[c, ev.new]; BPutBool[c, ev.installed]; BSkip[c, 18]; }; clientMessage => { BPut8[c, ev.format]; BPut16[c, 0]; --sequence number BPutDrawable[c, ev.window]; BPut32[c, ev.typeAtom.a]; SELECT ev.format FROM 32 => FOR i: [0..5) IN [0..5) DO BPut32[c, ev.w[i]] ENDLOOP; 8 => FOR i: [0..20) IN [0..20) DO BPut8[c, ev.b[i]] ENDLOOP; 16 => FOR i: [0..10) IN [0..10) DO BPut16[c, ev.h[i]] ENDLOOP; ENDCASE => ERROR; }; mappingNotify => { BSkip[c, 3]; --unused and sequence number BPut8[c, ORD[ev.request]]; BPut8[c, ev.firstKeycode]; BPut8[c, ev.count]; BSkip[c, 25]; }; ENDCASE => ERROR; }; FinishWithDetails[c, details]; }; TRUSTED { WITH ev: eventBody SELECT FROM local, errorNotify => ERROR; clientMessage => { SELECT ev.format FROM 8, 16, 32 => {}; ENDCASE => ERROR }; extension, tipEvent => ERROR; keyPress, keyRelease, buttonPress, buttonRelease, motionNotify, enterNotify, leaveNotify, focusIn, focusOut, keymapNotify, expose, graphicsExposure, noExposure, visibilityNotify, createNotify, destroyNotify, unmapNotify, mapNotify, mapRequest, reparentNotify, configureNotify, configureRequest, gravityNotify, resizeRequest, circulateNotify, circulateRequest, propertyNotify, selectionClear, selectionRequest, selectionNotify, colorMapNotify, mappingNotify => {}; ENDCASE => ERROR; }; DoWithLocks[c, action, details]; }; END. ζXlImplRequests.mesa Copyright Σ 1988, 1989, 1990, 1991, 1992, 1993 by Xerox Corporation. All rights reserved. Christian Jacobi, April 13, 1988 3:02:13 pm PDT Christian Jacobi, September 14, 1993 4:14 pm PDT textual copy lying around in AddDispatches --explicit check to stays if subrange checks are ommitted --explicit check to stays if subrange checks are ommitted --process to enable timeout mechanisms --don't bother X server too to often if wedges not too bad: use thread per connection --the vanilla X UngrabKeyboard request --Ignores originalCodeByte, dispatchDrawable, connection, and, sequence number in eventBody --WARNING: Some of the event types have not yet been tested --check validity outside of connections monitor Κ1€–(cedarcode) style•NewlineDelimiter ˜codešœ™Kšœ ΟeœO™ZKšœ/™/K™0—K˜šΟk œ˜ K˜”—šΟnœžœžœ˜Kšžœžœ˜Kšžœ„˜‹Kšžœ˜%Kšžœ*˜0—šœžœžœ˜K˜—Kšžœžœžœ˜Kšœžœ+˜IKšœžœžœ,˜RK˜šŸœžœžœ!žœ˜dKšœ ˜ šœžœ˜ Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ˜šœ˜Kšœ*™*Kšœžœ˜%Kšœ˜Kšœ$˜$Kšœ žœ˜Kšœžœ˜#Kšœžœ˜#Kšœ"˜"Kšœ!˜!Kšœ˜Kšœ!˜!Kšœžœ˜!Kšœ&˜&Kšœ(˜(Kšœžœ˜+Kšœžœ˜,Kšœžœ˜1Kšœ˜—K˜K˜—K˜šŸœžœžœN˜qšœžœ˜ Kšœ žœ˜šžœ*žœ˜2KšœW˜WKšœ!˜!K˜—Kšžœ%˜,šžœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšžœ$˜+Kšœ˜K˜—K˜—Kšœ ˜ Kšœ˜—K˜šŸœžœžœ˜¬šœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ šžœžœžœ ž˜Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜—š Ÿœžœžœžœžœžœ˜3Kšœžœ˜ K˜—šŸœžœžœžœ˜$KšΟc:™:Kšžœžœžœžœžœžœžœž˜-K˜—šŸœžœžœžœ˜$Kš :™:Kš žœžœžœžœžœžœž˜.K˜—Kšœ žœ˜Kšœžœžœžœ˜Kšœžœ˜Kšžœžœžœ˜ šžœžœ˜ Kšœ˜KšœM˜MKšœ˜—šžœžœ˜ Kšœ˜KšœM˜MKšœ˜—šžœžœ˜Kšœ˜KšœM˜MKšœ˜—šžœžœ˜ Kšœ˜KšœN˜NKšœ˜—šžœžœ˜!Kšœ˜KšœQ˜QKšœ˜—šžœžœ˜KšœN˜NKšœ˜—šžœžœ˜Kšœžœ9˜KKšœ˜—Kšžœ žœ!˜1K˜—K˜K˜šŸ œžœžœ˜7Kšœžœ'˜1Kšœ˜Kšœ˜Kšœ˜—Kšœ˜š Ÿ œžœžœ‘žœ1žœ˜–šœžœ˜ Kšœ žœ˜Kšœ˜Kšžœ žœžœ(žœ˜BKšžœ)˜0šžœ"žœžœž˜3KšœA˜AKšžœ˜—Kšžœ žœ žœ ˜'Kšœ˜Kšœ ˜,Kšœ ˜)Kšœ˜Kšœ˜Kšœ(˜(Kšœ žœ ˜Kšœ˜Kšœ˜Kšžœ$˜+Kšœ˜Kšœ˜—Kšžœžœžœ˜UKšžœžœ ˜AKšžœžœ˜9Kšžœžœ˜:Kšœ ˜ Kšœ˜—K˜šŸœžœžœ#˜LKšœžœ˜#Kšœžœ˜"K˜K˜—š Ÿœžœžœžœžœžœ˜OKšžœ$žœ Οfœ‘œ˜MKšžœ žœ˜EKšžœ žœ ‘œ‘œ˜GKšžœžœ!˜CKšžœžœžœ˜JKšžœžœžœ˜IKšžœžœžœ˜MKšžœ(žœ žœ˜PKšžœžœ"˜EKšžœžœžœ˜MKšžœžœžœ˜FKšžœ!žœ!˜HKšžœ*žœ)˜YKšžœžœ%˜IKšžœžœ%˜EKšœ˜K˜—šŸœžœžœžœžœ žœžœžœ˜SKšžœ$žœ ‘œ ˜GKšžœ žœ ‘œ ˜DKšžœ žœ ‘œ˜EKšžœžœ‘œ ˜FKšžœžœ‘œ˜IKšžœžœ‘œ ˜HKšžœžœ‘œ ˜JKšžœ(žœ ‘œ˜LKšžœžœ‘œ ˜GKšžœžœ‘œ ˜FKšžœžœ‘œ ˜FKšžœ!žœ‘œ ˜RKšžœ*žœ ‘œ ˜OKšžœžœ‘œ ˜IKšžœžœ‘œ ˜IKšœ˜—K˜š Ÿ œžœžœGžœžœ˜œšŸ œžœžœžœ˜CKšœ˜Kšœ˜—šœžœ˜ Kšœžœ'˜-Kšœ˜Kšœ˜Kšœ ˜*Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ ˜ Kšœ˜—K˜šŸ œžœžœžœ6˜SKšœ˜Kšœ˜Kšœ˜Kšœ6˜6Kš žœžœžœžœžœžœ ˜.K˜—K˜Kš œžœžœžœ žœ!˜HKš œžœžœžœ žœ˜Kšœ˜Kšœ˜Kšœ˜K˜—K˜šŸ œžœžœžœ ˜@Kšœ1˜1Kšžœ ˜Kšœ˜—K˜šŸ œžœžœUžœžœžœžœ#žœ"˜οšœžœ˜ Kšœ;˜;Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kš œ žœ žœžœžœ ˜9Kš œ žœ žœžœžœ ˜9Kšœ˜Kšœ˜K˜—Kšœ ˜ Kšœ˜—K˜šŸœžœžœJžœ žœžœžœžœžœ#žœ"˜Kšœžœ˜šœžœ˜ Kšœ;˜;Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kš œ žœ žœžœžœ ˜9Kš œ žœ žœžœžœ ˜9Kšœ˜K˜—Kšžœ žœžœ3˜IKšœ%˜%Kš œ žœ žœžœžœ˜BKšœ ˜ Kšœ˜—K˜šŸ œžœžœ-žœžœžœžœ&˜’šœžœ˜ Kšœ˜Kšœ˜Kš œ žœ žœžœžœ ˜9Kš œ žœ žœžœžœ ˜9Kšœ˜K˜—Kšžœ4žœžœ Ξ˜‘Kšœ ˜ K˜—K˜šŸ œžœžœ6˜Mšœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ5˜5K˜—Kšžœ4žœžœ \˜žKšœ%˜%Kšœ ˜ Kšœ˜—K˜šŸœžœ+˜BKšœžœžœ˜-Kšœ Οbœžœ ˜#K˜—K˜Kšœ žœžœ ˜šœžœžœžœ˜5Kšœ žœ žœ˜Kšœ ž œ˜Kšœ žœžœ˜Kšœ žœžœ˜Kšœ žœ˜Kšœ#˜#Kšœ!˜!K˜—K˜Kšœžœ˜:Kšœžœ  œžœV˜†K˜šŸ œžœžœ&˜?šžœ žœžœ˜Kšœžœ žœ˜8Kšœžœ˜Kšœžœ˜Kšžœ -˜EKšžœžœ.˜JK˜—K˜—K˜š Ÿ œžœžœ1žœ žœ˜_K™&Kšžœžœžœ˜šž˜Kšžœ˜Kšžœ žœžœ ˜6Kšžœžœžœ ˜>Kšžœžœžœ '˜Ušžœ>žœ˜FJš $™$šžœ˜ Kšžœ! ˜>šžœ˜šžœLžœ˜TKšœ9˜9Kšœžœ˜Kšž œ˜Kšžœ˜K˜—K˜——K˜—Kšžœ˜—K˜—K˜š Ÿ œžœžœ.žœžžœ#˜’šœžœžœ˜)Kšœ ˜ Kšœ&˜&Kšœ˜Kšœ ˜ Kšœ žœ˜Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ žœ˜šžœžœ˜Kšœžœ$˜.šžœžœžœ˜"Kšœžœ ˜'Kšœ7˜7KšžœA˜HK˜—Kšœ$˜$K˜—K˜—Kšœžœ˜Kšœ˜—Kšœ˜šŸœ  œžœ<˜dKšœ˜Kšœ˜Kšœ˜Kšžœ žœžœ#˜6K˜—K˜šŸ œžœžœ<˜VKšœžœB˜NKšœ ˜ Kšœ˜—Kšœ˜šŸœžœžœ|žœ˜¨šœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšžœ žœžœ˜1K˜—Kšœ ˜ Kšœ˜—K˜š Ÿ œžœžœmžœžœ„˜£šœžœ˜ Kšœ&˜&Kšœ˜Kšœ ˜ Kšœ žœ˜Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ0˜0Kšœ˜K˜—Kšœ ˜ K˜—K˜šŸ œžœžœEžœ˜}šœžœ˜ Kšœ˜Kšœ˜Kšœ0˜0Kšœ ˜ Kšœ˜Kšžœ žœžœ$˜7K˜—Kšœ ˜ K˜—K˜Kšœžœ˜5Kšœžœžœžœ˜Kšœ@˜@K˜šŸœ˜&Kšœ0™0šžœžœž˜šœ˜Kšœžœ3˜=Kšžœ!žœžœ ˜8Kšžœžœžœ ˜%Kšžœ(žœžœ ˜?šžœžœ˜Kšœ2žœ ˜WKšžœ  ˜K˜—šžœžœ˜ Kšœ.˜.Kšœ8 ˜LKšœ˜K˜—K˜—Kšžœ˜—Kšœ˜—K˜šŸœžœ˜1Kšœžœ$˜.šžœžœ˜$Kšœ*˜*Kšœ˜Kšœžœd˜„Kšœ˜—Kšœ˜—K˜š Ÿ œžœžœ2žœLžœ#˜Εšœžœ˜ Kšœžœ$˜.Kšœ ˜ Kšœ&˜&Kšœ˜Kšœ˜Kšœ žœ˜Kšœ žœ˜Kšœ ˜ Kšœ˜Kšœ žœ˜šžœžœ˜Kšœžœ˜Kšœ,˜,K˜—K˜—Kšœ˜Kšœ˜Kšœ˜—K˜šŸœžœžœ5žœ˜XKš &™&šœžœ˜ Kšœžœ$˜.Kšœ˜Kšœ˜Kšœ˜šžœžœ˜Kšœžœ˜Kšœ*žœ˜0K˜—K˜—Kšœ ˜ Kšœ˜K˜—šŸœžœžœ˜5Kšœžœ˜&Kšœžœ$˜.Kšœ˜KšœŽ˜ŽKšœ ˜ šžœ$žœž˜/Kšžœ5žœžœ˜CKšœ˜Kšžœ˜—K˜—K˜šŸœžœžœ\žœP˜Δšœžœ˜ Kšœ&˜&Kšœ˜Kšœ0˜0Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ ˜ Kšœ˜Kšœ˜—Kšœ ˜ K˜—K˜šŸ œžœžœ`˜všœžœ˜ Kšœ žœ ˜Kšœ˜Kšœ0˜0Kšœ ˜ Kšœ˜Kšœ˜—Kšœ ˜ K˜—K˜šŸ œžœžœN˜fšœžœ˜ Kšœ žœ ˜Kšœ˜Kšœ˜Kšžœ žœžœ#˜6K˜—Kšœ ˜ K˜—K˜šŸ œžœžœlžœ˜ŒKšœ9˜9Kšœ˜K™—šŸœžœžœ"˜>Kšœ,˜,Kšœ˜K™—šŸ œžœžœDžœ˜ušœžœ˜ Kšœ$˜$Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ ˜ Kšœ˜—K˜š Ÿœžœžœžœžœ˜RKšœ3˜3Kšœžœ˜.Kšœ˜K˜—K˜šŸœ  œžœ"žœ˜cKšœ˜Kšžœžœ˜2Kšœ˜Kšœ˜K˜—K˜šŸ œžœžœ.žœ˜eKšœ ˜ Kšœžœ=˜IKšœ˜šœ˜Kšœ ˜ Kšœ˜Kšœ&˜&Kšœ'˜'Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜—K˜šŸ œžœžœy˜‘šœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ ˜ Kšœ˜—K˜š Ÿœžœžœ9žœžœžœ˜{šœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšœžœžœ˜/Kšœžœ˜šœ˜K˜K˜K˜Kšœ˜šžœ$žœžœ˜IK˜DK˜ K˜—Kšœžœ˜šžœžœžœ ž˜Kšœ˜Kšœ žœžœžœ˜3Kšœ žœžœžœ˜3Kšžœ˜—Kšœ˜—Kšœ˜—K˜šŸ œžœžœGžœ˜yKšœ ˜ šœžœ˜ Kšœ žœ ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ˜šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ˜—K˜šŸœžœžœ>žœ˜€Kšœ ˜ šœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜Kšœ*˜*Kšœžœžœžœ˜4Kšœžœžœžœ˜4Kšœ˜Kšœ˜—K˜šŸœ  œžœ<˜cKšœ˜Kšœ˜Kšžœ žœžœ#˜6K˜—K˜šŸ œžœžœ&˜?šœžœ˜ Kšœžœ$˜.Kšœ.˜.Kšœ žœ˜&K˜—Kšœ ˜ Kšœ˜—K˜šŸ œžœžœ&˜=Kšœžœ$˜.Kšœžœ"˜)šœžœžœ˜)Kšœžœ$˜.šžœžœžœžœ˜)Kšœžœ ˜&Kšœ5˜5Kšžœ@˜GK˜—Kšœ˜Kšœ˜Kšœ#˜#K˜—Kšžœžœžœžœ?˜^Kšœ ˜ K˜—K˜šŸ œžœžœ%žœ˜Yšœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ ˜ Kšœ˜šœ˜Kšœ˜Kšœ˜Kšœ%˜%Kšœ"˜"Kšœ"˜"Kšœ'˜'Kšœ(˜(Kšœ(˜(Kšœ˜—K˜K˜—š Ÿ œžœžœ!žœ žœ˜^šœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœžœ˜.Kšœ˜šœ˜Kšœ˜Kšœ#˜#Kšœ%˜%Kšœ˜Kšœ˜Kšœ žœ˜Kšœ˜Kšœ˜šžœžœžœž˜Kšœ3˜3Kšžœ˜—Kšœ˜—K˜K˜—šŸœžœžœU˜qšœžœ˜ Kšœ žœ˜ Kšœ˜Kšœ˜K˜—Kšœ ˜ Kšœ˜K˜—šŸœžœžœU˜pšœžœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ ˜ Kšœ˜K˜—šŸœžœžœ1žœ<žœžœžœ˜Ύšœžœ˜ Kšœ%˜%Kšœ˜Kšœ žœ ˜Kšœ žœ˜(Kšœ ˜ Kšœ ˜!Kšœ˜Kšœ˜Kšžœ žœžœžœ˜6Kšœ˜K˜—Kšœ ˜ Kšœ˜K˜—šŸ œžœžœ1žœC˜ŽKšœ[™[Kšœ’9™;šœžœ˜ Kšœ%˜%Kšœ˜Kšœ˜Kšœ žœ˜)šžœ˜ šžœžœž˜šœ˜Kšœ žœ˜Kšœ  ˜Kšœ˜Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšœ˜Kšœ0˜0Kšœ˜Kšœ  ˜Kšœ˜—šœ˜Kšœ žœ ˜Kšœ  ˜Kšœ˜Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšœ˜Kšœ0˜0Kšœ˜Kšœ  ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ"˜"Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—šœ˜Kšœ žœ˜Kšœ  ˜Kšœ˜Kšœ˜Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜Kšœ0˜0Kšœ˜Kšœ ˜ Kšœ˜—šœ˜Kšœ žœ˜Kšœ  ˜Kšœ˜Kšœ˜Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜Kšœ0˜0Kšœ žœ ˜Kšœ žœžœ ˜.Kšœ˜—šœ˜Kšœ žœ˜Kšœ  ˜Kšœ"˜"Kšœ žœ ˜Kšœ˜Kšœ˜—šœ˜Kšžœ žœ žœžœ˜;Kšœ˜—šœ ˜ Kšœ  ˜)Kšœ˜Kšœ 5˜TKšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ 5˜TKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ žœ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ1˜1Kšœ,˜,Kšœ#˜#Kšœ ˜ Kšœ˜—šœ˜Kšœ  ˜)Kšœ"˜"Kšœ˜Kšœ ˜ Kšœ˜—šœ˜Kšœ  ˜)Kšœ"˜"Kšœ˜Kšœ"˜"Kšœ ˜ Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—šœ˜Kšœ  ˜)Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ"˜"Kšœ˜Kšœ#˜#Kšœ/˜/Kšœ*˜*Kšœ˜Kšœ ˜ Kšœ˜—šœ˜Kšœ žœ˜Kšœ  ˜Kšœ˜Kšœ˜Kšœ˜Kšœ/˜/Kšœ*˜*Kšœ˜Kšœ ˜ Kšœ˜—šœ˜Kšœ  ˜)Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ"˜"Kšœ˜Kšœ  ˜Kšœ žœ ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ  ˜Kšœ žœ ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ ˜ Kšœ˜Kšœ žœ ˜Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ%˜%Kšœ˜Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ ˜ Kšœ%˜%Kšœ"˜"Kšœ$˜$Kšœ ˜ Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ ˜ Kšœ%˜%Kšœ"˜"Kšœ$˜$Kšœ ˜ Kšœ˜—šœ˜Kšœ  ˜)Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ˜Kšœ ˜!Kšœ˜Kšœ˜šžœ ž˜Kš œžœ žœžœžœ˜Kšžœžœ˜—Kšœ˜—šœ˜Kšœ  ˜)Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšžœžœ˜—K˜—Kšœ˜K˜—šžœ˜ Kšœ/™/šžœžœž˜Kšœžœ˜šœ˜šžœ žœ˜Kšœ˜Kšžœž˜—Kšœ˜—Kšœžœ˜KšœΠ˜ΠKšžœžœ˜—K˜—Kšœ ˜ Kšœ˜—K˜Kšžœ˜K˜—…—ͺޚ