<<>> <> <> <> <> 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.