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
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;
<<Xl.>> 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];
textual copy lying around in AddDispatches
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 {
--explicit check to stays if subrange checks are ommitted
IF i>LAST[INT16] OR i<FIRST[INT16] THEN ERROR
};
CheckC16: PROC [i: INT32] = INLINE {
--explicit check to stays if subrange checks are ommitted
IF LOOPHOLE[i, CARD32]>LAST[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 <<XlPrivate>> 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;
<<XlPrivateTypes.>>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 <<use only flushNowDetails>>];
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] = {
--process to enable timeout mechanisms
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 {
--don't bother X server too to often
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 = "�r←KeyboardGrabCheck";
keyboardGrab: REF ¬ NEW[INT];
propertyEvents: EventFilter = CreateEventFilter[propertyNotify];
KeyboardUnWedgeProc: EventProcType = {
if wedges not too bad: use thread per connection
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] = {
--the vanilla X UngrabKeyboard request
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] = {
--Ignores originalCodeByte, dispatchDrawable, connection, and, sequence number in eventBody
--WARNING: Some of the event types have not yet been tested
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 {
--check validity outside of connections monitor
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.