XlConventionsImpl.mesa
Copyright Ó 1988, 1989, 1990, 1991 by Xerox Corporation. All rights reserved.
Christian Jacobi, April 13, 1988 3:02:13 pm PDT
Christian Jacobi, August 22, 1991 4:28 pm PDT
DIRECTORY
Rope, Xl, XlConventions, XlICCCMTypes, XlPredefinedAtoms, XlService;
XlConventionsImpl: CEDAR PROGRAM
IMPORTS Rope, Xl, XlService
EXPORTS XlConventions
~ BEGIN OPEN Xl;
cutBuffKey: REF ATOM ¬ NEW[ATOM ¬ $CutBuff];
cutBuffList: LIST OF XAtom;
SetWMNormalHints: PUBLIC PROC [c: Connection, window: Window, sizeHints: XlICCCMTypes.WMNormalHints, allways: BOOL ¬ FALSE] = {
usPos: CARD = 1;
usSize: CARD = 2;
pPos: CARD = 4;
pSize: CARD = 8;
pMinSize: CARD = 16;
pMaxSize: CARD = 32;
pResizeInc: CARD = 64;
pAspect: CARD = 128;
pBaseSz: CARD = 256;
pWinGravity: CARD = 512;
x: REF Card32Sequence ¬ NEW[Card32Sequence[18]];
flags: CARD32 ¬ 0;
x[1] ¬ LOOPHOLE[sizeHints.obsoletePos.x];
x[2] ¬ LOOPHOLE[sizeHints.obsoletePos.y];
IF sizeHints.userPos THEN flags ¬ flags+usPos;
IF sizeHints.clientPos THEN flags ¬ flags+pPos;
x[3] ¬ LOOPHOLE[sizeHints.obsoleteSz.width];
x[4] ¬ LOOPHOLE[sizeHints.obsoleteSz.height];
IF sizeHints.userSize THEN flags ¬ flags+usSize;
IF sizeHints.clientSize THEN flags ¬ flags+pSize;
x[5] ¬ LOOPHOLE[sizeHints.minSz.width];
x[6] ¬ LOOPHOLE[sizeHints.minSz.height];
IF sizeHints.minSz.width>0 OR sizeHints.minSz.height>0 THEN flags ¬ flags+pMinSize;
x[7] ¬ LOOPHOLE[sizeHints.maxSz.width];
x[8] ¬ LOOPHOLE[sizeHints.maxSz.height];
IF sizeHints.maxSz.width>0 OR sizeHints.maxSz.height>0 THEN flags ¬ flags+pMaxSize;
x[9] ¬ LOOPHOLE[sizeHints.incSz.width];
x[10] ¬ LOOPHOLE[sizeHints.incSz.height];
IF sizeHints.incSz.width>0 OR sizeHints.incSz.height>0 THEN flags ¬ flags+pResizeInc;
x[11] ¬ LOOPHOLE[sizeHints.minAspectN];
x[12] ¬ LOOPHOLE[sizeHints.minAspectD];
x[13] ¬ LOOPHOLE[sizeHints.maxAspectN];
x[14] ¬ LOOPHOLE[sizeHints.maxAspectD];
IF sizeHints.minAspectN>0 OR sizeHints.maxAspectN>0 THEN flags ¬ flags+pAspect;
x[15] ¬ LOOPHOLE[sizeHints.baseSz.width];
x[16] ¬ LOOPHOLE[sizeHints.baseSz.height];
IF sizeHints.baseSz.width>0 OR sizeHints.baseSz.height>0 THEN flags ¬ flags+pBaseSz;
IF sizeHints.gravity>=northWest AND sizeHints.gravity<=southEast THEN {
x[17] ¬ ORD[sizeHints.gravity];
flags ¬ flags+pWinGravity;
};
x[0] ¬ flags;
IF flags#0 OR allways THEN
ChangeProperty[c: c, w: window, property: XlPredefinedAtoms.wmNormalHints, type: XlPredefinedAtoms.wmSizeHints, mode: replace, data: x];
};
SetWMHints: PUBLIC PROC [c: Connection, window: Window, hints: XlICCCMTypes.WMHints, allways: BOOL ¬ FALSE] = {
inputHint: CARD = 1;
stateHint: CARD = 2;
iconPixmapHint: CARD = 4;
iconWindowHint: CARD = 8;
iconPositionHint: CARD = 16;
iconMaskHint: CARD = 32;
windowGroupHint: CARD = 64;
x: REF Card32Sequence ¬ NEW[Card32Sequence[9]];
flags: CARD32 ¬ 0;
x[1] ¬ hints.input;
IF hints.input#0 THEN flags ¬ flags+inputHint;
x[2] ¬ hints.initialState;
IF hints.initialState#0 THEN flags ¬ flags+stateHint;
x[3] ¬ hints.iconPixmap;
IF hints.iconPixmap#Xl.nullPixmap THEN flags ¬ flags+iconPixmapHint;
x[4] ¬ hints.iconWindow;
IF hints.iconWindow#Xl.nullWindow THEN flags ¬ flags+iconWindowHint;
x[5] ¬ LOOPHOLE[hints.iconPos.x];
x[6] ¬ LOOPHOLE[hints.iconPos.y];
IF hints.iconPos.x#0 OR hints.iconPos.y#0 THEN flags ¬ flags+iconPositionHint;
x[7] ¬ hints.iconMask;
IF hints.iconMask#Xl.nullPixmap THEN flags ¬ flags+iconMaskHint;
x[8] ¬ hints.windowGroup;
IF hints.windowGroup#Xl.nullWindow THEN flags ¬ flags+windowGroupHint;
x[0] ¬ flags;
IF flags#0 OR allways THEN
ChangeProperty[c: c, w: window, property: XlPredefinedAtoms.wmHints, type: XlPredefinedAtoms.wmHints, mode: replace, data: x];
};
SetWindowName: PUBLIC PROC [c: Connection, window: Window, windowName: ROPE] = {
ChangeProperty[c, window, XlPredefinedAtoms.wmName, XlPredefinedAtoms.string, replace, windowName];
};
SetIconName: PUBLIC PROC [c: Connection, window: Window, iconName: ROPE] = {
ChangeProperty[c, window, XlPredefinedAtoms.wmIconName, XlPredefinedAtoms.string, replace, iconName];
};
SetWMTransient: PUBLIC PROC [c: Connection, window: Window, for: Window] = {
x: REF Card32Sequence ¬ NIL;
IF Xl.WindowId[for]#0 THEN {
x ¬ NEW[Card32Sequence[1]];
x[0] ¬ Xl.WindowId[for];
};
Xl.ChangeProperty[c, window, XlPredefinedAtoms.wmTransientFor, XlPredefinedAtoms.wmTransientFor, replace, x];
};
SetWMClass: PUBLIC PROC [c: Connection, window: Window, instance, class: ROPE ¬ NIL] = {
IF class#NIL OR instance#NIL THEN {
val: ROPE ¬ Rope.Cat[instance, "\000", class, "\000"];
ChangeProperty[c, window, XlPredefinedAtoms.wmClass, XlPredefinedAtoms.string, replace, val];
};
};
SetWMProtocols: PUBLIC PROC [c: Connection, window: Window, protocols: LIST OF Rope.ROPE] = {
protocolsAtom: Xl.XAtom ¬ Xl.MakeAtom[c, "WM←PROTOCOLS"];
cnt: NAT ¬ 0;
x: REF Xl.Card32Sequence;
FOR l: LIST OF Rope.ROPE ¬ protocols, l.rest WHILE l#NIL DO
cnt ¬ cnt+1;
ENDLOOP;
x ¬ NEW[Xl.Card32Sequence[cnt]];
FOR cn: NAT IN [0..cnt) DO
IF protocols=NIL THEN {cnt ¬ cn; EXIT};
x[cn] ¬ Xl.MakeAtom[c, protocols.first];
protocols ¬ protocols.rest
ENDLOOP;
Xl.ChangeProperty[c: c, w: window, property: protocolsAtom, type: XlPredefinedAtoms.atom, mode: replace, data: x, num: cnt];
};
WMQueryPosition: PUBLIC PROC [c: Connection] RETURNS [BOOL] = {
SELECT XlService.GetServiceProp[c, $WM] FROM
$uwm => RETURN [TRUE];
$twm => RETURN [FALSE];
$none => RETURN [FALSE];
ENDCASE => RETURN [FALSE];
};
WMMakesHeader: PUBLIC PROC [c: Connection] RETURNS [BOOL] = {
SELECT XlService.GetServiceProp[c, $WM] FROM
$uwm => RETURN [FALSE];
$twm => RETURN [TRUE];
$none => RETURN [FALSE];
ENDCASE => RETURN [TRUE];
};
CutBufferInit: Xl.InitializeProcType = {
cutBuffList ¬ LIST[XlPredefinedAtoms.cutBuffer0, XlPredefinedAtoms.cutBuffer1, XlPredefinedAtoms.cutBuffer2, XlPredefinedAtoms.cutBuffer3, XlPredefinedAtoms.cutBuffer4, XlPredefinedAtoms.cutBuffer5, XlPredefinedAtoms.cutBuffer6, XlPredefinedAtoms.cutBuffer7];
FOR l: LIST OF XAtom ¬ cutBuffList, l.rest WHILE l#NIL DO
Xl.ChangeProperty[c: c, w: FirstRoot[c], property: l.first, type: XlPredefinedAtoms.string, mode: append, data: NIL];
ENDLOOP;
};
CutBufferPush: PUBLIC PROC [c: Xl.Connection, data: Rope.ROPE, hackForXTerm: BOOL ¬ FALSE] = {
root: Xl.Window ¬ FirstRoot[c];
[] ¬ XlService.GetServicePropAndInit[c, cutBuffKey, CutBufferInit];
IF ~hackForXTerm THEN {
Xl.GrabServer[c];
Xl.RotateProperties[c, root, 1, cutBuffList];
};
IF Rope.Length[data]>2000 THEN data ¬ Rope.Substr[data, 0, 2000]; --prevent server memory overflow
Xl.ChangeProperty[c: c, w: root, property: cutBuffList.first, type: XlPredefinedAtoms.string, mode: replace, data: data];
--rude but effective:
-- Clear selection; programs like xterm check for both, selections and cutbuffer.
-- These programs will not use a selection after a cut command anymore
Xl.SetSelectionOwner[c: c, selection: XlPredefinedAtoms.primary, time: Xl.currentTime];
IF ~hackForXTerm THEN Xl.UngrabServer[c];
};
CutBufferGet: PUBLIC PROC [c: Xl.Connection] RETURNS [data: Rope.ROPE¬NIL] = {
root: Xl.Window ¬ FirstRoot[c];
pr: PropertyReturnRec;
[] ¬ XlService.GetServicePropAndInit[c, cutBuffKey, CutBufferInit];
pr ¬ Xl.GetProperty[c: c, w: root, property: cutBuffList.first, supposedFormat: 8];
WITH pr.value SELECT FROM
r: Rope.ROPE => data ¬ r;
ENDCASE => {};
};
CutBufferRotate: PUBLIC PROC [c: Xl.Connection, amount: INT ¬ -1] = {
root: Xl.Window ¬ FirstRoot[c];
[] ¬ XlService.GetServicePropAndInit[c, cutBuffKey, CutBufferInit];
Xl.RotateProperties[c, root, amount, cutBuffList];
Xl.Flush[c];
};
END.