XlShapeImpl.mesa
Copyright Ó 1991, 1992, 1993 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, October 4, 1991
Christian Jacobi, September 14, 1993 4:22 pm PDT
X11 nonrectangular window shape extension
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.