DIRECTORY CBitmapReader, ImagerSample, IO, PFS, Rope, Xl, XTk, XTkDB, XTkIcon, XTkShellWidgets; XTkIconImpl: CEDAR PROGRAM IMPORTS CBitmapReader, ImagerSample, IO, PFS, Rope, Xl, XTkDB, XTkShellWidgets EXPORTS XTkIcon = BEGIN SMFromName: PROC [fileName: Rope.ROPE] RETURNS [sm: ImagerSample.RasterSampleMap ¬ NIL] = { GetStream: PROC [fileName: Rope.ROPE] RETURNS [s: IO.STREAM ¬ NIL] = { IF Rope.Length[fileName]>0 THEN { ENABLE PFS.Error => GOTO oops; s ¬ PFS.StreamOpen[fileName: PFS.PathFromRope[fileName], accessOptions: read]; EXITS oops => {} }; }; stream: IO.STREAM ~ GetStream[fileName]; IF stream#NIL THEN { sm ¬ CBitmapReader.FromStream[stream ! CBitmapReader.Error => {IO.Close[stream ! IO.Error => GOTO oops]; GOTO oops} ].sm; IO.Close[stream]; }; EXITS oops => {}; }; SetIcon: PROC [shell: XTk.Widget, icccmHints: REF XTkShellWidgets.ICCCMHints, baseFileNamePart, maskFileNamePart: Rope.ROPE] = { sm: ImagerSample.RasterSampleMap ¬ SMFromName[baseFileNamePart]; IF sm#NIL THEN { screen: Xl.Screen ~ shell.screenDepth.screen; szVec: ImagerSample.Vec ~ ImagerSample.GetSize[sm]; size: Xl.Size ~ [width: szVec.f, height: szVec.s]; base: LONG POINTER ~ LOOPHOLE[ImagerSample.GetBase[sm].word]; scanLineBytes: INT ~ ImagerSample.GetBitsPerLine[sm]/8; iconPixmap: Xl.Pixmap ~ Xl.CreatePixmap[shell.connection, screen.root.drawable, size, 1]; --A pixmap of depth 1 is always supported (Protocol; in prose for connection set up) gc: Xl.GContext ~ Xl.MakeGContext[shell.connection, iconPixmap.drawable]; Xl.SetGCGrounds[gc, 1, 0]; Xl.PutImage[c: shell.connection, drawable: iconPixmap.drawable, gc: gc, base: base, size: size, dest: [0, 0], offx: 0, offy: 0, scanLineBytes: scanLineBytes, bitsPerPixel: 1]; icccmHints.wmHints.iconPixmap ¬ iconPixmap; icccmHints.wmHintsChanged ¬ TRUE; IF Rope.Equal[baseFileNamePart, maskFileNamePart] THEN { icccmHints.wmHints.iconMask ¬ iconPixmap; icccmHints.wmHintsChanged ¬ TRUE; RETURN; }; IF maskFileNamePart#NIL THEN { sm: ImagerSample.RasterSampleMap ¬ SMFromName[maskFileNamePart]; IF sm#NIL THEN { szVec: ImagerSample.Vec ~ ImagerSample.GetSize[sm]; size: Xl.Size ~ [width: szVec.f, height: szVec.s]; base: LONG POINTER ~ LOOPHOLE[ImagerSample.GetBase[sm].word]; scanLineBytes: INT ~ ImagerSample.GetBitsPerLine[sm]/8; maskPixmap: Xl.Pixmap ~ Xl.CreatePixmap[shell.connection, screen.root.drawable, size, 1]; --A pixmap of depth 1 is always supported (Protocol; in prose for connection set up) Xl.PutImage[c: shell.connection, drawable: maskPixmap.drawable, gc: gc, base: base, size: size, dest: [0, 0], offx: 0, offy: 0, scanLineBytes: scanLineBytes, bitsPerPixel: 1]; icccmHints.wmHints.iconMask ¬ maskPixmap; icccmHints.wmHintsChanged ¬ TRUE; }; }; }; }; RopeQuery: PROC [shell: XTk.Widget, key: ATOM] RETURNS [Rope.ROPE¬NIL] = { q: REF ~ XTkDB.DoQueryFromWidget[shell, FALSE, key]; WITH q SELECT FROM r: Rope.ROPE => RETURN [r]; ENDCASE => {} }; SetIconName: PUBLIC PROC [shell: XTk.Widget, fromDB: BOOL _ TRUE, default: Rope.ROPE ¬ NIL] = { icccmHints: REF XTkShellWidgets.ICCCMHints ~ XTkShellWidgets.GetHints[shell]; IF icccmHints.iconName=NIL THEN { IF fromDB THEN { specified: Rope.ROPE ¬ RopeQuery[shell, $iconName]; IF ~Rope.IsEmpty[specified] THEN { icccmHints.iconName ¬ specified; icccmHints.iconNameChanged ¬ TRUE; RETURN } }; icccmHints.iconName ¬ default; }; }; SetIconMask: PUBLIC PROC [shell: XTk.Widget, fromDB: BOOL _ TRUE, packageName, shortName: Rope.ROPE ¬ NIL] = { fileName: Rope.ROPE ¬ NIL; icccmHints: REF XTkShellWidgets.ICCCMHints ~ XTkShellWidgets.GetHints[shell]; hasIconWindow: BOOL ¬ icccmHints.wmHints.iconWindow#Xl.nullWindow; hasIcon: BOOL ~ hasIconWindow OR (icccmHints.wmHints.iconPixmap#Xl.illegalPixmap AND icccmHints.wmHints.iconPixmap#Xl.nullPixmap); hasMask: BOOL ~ hasIconWindow OR (icccmHints.wmHints.iconMask#Xl.illegalPixmap AND icccmHints.wmHints.iconMask#Xl.nullPixmap); IF ~hasIcon THEN { IF fromDB THEN { fileName ¬ RopeQuery[shell, $iconPixmap]; IF ~Rope.IsEmpty[fileName] THEN { iconMaskFile: Rope.ROPE ¬ NIL; IF ~hasMask THEN iconMaskFile ¬ RopeQuery[shell, $iconMask]; SetIcon[shell, icccmHints, fileName, iconMaskFile]; RETURN; } }; fileName _ IO.PutFR["/cedar/%g/%g.", IO.rope[packageName], IO.rope[shortName]]; SetIcon[shell, icccmHints, Rope.Concat[fileName, "xIcon"], Rope.Concat[fileName, "xIconMask"]]; }; }; END. ΐ XTkIconImpl.mesa Copyright Σ 1991, 1992 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, May 2, 1991 2:46:56 pm PDT Christian Jacobi, July 13, 1992 2:46 pm PDT Κς–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ Οeœ7™BKšœ7™7K™+K™—šΟk œ˜ Kšœžœžœ1˜UK˜—šΟn œžœžœ˜Kšžœžœžœ"˜NKšžœ ˜—Kšžœ˜K˜š Ÿ œžœžœžœ%žœ˜[šŸ œžœžœžœžœžœžœ˜Fšžœžœ˜!Kšžœžœ žœ˜Kšœžœžœ/˜OKšžœ ˜K˜—K˜—Kšœžœžœ˜(šžœžœžœ˜šœ%˜%Kš œžœžœ žœžœ˜NKšœ˜—Kšžœ˜K˜—Kšžœ ˜Kšœ˜—K˜šŸœžœ!žœFžœ˜€Kšœ@˜@šžœžœžœ˜Kšœ-˜-Kšœ3˜3Kšœ2˜2Kšœžœžœžœ ˜=Kšœžœ%˜7Kšœ[ΟcT˜―KšœI˜IKšœ˜Kšœ―˜―Kšœ+˜+Kšœžœ˜!šžœ0žœ˜8Kšœ*˜*Kšœžœ˜!Kšžœ˜K˜—šžœžœžœ˜Kšœ@˜@šžœžœžœ˜Kšœ3˜3Kšœ2˜2Kšœžœžœžœ ˜=Kšœžœ%˜7Kšœ[ T˜―Kšœ―˜―Kšœ)˜)Kšœžœ˜!K˜—Kšœ˜—Kšœ˜—Kšœ˜—K˜š Ÿ œžœžœžœžœžœ˜JKšœžœ"žœ˜4šžœžœž˜Kšœžœžœ˜Kšžœ˜ —K˜—K˜šŸ œžœžœžœžœžœžœ˜_Kšœ žœ?˜Nšžœžœžœ˜!šžœžœ˜Kšœžœ˜3šžœžœ˜"Kšœ!˜!Kšœžœ˜"Kšž˜Kšœ˜—K˜—Kšœ˜K˜—Kšœ˜—šŸ œžœžœžœžœžœžœ˜nKšœžœžœ˜Kšœ žœ?˜NKšœžœ/˜BKšœ žœžœ1žœ.˜‚Kšœ žœžœ/žœ,˜~šžœ žœ˜šžœžœ˜Kšœ)˜)šžœžœ˜!Kšœžœžœ˜Kšžœ žœ,˜