<<>> <> <> <> <> <<>> <> <<>> DIRECTORY Basics, Xl, XlEndianPrivate, XlExtensions, XlPrivate, XlShape; XlShapeImpl: CEDAR MONITOR LOCKS c USING c: Xl.Connection IMPORTS Basics, Xl, XlEndianPrivate, XlExtensions, XlPrivate EXPORTS XlShape SHARES Xl ~ BEGIN OPEN XlShape; notifyKey: PUBLIC REF ANY ¬ NEW[ATOM ¬ $ShapeNotify]; ConnectionData: TYPE ~ RECORD [ c: Xl.Connection, ex: XlExtensions.Extension ¬ NIL ]; GetConnectionData: PROC [c: Xl.Connection] RETURNS [cd: REF ConnectionData] = { cd ¬ lastConnectionData; IF cd.c=c THEN RETURN[cd]; cd ¬ lastConnectionData ¬ NARROW[Xl.GetConnectionPropAndInit[c, privateKey, InitExtension]]; }; privateKey: REF ~ NEW[ATOM ¬ $SHAPE]; lastConnectionData: REF ConnectionData ¬ NEW[ConnectionData]; --never NIL InitExtension: Xl.InitializeProcType = { <<--For this connection-->> cd: REF ConnectionData ~ NEW[ConnectionData]; cd.ex ¬ XlExtensions.StartExtension[c, $SHAPE]; RETURN [cd] }; QueryVersion: PUBLIC PROC [c: Xl.Connection] RETURNS [available: BOOL ¬ FALSE, majorVersion: INT ¬ 0, minorVersion: INT ¬ 0] = { cd: REF ConnectionData ¬ GetConnectionData[c]; reply: XlPrivate.Reply; IF cd.ex#NIL THEN { DoIt: PROC [c: Xl.Connection] = { XlPrivate.BInit[c, cd.ex.majorOpcode, 0, 1]; reply ¬ XlPrivate.FinishWithReply[c]; }; XlPrivate.DoWithLocks[c, DoIt, NIL]; XlPrivate.CheckReply[reply]; XlPrivate.Skip[reply, 7]; majorVersion ¬ XlPrivate.Read16[reply]; minorVersion ¬ XlPrivate.Read16[reply]; available ¬ majorVersion>0; XlPrivate.DisposeReply[c, reply]; }; }; <<>> Rectangles: PUBLIC PROC [c: Xl.Connection, dest: Xl.Window, destKind: Kind, op: Op, off: Xl.Point, rectangles: REF ANY, ordering: Xl.Ordering, start: INT ¬ 0, number: INT ¬ LAST[INT], details: Xl.Details ¬ NIL] = { EntryDoIt: ENTRY PROC [c: Xl.Connection] = { err: Xl.ErrorNotifyEvent; XlPrivate.BInit[c, cd.ex.majorOpcode, 1, 4+2*total]; XlPrivate.BPut8[c, ORD[op]]; XlPrivate.BPut8[c, ORD[destKind]]; XlPrivate.BPut8[c, ORD[ordering]]; XlPrivate.BPut8[c, 0]; XlPrivate.BPutDrawable[c, dest]; XlPrivate.BPutPoint[c, off]; XlPrivate.BPutRectangles[c, rects, start, total]; err ¬ XlPrivate.FinishWithDetailsNoErrors[c, details]; IF err#NIL THEN RETURN WITH ERROR Xl.XError[err]; }; rects: Xl.PackedRects ¬ NIL; total: INT; cd: REF ConnectionData ¬ GetConnectionData[c]; IF cd.ex=NIL OR start<0 THEN ERROR; WITH rectangles SELECT FROM pr: Xl.PackedRects => rects ¬ pr ENDCASE => ERROR; total ¬ (IF rects#NIL THEN MIN[number, rects.numberOfRects-start] ELSE 0); IF total>Xl.Info[c].maxRequestLength/2 THEN ERROR; EntryDoIt[c]; }; <<>> Mask: PUBLIC PROC [c: Xl.Connection, dest: Xl.Window, destKind: Kind, op: Op, off: Xl.Point, source: Xl.Pixmap ¬ Xl.nullPixmap, details: Xl.Details ¬ NIL] = { EntryDoIt: ENTRY PROC [c: Xl.Connection] = { err: Xl.ErrorNotifyEvent; XlPrivate.BInit[c, cd.ex.majorOpcode, 2, 5]; XlPrivate.BPut8[c, ORD[op]]; XlPrivate.BPut8[c, ORD[destKind]]; XlPrivate.BSkip[c, 2]; XlPrivate.BPutDrawable[c, dest]; XlPrivate.BPutPoint[c, off]; XlPrivate.BPutPixmap[c, source]; err ¬ XlPrivate.FinishWithDetailsNoErrors[c, details]; IF err#NIL THEN RETURN WITH ERROR Xl.XError[err]; }; cd: REF ConnectionData ¬ GetConnectionData[c]; IF cd.ex=NIL THEN ERROR; EntryDoIt[c]; }; <<>> Combine: PUBLIC PROC [c: Xl.Connection, dest: Xl.Window, destKind: Kind, op: Op, off: Xl.Point, source: Xl.Window, sourceKind: Kind, details: Xl.Details ¬ NIL] = { EntryDoIt: ENTRY PROC [c: Xl.Connection] = { err: Xl.ErrorNotifyEvent; XlPrivate.BInit[c, cd.ex.majorOpcode, 3, 5]; XlPrivate.BPut8[c, ORD[op]]; XlPrivate.BPut8[c, ORD[destKind]]; XlPrivate.BPut8[c, ORD[sourceKind]]; XlPrivate.BSkip[c, 1]; XlPrivate.BPutDrawable[c, dest]; XlPrivate.BPutPoint[c, off]; XlPrivate.BPutDrawable[c, source]; err ¬ XlPrivate.FinishWithDetailsNoErrors[c, details]; IF err#NIL THEN RETURN WITH ERROR Xl.XError[err]; }; cd: REF ConnectionData ¬ GetConnectionData[c]; IF cd.ex=NIL THEN ERROR; EntryDoIt[c]; }; Offset: PUBLIC PROC [c: Xl.Connection, dest: Xl.Window, destKind: Kind, off: Xl.Point, details: Xl.Details ¬ NIL] = { EntryDoIt: ENTRY PROC [c: Xl.Connection] = { err: Xl.ErrorNotifyEvent; XlPrivate.BInit[c, cd.ex.majorOpcode, 4, 4]; XlPrivate.BPut8[c, ORD[destKind]]; XlPrivate.BSkip[c, 3]; XlPrivate.BPutDrawable[c, dest]; XlPrivate.BPutPoint[c, off]; err ¬ XlPrivate.FinishWithDetailsNoErrors[c, details]; IF err#NIL THEN RETURN WITH ERROR Xl.XError[err]; }; cd: REF ConnectionData ¬ GetConnectionData[c]; IF cd.ex=NIL THEN ERROR; EntryDoIt[c]; }; ReadPos: PROC [reply: XlPrivate.Reply] RETURNS [p: Xl.Point] = INLINE { p.x ¬ LONG[LOOPHOLE[XlPrivate.Read16[reply], INT16]]; p.y ¬ LONG[LOOPHOLE[XlPrivate.Read16[reply], INT16]]; }; ReadSize: PROC [reply: XlPrivate.Reply] RETURNS [s: Xl.Size] = INLINE { s.width ¬ LONG[XlPrivate.Read16[reply]]; s.height ¬ LONG[XlPrivate.Read16[reply]]; }; QueryExtents: PUBLIC PROC [c: Xl.Connection, dest: Xl.Window] RETURNS [e: ExtentsRec] = { cd: REF ConnectionData ¬ GetConnectionData[c]; reply: XlPrivate.Reply; DoIt: PROC [c: Xl.Connection] = { XlPrivate.BInit[c, cd.ex.majorOpcode, 5, 2]; XlPrivate.BPutDrawable[c, dest]; reply ¬ XlPrivate.FinishWithReply[c]; }; IF cd.ex=NIL THEN ERROR; XlPrivate.DoWithLocks[c, DoIt, NIL]; XlPrivate.CheckReply[reply]; XlPrivate.Skip[reply, 7]; e.boundingShaped ¬ XlPrivate.Read8[reply]#0; e.clipShaped ¬ XlPrivate.Read8[reply]#0; e.boundingShape ¬ ReadPos[reply]; e.widthBounding ¬ ReadSize[reply]; e.clipShape ¬ ReadPos[reply]; e.widthClipShape ¬ ReadSize[reply]; XlPrivate.DisposeReply[c, reply]; }; SelectInput: PUBLIC PROC [c: Xl.Connection, window: Xl.Window, enable: BOOL, details: Xl.Details ¬ NIL] = { EntryDoIt: ENTRY PROC [c: Xl.Connection] = { err: Xl.ErrorNotifyEvent; XlPrivate.BInit[c, cd.ex.majorOpcode, 6, 3]; XlPrivate.BPutDrawable[c, window]; XlPrivate.BPut8[c, XlPrivate.ToCBool[enable]]; XlPrivate.BSkip[c, 3]; err ¬ XlPrivate.FinishWithDetailsNoErrors[c, details]; IF err#NIL THEN RETURN WITH ERROR Xl.XError[err]; }; cd: REF ConnectionData ¬ GetConnectionData[c]; IF cd.ex#NIL THEN EntryDoIt[c]; }; InputSelected: PUBLIC PROC [c: Xl.Connection, window: Xl.Window] RETURNS [enabled: BOOL] = { cd: REF ConnectionData ¬ GetConnectionData[c]; reply: XlPrivate.Reply; DoIt: PROC [c: Xl.Connection] = { XlPrivate.BInit[c, cd.ex.majorOpcode, 7, 2]; XlPrivate.BPutDrawable[c, window]; reply ¬ XlPrivate.FinishWithReply[c]; }; IF cd.ex=NIL THEN ERROR; XlPrivate.DoWithLocks[c, DoIt, NIL]; XlPrivate.CheckReply[reply]; enabled ¬ XlPrivate.Read8[reply]#0; XlPrivate.DisposeReply[c, reply]; }; GetRectangles: PUBLIC PROC [c: Xl.Connection, window: Xl.Window, kind: Kind] RETURNS [rectangles: Xl.PackedRects, ordering: Xl.Ordering] = { cd: REF ConnectionData ¬ GetConnectionData[c]; reply: XlPrivate.Reply; DoIt: PROC [c: Xl.Connection] = { XlPrivate.BInit[c, cd.ex.majorOpcode, 8, 3]; XlPrivate.BPutDrawable[c, window]; XlPrivate.BPut8[c, ORD[kind]]; XlPrivate.BSkip[c, 3]; reply ¬ XlPrivate.FinishWithReply[c]; }; ReadRectangles: PROC [reply: XlPrivate.Reply, n: CARD] RETURNS [rectangles: Xl.PackedRects] = TRUSTED { rectangles ¬ NEW[Xl.PackedRectangleSequence[n]]; Basics.MoveWords[dst: LOOPHOLE[@rectangles[0]], src: LOOPHOLE[reply.varPart], count: n*WORDS[Xl.PackedRectangle]]; }; n: CARD32; IF cd.ex=NIL THEN ERROR; XlPrivate.DoWithLocks[c, DoIt, NIL]; XlPrivate.CheckReply[reply]; ordering ¬ VAL[XlPrivate.Read8[reply]]; XlPrivate.Skip[reply, 6]; n ¬ XlPrivate.Read32[reply]; XlPrivate.Skip[reply, 20]; rectangles ¬ ReadRectangles[reply, n]; XlPrivate.DisposeReply[c, reply]; }; ProcessShapeNotifyEvent: XlExtensions.ProcessExtensionEventProc = { ev: REF NotifyRep ~ NEW[NotifyRep]; BEGIN byte: BYTE ¬ XlEndianPrivate.InlineExtensionGet8[xEvent, 1]; IF byte<2 THEN ev.kind ¬ VAL[byte]; END; ev.window.drawable ¬ [XlEndianPrivate.InlineExtensionGet32[xEvent, 4]]; ev.pos.x ¬ LOOPHOLE[XlEndianPrivate.InlineExtensionGet16[xEvent, 8], INT16]; ev.pos.y ¬ LOOPHOLE[XlEndianPrivate.InlineExtensionGet16[xEvent, 10], INT16]; ev.size.width ¬ XlEndianPrivate.InlineExtensionGet16[xEvent, 12]; ev.size.height ¬ XlEndianPrivate.InlineExtensionGet16[xEvent, 14]; ev.time ¬ LOOPHOLE[XlEndianPrivate.InlineExtensionGet32[xEvent, 16]]; ev.shaped ¬ XlEndianPrivate.InlineExtensionGet8[xEvent, 20]#0; xEvent.decoded ¬ ev; xEvent.dispatchDrawable ¬ ev.window; xEvent.match ¬ notifyKey; xEvent.extension ¬ $SHAPE; RETURN [dispatch] }; XlExtensions.DefineExtensionClass[key: $SHAPE, processEvents: ProcessShapeNotifyEvent, majorEventsCnt: 1]; END.