fudgets (empty) → 0.18.3
raw patch · 374 files changed
+26265/−0 lines, 374 filesdep +arraydep +basedep +containerssetup-changed
Dependencies added: array, base, containers, directory, fudgets, old-time, parallel, process, random, time, unix
Files
- COPYRIGHT +12/−0
- Contrib/AuxShellF.hs +31/−0
- Contrib/BitmapF.hs +52/−0
- Contrib/CompletionStringF.hs +104/−0
- Contrib/ConnectF.hs +58/−0
- Contrib/ContribFudgets.hs +51/−0
- Contrib/DynRadioGroupF.hs +19/−0
- Contrib/EndButtonsF.hs +19/−0
- Contrib/FilePickPopupF.hs +239/−0
- Contrib/FileShellF.hs +146/−0
- Contrib/HandleF.hs +92/−0
- Contrib/HelpBubbleF.hs +56/−0
- Contrib/HyperGraphicsF2.hs +132/−0
- Contrib/KeyGfx.hs +34/−0
- Contrib/LinearSplitP.hs +64/−0
- Contrib/MenuBarF.hs +199/−0
- Contrib/MeterF.hs +33/−0
- Contrib/ReactionM.hs +51/−0
- Contrib/ReactiveF.hs +9/−0
- Contrib/ShapedButtonsF.hs +298/−0
- Contrib/SmileyF.hs +28/−0
- Contrib/SocketServer.hs +41/−0
- Contrib/SplitF.hs +39/−0
- Contrib/SuperMenuF.hs +239/−0
- Contrib/TitleShellF.hs +26/−0
- Contrib/TreeBrowser.hs +144/−0
- Contrib/TypedSockets.hs +44/−0
- Demos/Mandelbrot/Explore.hs +82/−0
- Demos/Mandelbrot/Mandelbrot.hs +30/−0
- Demos/SpaceInvaders/BitmapOps.hs +44/−0
- Demos/SpaceInvaders/GUI.hs +184/−0
- Demos/SpaceInvaders/InvaderTypes.hs +18/−0
- Demos/SpaceInvaders/MainF.hs +34/−0
- Demos/SpaceInvaders/Metrics.hs +16/−0
- Demos/SpaceInvaders/Pics.hs +39/−0
- Demos/SpaceInvaders/Pics1.hs +93/−0
- Demos/SpaceInvaders/ReadPic.hs +16/−0
- Demos/SpaceInvaders/ScoreF.hs +20/−0
- Demos/SpaceInvaders/SpaceInvaders2.hs +8/−0
- Demos/SpaceInvaders/WorldF.hs +490/−0
- Demos/Tiles/BoardF.hs +53/−0
- Demos/Tiles/ChoiceF.hs +31/−0
- Demos/Tiles/DesignF.hs +74/−0
- Demos/Tiles/DrawingF.hs +107/−0
- Demos/Tiles/Main.hs +38/−0
- Demos/Tiles/MyUtils.hs +11/−0
- Demos/Tiles/RadioDrawF.hs +44/−0
- Demos/Tiles/Tiles.hs +83/−0
- Demos/Tiles/ToggleDrawGroupF.hs +24/−0
- Demos/Tiles/ToolsF.hs +46/−0
- Demos/clock/ClockF.hs +141/−0
- Demos/clock/fudgetclock.hs +5/−0
- Demos/graph/Compat.hs +18/−0
- Demos/graph/Diff.hs +42/−0
- Demos/graph/Eval.hs +28/−0
- Demos/graph/Exp.hs +29/−0
- Demos/graph/ExpF.hs +42/−0
- Demos/graph/Graph.hs +46/−0
- Demos/graph/Lex.hs +23/−0
- Demos/graph/Ops.hs +87/−0
- Demos/graph/Parser.hs +64/−0
- Demos/graph/Parsop.hs +83/−0
- Demos/graph/PlotF.hs +201/−0
- Demos/graph/Root.hs +23/−0
- Demos/graph/Show.hs +57/−0
- Demos/graph/Simp.hs +61/−0
- Demos/graph/UserCoords.hs +41/−0
- Demos/graph/ZoomF.hs +84/−0
- Demos/life/Generate.hs +17/−0
- Demos/life/Life.hs +40/−0
- Demos/life/Main.hs +31/−0
- Demos/life/Panel.hs +20/−0
- Demos/life/Timer.hs +6/−0
- Demos/life/Utils2.hs +20/−0
- Demos/mines/Box.hs +59/−0
- Demos/mines/FUtil.hs +35/−0
- Demos/mines/MineField.hs +186/−0
- Demos/mines/Pics.hs +200/−0
- Demos/mines/XMine.hs +60/−0
- Demos/paint/GraphF.hs +84/−0
- Demos/paint/Paint.hs +63/−0
- Examples/FancyHello.hs +26/−0
- Examples/StopWatch.hs +23/−0
- Examples/texteditor.hs +6/−0
- README.md +71/−0
- Setup.hs +2/−0
- fudgets.cabal +539/−0
- hsrc/AllFudgets.hs +33/−0
- hsrc/Fudgets.hs +259/−0
- hsrc/combinators/BranchF.hs +70/−0
- hsrc/combinators/Combinators.hs +19/−0
- hsrc/combinators/CompF.hs +72/−0
- hsrc/combinators/CompFfun.hs +61/−0
- hsrc/combinators/ContDynF.hs +27/−0
- hsrc/combinators/DynListF.hs +40/−0
- hsrc/combinators/InputF.hs +29/−0
- hsrc/combinators/ListF.hs +74/−0
- hsrc/combinators/LoopCompF.hs +30/−0
- hsrc/combinators/LoopLow.hs +46/−0
- hsrc/combinators/Loops.hs +76/−0
- hsrc/combinators/NullF.hs +87/−0
- hsrc/combinators/ParF.hs +10/−0
- hsrc/combinators/ProdF.hs +8/−0
- hsrc/combinators/Route.hs +13/−0
- hsrc/combinators/SerCompF.hs +87/−0
- hsrc/combinators/StateMonads.hs +100/−0
- hsrc/combinators/TreeF.hs +19/−0
- hsrc/containers/BubbleF.hs +86/−0
- hsrc/containers/Containers.hs +21/−0
- hsrc/containers/DShellF.hs +106/−0
- hsrc/containers/Dlayout.hs +142/−0
- hsrc/containers/DragF.hs +250/−0
- hsrc/containers/FreeGroupF.hs +56/−0
- hsrc/containers/PopupF.hs +53/−0
- hsrc/containers/PopupGroupF.hs +66/−0
- hsrc/containers/PosPopupShellF.hs +45/−0
- hsrc/containers/RootWindowF.hs +50/−0
- hsrc/containers/ScrollF.hs +181/−0
- hsrc/containers/SelectionF.hs +109/−0
- hsrc/containers/Shells.hs +42/−0
- hsrc/debug/Debug.hs +5/−0
- hsrc/debug/Maptrace.hs +10/−0
- hsrc/debug/ShowCommandF.hs +43/−0
- hsrc/debug/ShowFailure.hs +6/−0
- hsrc/debug/SpyF.hs +22/−0
- hsrc/defaults/DefaultParams.hs +8/−0
- hsrc/defaults/FDefaults.hs +57/−0
- hsrc/defaults/defaults.h +33/−0
- hsrc/doRequest.hs +17/−0
- hsrc/drawing/BitmapDrawing.hs +35/−0
- hsrc/drawing/Color.hs +71/−0
- hsrc/drawing/Convgc.hs +32/−0
- hsrc/drawing/Cursor.hs +22/−0
- hsrc/drawing/Drawing.hs +76/−0
- hsrc/drawing/DrawingModules.hs +42/−0
- hsrc/drawing/DrawingOps.hs +226/−0
- hsrc/drawing/DrawingUtils.hs +103/−0
- hsrc/drawing/Expose.hs +27/−0
- hsrc/drawing/FixedDrawing.hs +35/−0
- hsrc/drawing/FlexibleDrawing.hs +141/−0
- hsrc/drawing/Font.hs +194/−0
- hsrc/drawing/FontProperty.hs +27/−0
- hsrc/drawing/GCAttrs.hs +277/−0
- hsrc/drawing/GCtx.hs +38/−0
- hsrc/drawing/Gc.hs +26/−0
- hsrc/drawing/Graphic.hs +51/−0
- hsrc/drawing/Graphic2Pixmap.hs +31/−0
- hsrc/drawing/LoadFont.hs +72/−0
- hsrc/drawing/Pixmap.hs +30/−0
- hsrc/drawing/PixmapGen.hs +43/−0
- hsrc/drawing/TextExtents.hs +12/−0
- hsrc/drawing/TransCoord.hs +23/−0
- hsrc/exists.h +33/−0
- hsrc/filters/DoubleClickF.hs +27/−0
- hsrc/filters/Filters.hs +15/−0
- hsrc/filters/FocusMgr.hs +179/−0
- hsrc/filters/NewCache.hs +64/−0
- hsrc/filters/ShapeGroupMgr.hs +75/−0
- hsrc/fudgets/BellF.hs +9/−0
- hsrc/fudgets/Border3dF.hs +146/−0
- hsrc/fudgets/ButtonBorderF.hs +95/−0
- hsrc/fudgets/ButtonF.hs +40/−0
- hsrc/fudgets/ButtonGroupF.hs +121/−0
- hsrc/fudgets/DButtonF.hs +66/−0
- hsrc/fudgets/DDisplayF.hs +200/−0
- hsrc/fudgets/DRadioF.hs +39/−0
- hsrc/fudgets/DStringF.hs +44/−0
- hsrc/fudgets/DToggleButtonF.hs +35/−0
- hsrc/fudgets/DialogF.hs +133/−0
- hsrc/fudgets/Edit.hs +362/−0
- hsrc/fudgets/Editor.hs +214/−0
- hsrc/fudgets/Edtypes.hs +12/−0
- hsrc/fudgets/FilePickF.hs +64/−0
- hsrc/fudgets/GcWarningF.hs +43/−0
- hsrc/fudgets/GraphicsF.hs +576/−0
- hsrc/fudgets/GuiElems.hs +72/−0
- hsrc/fudgets/HyperGraphicsF.hs +76/−0
- hsrc/fudgets/InputEditorF.hs +40/−0
- hsrc/fudgets/LabelF.hs +28/−0
- hsrc/fudgets/MenuButtonF.hs +44/−0
- hsrc/fudgets/MenuF.hs +254/−0
- hsrc/fudgets/MenuPopupF.hs +117/−0
- hsrc/fudgets/MoreF.hs +65/−0
- hsrc/fudgets/MoreFileF.hs +44/−0
- hsrc/fudgets/OnOffDispF.hs +30/−0
- hsrc/fudgets/PopupMenuF.hs +90/−0
- hsrc/fudgets/PushButtonF.hs +21/−0
- hsrc/fudgets/QuitButtonF.hs +21/−0
- hsrc/fudgets/QuitF.hs +19/−0
- hsrc/fudgets/RadioF.hs +49/−0
- hsrc/fudgets/StringF.hs +339/−0
- hsrc/fudgets/TerminalF.hs +130/−0
- hsrc/fudgets/TextF.hs +300/−0
- hsrc/fudgets/ToggleButtonF.hs +37/−0
- hsrc/fudgets/ToggleGroupF.hs +25/−0
- hsrc/ghc-dialogue/AsyncInput.hs +415/−0
- hsrc/ghc-dialogue/CSizes.hs +6/−0
- hsrc/ghc-dialogue/CString16.hs +16/−0
- hsrc/ghc-dialogue/ContinuationIO.hs +169/−0
- hsrc/ghc-dialogue/DialogueIO.hs +21/−0
- hsrc/ghc-dialogue/DoRequest.hs +141/−0
- hsrc/ghc-dialogue/DoXCommand.hs +366/−0
- hsrc/ghc-dialogue/DoXRequest.hs +488/−0
- hsrc/ghc-dialogue/EncodeEvent.hs +261/−0
- hsrc/ghc-dialogue/IOUtil.hs +39/−0
- hsrc/ghc-dialogue/Marshall.hs +187/−0
- hsrc/ghc-dialogue/MyForeign.hs +93/−0
- hsrc/ghc-dialogue/PQueue.hs +16/−0
- hsrc/ghc-dialogue/P_IO_data.hs +172/−0
- hsrc/ghc-dialogue/StructFuns.hs +26/−0
- hsrc/ghc-dialogue/XCallTypes.hs +116/−0
- hsrc/ghc-dialogue/Xlib.hs +344/−0
- hsrc/ghc-dialogue/asyncinput.h +41/−0
- hsrc/ghc-dialogue/ccalls.h +208/−0
- hsrc/ghc-dialogue/cfundefs.h +50/−0
- hsrc/ghc-dialogue/cfuns.c +4/−0
- hsrc/ghc-dialogue/cfuns.h +11/−0
- hsrc/ghc-dialogue/cimports.h +41/−0
- hsrc/ghc-dialogue/csizes.h +19/−0
- hsrc/ghc-dialogue/newstructfuns.h +17/−0
- hsrc/ghc-dialogue/structs.h +57/−0
- hsrc/ghc/DFudIO.hs +33/−0
- hsrc/ghc/DialogueSpIO.hs +55/−0
- hsrc/ghc/FudIO.hs +16/−0
- hsrc/ghc/GetModificationTime.hs +14/−0
- hsrc/ghc/GetTime.hs +14/−0
- hsrc/ghc/HbcWord.hs +15/−0
- hsrc/ghc/List2.hs +3/−0
- hsrc/ghc/LowLevel.hs +12/−0
- hsrc/ghc/PackedString.hs +22/−0
- hsrc/ghc/ShowFun.hs +9/−0
- hsrc/ghc/SpIO.hs +50/−0
- hsrc/ghc/UnsafePerformIO.hs +3/−0
- hsrc/hbc_library/FudUTF8.hs +34/−0
- hsrc/infix/CompOps.hs +48/−0
- hsrc/infix/InfixOps.hs +8/−0
- hsrc/infix/LayoutOps.hs +11/−0
- hsrc/infix/OldLayoutOps.hs +27/−0
- hsrc/internals/CompiledGraphics.hs +145/−0
- hsrc/internals/DLValue.hs +16/−0
- hsrc/internals/DrawCompiledGraphics.hs +24/−0
- hsrc/internals/DrawCompiledGraphics1.hs +94/−0
- hsrc/internals/Editfield.hs +84/−0
- hsrc/internals/IntMemo.hs +36/−0
- hsrc/internals/IsRequest.hs +18/−0
- hsrc/internals/MGOps.hs +101/−0
- hsrc/internals/MeasuredGraphics.hs +123/−0
- hsrc/internals/PathTree.hs +182/−0
- hsrc/internals/Queue.hs +17/−0
- hsrc/internals/StringEdit.hs +51/−0
- hsrc/internals/Table.hs +23/−0
- hsrc/internals/Tables.hs +99/−0
- hsrc/internals/Tables2.hs +24/−0
- hsrc/internals/Tree234.hs +239/−0
- hsrc/internals/UndoStack.hs +27/−0
- hsrc/io/AppStorage.hs +20/−0
- hsrc/io/AsyncTransmitter.hs +117/−0
- hsrc/io/HaskellIO.hs +63/−0
- hsrc/io/InOut.hs +17/−0
- hsrc/io/IoF.hs +14/−0
- hsrc/io/OpenSocket.hs +28/−0
- hsrc/io/Process.hs +15/−0
- hsrc/io/ReadFileF.hs +40/−0
- hsrc/io/Socketio.hs +34/−0
- hsrc/io/StdIoUtil.hs +60/−0
- hsrc/io/TimerF.hs +37/−0
- hsrc/io/Transceivers.hs +13/−0
- hsrc/io/UnsafeGetDLValue.hs +13/−0
- hsrc/io/WriteFile.hs +18/−0
- hsrc/kernelutils/BgF.hs +21/−0
- hsrc/kernelutils/GetVisual.hs +9/−0
- hsrc/kernelutils/GetWindowProperty.hs +19/−0
- hsrc/kernelutils/GreyBgF.hs +85/−0
- hsrc/kernelutils/InternAtom.hs +35/−0
- hsrc/kernelutils/KernelUtils.hs +14/−0
- hsrc/kernelutils/MapstateK.hs +5/−0
- hsrc/kernelutils/ParK.hs +52/−0
- hsrc/kernelutils/QueryPointer.hs +15/−0
- hsrc/kernelutils/QueryTree.hs +45/−0
- hsrc/kernelutils/QuitK.hs +61/−0
- hsrc/kernelutils/ShapeK.hs +55/−0
- hsrc/kernelutils/SimpleF.hs +48/−0
- hsrc/layout/AlignP.hs +35/−0
- hsrc/layout/Alignment.hs +12/−0
- hsrc/layout/AutoLayout.hs +352/−0
- hsrc/layout/AutoPlacer.hs +77/−0
- hsrc/layout/CondLayout.hs +32/−0
- hsrc/layout/DynListLF.hs +34/−0
- hsrc/layout/DynSpacerF.hs +18/−0
- hsrc/layout/HorizontalAlignP.hs +96/−0
- hsrc/layout/Layout.hs +29/−0
- hsrc/layout/LayoutDir.hs +35/−0
- hsrc/layout/LayoutDoNow.hs +27/−0
- hsrc/layout/LayoutF.hs +52/−0
- hsrc/layout/LayoutHints.hs +15/−0
- hsrc/layout/LayoutRequest.hs +81/−0
- hsrc/layout/LayoutSP.hs +125/−0
- hsrc/layout/Layoutspec.hs +60/−0
- hsrc/layout/MatrixP.hs +49/−0
- hsrc/layout/NameLayout.hs +193/−0
- hsrc/layout/ParagraphP.hs +51/−0
- hsrc/layout/Placer.hs +34/−0
- hsrc/layout/Placers.hs +84/−0
- hsrc/layout/Placers2.hs +72/−0
- hsrc/layout/Sizing.hs +14/−0
- hsrc/layout/SizingF.hs +47/−0
- hsrc/layout/Spacer.hs +17/−0
- hsrc/layout/Spacers.hs +112/−0
- hsrc/layout/TableP.hs +141/−0
- hsrc/layout/TryLayout.hs +16/−0
- hsrc/layout/UserLayoutF.hs +26/−0
- hsrc/lowlevel/Cont.hs +97/−0
- hsrc/lowlevel/Display.hs +17/−0
- hsrc/lowlevel/FudgetIO.hs +32/−0
- hsrc/lowlevel/Srequest.hs +48/−0
- hsrc/lowlevel/TagEvents.hs +180/−0
- hsrc/lowlevel/WindowF.hs +148/−0
- hsrc/lowlevel/Xcommand.hs +15/−0
- hsrc/lowlevel/Xrequest.hs +31/−0
- hsrc/sp/CompSP.hs +156/−0
- hsrc/sp/Dynforkmerge.hs +34/−0
- hsrc/sp/IdempotSP.hs +17/−0
- hsrc/sp/InputSP.hs +70/−0
- hsrc/sp/Loop.hs +69/−0
- hsrc/sp/Loopthrough.hs +79/−0
- hsrc/sp/ParSP.hs +21/−0
- hsrc/sp/SP.hs +8/−0
- hsrc/sp/SPmonad.hs +26/−0
- hsrc/sp/SPstateMonad.hs +23/−0
- hsrc/sp/SpEither.hs +19/−0
- hsrc/sp/Spinterp.hs +9/−0
- hsrc/sp/Spops.hs +96/−0
- hsrc/sp/StreamProc.hs +16/−0
- hsrc/sp/StreamProcIO.hs +14/−0
- hsrc/types/Direction.hs +3/−0
- hsrc/types/Drawcmd.hs +37/−0
- hsrc/types/Fudget.hs +44/−0
- hsrc/types/InputMsg.hs +41/−0
- hsrc/types/ListRequest.hs +31/−0
- hsrc/types/Message.hs +33/−0
- hsrc/types/Path.hs +30/−0
- hsrc/types/Popupmsg.hs +5/−0
- hsrc/types/Rects.hs +52/−0
- hsrc/types/Types.hs +11/−0
- hsrc/utils/CmdLineEnv.hs +63/−0
- hsrc/utils/Defaults.hs +56/−0
- hsrc/utils/EitherUtils.hs +51/−0
- hsrc/utils/FilePaths.hs +86/−0
- hsrc/utils/FudUtilities.hs +15/−0
- hsrc/utils/FudVersion.hs +7/−0
- hsrc/utils/Geometry.hs +106/−0
- hsrc/utils/HbcUtils.hs +44/−0
- hsrc/utils/MapstateMsg.hs +26/−0
- hsrc/utils/StringUtils.hs +17/−0
- hsrc/utils/Utils.hs +101/−0
- hsrc/xtypes/AuxTypes.hs +56/−0
- hsrc/xtypes/Command.hs +132/−0
- hsrc/xtypes/DrawInPixmap.hs +23/−0
- hsrc/xtypes/DrawInWindow.hs +24/−0
- hsrc/xtypes/DrawTypes.hs +44/−0
- hsrc/xtypes/Event.hs +122/−0
- hsrc/xtypes/EventMask.hs +37/−0
- hsrc/xtypes/FRequest.hs +34/−0
- hsrc/xtypes/Image.hs +7/−0
- hsrc/xtypes/ResourceIds.hs +44/−0
- hsrc/xtypes/Sockets.hs +68/−0
- hsrc/xtypes/Visual.hs +19/−0
- hsrc/xtypes/XDraw.hs +20/−0
- hsrc/xtypes/XStuff.hs +8/−0
- hsrc/xtypes/XTypesModules.hs +11/−0
- hsrc/xtypes/Xtypes.hs +164/−0
- xlib/fdzero.c +53/−0
- xlib/socketlib/defs.h +18/−0
- xlib/socketlib/inet.c +404/−0
+ COPYRIGHT view
@@ -0,0 +1,12 @@+The authors have the copyright to all files distributed as part of the+fudget library, except where an explicit copyright notice states+otherwise.++The files may be distributed and used free of charge for+non-commercial purposes only. Commercial use of the fudget library+requires an agreement with the authors.++This file should be included unchanged in all copies.+++Magnus Carlsson & Thomas Hallgren
+ Contrib/AuxShellF.hs view
@@ -0,0 +1,31 @@+module AuxShellF where+import Fudgets+import TitleShellF(wmShellF')++auxShellF = auxShellF' standard+delayedAuxShellF = delayedAuxShellF' standard++delayedAuxShellF' pm title fud =+ auxShellF' pm title fud >=^^< emptyDownSP+ where+ -- 3x3 state transition table:+ emptyDownSP = getPopSP emptyDownSP upSP downSP+ downSP x = getPopSP (downSP x) (msgSP x) downSP+ upSP = getPopSP emptyDownSP upSP msgSP++ msgSP x = putSP (Right x) upSP++ getPopSP downSP upSP msgSP = getSP $ either popSP msgSP+ where popSP b = putSP (Left b) $ if b then upSP else downSP++auxShellF' pm title fud =+ mapEither (const False) id >^=<+ wmShellF' (pm . setVisible False) title fud+ >=^< mapEither Right id++{-+auxShellF lbl title fud =+ loopThroughRightF+ (wmShellF' (setVisible False) title fud)+ (Right>^=<toggleButtonF lbl>=^<const False)+-}
+ Contrib/BitmapF.hs view
@@ -0,0 +1,52 @@+module BitmapF (bitmapButtonF, bitmapDispF, bitmapDispBorderF) where+import AllFudgets++windowKernel filename =+ allocNamedColorPixel defaultColormap "black" $ \fg ->+ allocNamedColorPixel defaultColormap "white" $ \bg ->+ changeBackPixel "white" $+ wCreateGC rootGC [GCFunction GXcopy,+ GCForeground fg,+ GCBackground bg,+ GCGraphicsExposures False] $ \drawGC ->+ let displayImage size bitmapid =+ createPixmap size copyFromParent (\pixmapid ->+ putsK [Low (pmCopyPlane pixmapid drawGC (Pixmap bitmapid) + (Rect (Point 0 0) size) (Point 0 0) 0),+ lxcmd (ChangeWindowAttributes [CWBackPixmap pixmapid]),+ lxcmd (FreePixmap bitmapid),+ lxcmd (FreePixmap pixmapid),+ Low (layoutRequestCmd (plainLayout size True True)),+ lxcmd ClearWindow] + displayproc)+ lxcmd = Low . XCmd+ displayproc =+ getK (\msg ->+ case msg of+ Low (XEvt (Expose _ 0)) -> xcommandK ClearWindow displayproc + High BitmapBad -> error ("Invalid bitmap file")+ High (BitmapReturn size _ bitmapid) -> displayImage size bitmapid+ _ -> displayproc)+ in readBitmapFile filename (\bmr ->+ case bmr of+ BitmapBad -> error ("Invalid bitmap file " ++ filename)+ BitmapReturn size _ bitmapid -> displayImage size bitmapid)++bitmapDispF :: FilePath -> F BitmapReturn a+bitmapDispF filename =+ let wattrs = [CWBackingStore WhenMapped, CWEventMask [ExposureMask]]+ kernelF = windowF ([XCmd $ ChangeWindowAttributes wattrs])+ (windowKernel filename)+ in marginHVAlignF 0 aCenter aCenter kernelF++bitmapDispBorderF :: Int -> FilePath -> F BitmapReturn a+bitmapDispBorderF width filename =+ let wattrs = [CWBackingStore WhenMapped, CWEventMask [ExposureMask]]+ kernelF = windowF [XCmd (ChangeWindowAttributes wattrs),+ XCmd (ConfigureWindow [CWBorderWidth width])]+ (windowKernel filename)+ in marginHVAlignF 0 aCenter aCenter kernelF++bitmapButtonF keys filename =+ let kernelF = bitmapDispBorderF 0 filename + in fromRight >^=< (pushButtonF keys kernelF)
+ Contrib/CompletionStringF.hs view
@@ -0,0 +1,104 @@+module CompletionStringF+ (stdcc,completeFromList,+ completionStringF,completionStringF',completionStringF'')+ where+import Fudgets+import Data.List(isPrefixOf) +import HbcUtils(mapSnd)++completionStringF = completionStringF' stdcc standard++stdcc = argReadKey "stdcc" ' ' -- standard completion char++completionStringF' cc cust = completionStringF'' cc cust >=^< mapEither id Right++completionStringF'' cc cust = -- cc = completion character+ loopThroughRightF (absF completeSP0) (stringF'' cust)+ where+ completeSP0 = completeSP (const []) ([],[]) ""++ completeSP listfun updownlist current =+ getSP $ either fromStringF fromOutside+ where+ list = listfun current++ same = completeSP listfun updownlist current+ newList listfun' = completeSP listfun' ([],[]) current+ newString' p s = putSP (toOutput (InputChange s)) $+ completeSP listfun p s+ newString = newString' ([],[])+++ toStringF'' = Left+ toString = toStringF'' . Right+ toCustomiser = toStringF'' . Left+ toOutput = Right . Right+ toCompletionList = Right . Left++ fromOutside = either newList inputToStringF''+ inputToStringF'' msg = putSP (toStringF'' msg) same++ fromStringF msg = + case msg of+ InputDone "Up" _ -> goto above+ InputDone "Down" _ -> goto below+ InputDone "Tab" _ -> doCompletion+ InputDone _ _ -> putSP (toOutput msg) same+ InputChange s ->+ if s==current++[cc]+ then doCompletion+ else if fromupdownlist s+ then same+ else newString s -- erase completion list?++ fromupdownlist s =+ case updownlist of+ (_,(_,s'):_) -> s==s'+ _ -> False++ goto (_,[]) = same+ goto l@(_,item@(_,s):_) =+ putSP (toString s) $+ putSP (toCompletionList [item]) $+ putSP (toOutput (InputChange s)) $+ newString' l current++ above = case updownlist of+ ([],[]) -> case reverse updownlist' of+ x:xs -> (xs,[x])+ _ -> ([],[])+ (x:xs,ys) -> (xs,x:ys)+ _ -> updownlist++ below = case updownlist of+ ([],[]) -> ([],updownlist')+ (xs,x1:x2:ys) -> (x1:xs,x2:ys)+ _ -> updownlist++ updownlist' = mapSnd (current++) list++ doCompletion =+ putSP (toCompletionList list) $+ putNewString (current++commonPrefix (map snd list))++ putNewString new =+ putSP (toString new) $+ putSP (toCustomiser (setCursorPos (length new))) $+ newString new++commonPrefix ((c:s):ss) =+ case filter ((/=[c]).take 1) ss of+ [] -> c:commonPrefix (s:map tail ss)+ _ -> []+commonPrefix _ = []++pos y xs =+ case [ix|ix@(i,x)<-number 0 xs,y `isPrefixOf` x] of+ [] -> (0,False)+ (i,x):_ -> (i,x==y)++completeFromList list current =+ [(current,compl)|(pre,compl)<-splits,pre==current]+ where+ splits = map (splitAt n) list+ n = length current
+ Contrib/ConnectF.hs view
@@ -0,0 +1,58 @@+module ConnectF where+import Fudgets(F,(>+<))++infixl :&:,>&<+++--leaf :: (o->h)->F i o->(F i o,o->h,i->i)+tagF handler fud = TagF fud handler id++--data TagF a b c = TagF a b c+data TagF i o h t = TagF (F i o) (o->h) (t i)+-- TagF makes the type more readable but also more restrictive...++tf1 >&< tf2 = compTagF (>+<) tf1 tf2++compTagF compF (TagF fud1 get1 tag1) (TagF fud2 get2 tag2) =+ TagF (compF fud1 fud2) (either get1 get2) (etag1 :&: etag2)+ where+ etag1 = extend Left tag1+ etag2 = extend Right tag2++mapTF f (TagF fud get tag) = TagF (f fud) get tag++ltr ih (TagF fud get tag) =+ (fud,either get ih,Right :&: extend Left tag)++class Tag f where+ extend :: (b->c) -> f b -> f c++data Tags f1 f2 a = (f1 a) :&: (f2 a)++instance Tag ((->) a) where+ extend = (.)++instance (Tag f1,Tag f2) => Tag (Tags f1 f2) where+ extend f (g1:&:g2) = extend f g1:&:extend f g2++{-+newtype Selector d a = S (d a->Maybe a)++instance Tag (Selector d) where+ extend f +++f d1 d2 = (either d1 no,either no d2)+ :: (d1 a -> Maybe a) ->+ (d2 b -> Maybe b) ->+ (Either (d1 a) (d2 b)->Maybe a,Either (d1 a) (d2 b)->Maybe b)++a->Maybe b -> Either a c -> Maybe b+-}++no _ = Nothing+yes s = Just s+left f = either f no+right = either no+leftleft = left . left+leftyes = left yes
+ Contrib/ContribFudgets.hs view
@@ -0,0 +1,51 @@+-- | Contributed add-ons to the Fudget Library+module ContribFudgets(+ -- * Contributed add-ons to the Fudget Library+-- module SuperMenuF,+ module BitmapF,+ module ShapedButtonsF,+-- module MenuBar,+ module TitleShellF,+ module AuxShellF,+ module SmileyF,+ module MenuBarF,+ module HelpBubbleF,+ module FileShellF,+ module FilePickPopupF,+ module CompletionStringF,+ module EndButtonsF,+ module MeterF,+ --module HandleF,+ --module LinearSplitP,+ module SplitF,+ module SocketServer,+ module TypedSockets,+ module HyperGraphicsF2,+ module ConnectF,+ module ReactiveF,+ module TreeBrowser+ ) where++import BitmapF+--import MenuBar+import ShapedButtonsF+import SuperMenuF() -- not exported because of name clashes, import SuperMenuF.+import TitleShellF+import AuxShellF+import SmileyF+import MenuBarF+import HelpBubbleF+import FileShellF+import FilePickPopupF+import CompletionStringF+import EndButtonsF+import MeterF+--import HandleF+--import LinearSplitP+import SplitF+import SocketServer+import TypedSockets+import HyperGraphicsF2+import ConnectF+import ReactiveF+import TreeBrowser
+ Contrib/DynRadioGroupF.hs view
@@ -0,0 +1,19 @@+module DynRadioGroupF where+import Fudgets++dynRadioGroupF alts startalt = dynRadioGroupF' standard alts startalt++dynRadioGroupF' pm alts startalt =+ loopThroughRightF (mapstateF ctrl (alts,startalt))+ (dynF (rgF alts startalt))+ where+ rgF = radioGroupF' pm++ ctrl (alts,current) = either fromRadioGroupF fromOutside+ where+ fromRadioGroupF choice = ((alts,choice),[Right (alts,choice)])+ fromOutside (alts',current') =+ ((alts',current'),+ if map fst alts' == map fst alts+ then [Left (Right current')]+ else [Left (Left (rgF alts' current'))])
+ Contrib/EndButtonsF.hs view
@@ -0,0 +1,19 @@+module EndButtonsF where+import AllFudgets++endButtonsF =+ noStretchF False True $ matrixF 2 (ok >+< cancel)+ where+ ok = buttonF "OK"+ cancel = buttonF' pm "Cancel"+ where+ pm = setKeys [([],"Escape")]+++endButtonsF' =+ noStretchF False True $ matrixF 2 (ok >+< cancel) >=^< Left+ where+ ok = buttonF'' standard "OK" >=^< Left . setLabel >=^^< idempotSP+ cancel = buttonF' pm "Cancel"+ where+ pm = setKeys [([],"Escape")]
+ Contrib/FilePickPopupF.hs view
@@ -0,0 +1,239 @@+module FilePickPopupF(filePickF,filePickF',filePickPopupF,filePickPopupF',filePickPopupOptF,filePickPopupOptF',startDir,aFilePath,popup) where+import AllFudgets+import EndButtonsF+--import Files+import Data.List(sort,partition)+import HbcUtils(uncurry3)+import DialogueIO hiding (IOError)+import CompletionStringF+import UnsafePerformIO(unsafePerformIO)+import System.Directory(getCurrentDirectory)++popup = ("OK",Nothing)++filePickPopupF = filePickPopupF' noextrabuttons+filePickPopupOptF = filePickPopupOptF' noextrabuttons+filePickF = filePickF' noextrabuttons++noextrabuttons = [] :: ([(AFilePath->AFilePath,KeySym,String)])++filePickPopupF' btns = mapFilterSP ok >^^=< filePickPopupOptF' btns+ where+ ok (x,Nothing) = Nothing+ ok (x,Just y) = Just (x,y)+++filePickPopupOptF' btns =+ --delayF $ -- commented out to avoid a layout problem under XQuartz+ popupShellF "File Selection" Nothing (filePickF' btns >=^< snd)+++filePickF' btns =+ loopThroughRightF (ctrlF (aFilePath startDir,"")) (partsF btns)+ where+ ctrlF st@(dir,file) = getF $ either internal external+ where+ same = ctrlF st++ internal = either (either dirDisp goto) (either fileInput done)++ external (lbl,optpath) = putF (toButtons lbl) (external2 optpath)+ where+ external2 Nothing = putF (toDirDispDir dir) same+ external2 (Just s) = newpath (aFilePath s)++ dirDisp = either pick dirList+ dirList list = putF (toFileCompletion (completeFromList (map fst list))) same++ pick inp =+ pathPartsF (compactPath path) $ \ st'@(dir',file') ->+ if file'==""+ then change (dir',file) -- keep previous file name+ else case inputDone inp of+ Nothing -> change st'+ Just _ -> if file'==file -- Hmm. Check dir too.+ then output path+ else same -- false double click+ where+ path = stripInputMsg inp++ goto f = change (f dir,file)++ fileInput = either completionList filename++ completionList = flip putF same . toDirDispCompletions++ filename inp =+ case inputDone inp of+ Nothing -> ctrlF (dir,stripInputMsg inp)+ Just "" -> same+ --Just name@('/':_) -> newname (aFilePath name)+ --Just name -> newname (extendPath dir name)+ Just path' -> newname (joinPaths dir (aFilePath path'))+ where+ newname path =+ pathPartsF (compactPath path) $ \ st'@(dir',file') ->+ if file'==""+ then change st'+ else output (extendPath dir' file')++ done = either ok cancel+ where+ ok _ = putF (out (Just (filePath (extendPath dir file)))) same+ cancel _ = putF (out Nothing) same++ newpath path = pathPartsF (compactPath path) change++ change st@(dir',file') =+ putsF ([toFileInput file']+++ (if dir'/=dir then [toDirDispDir dir'] else [])) $+ ctrlF st++ output path =+ putF (out (Just (filePath path'))) (newpath path')+ where+ path' = compactPath path++ out = Right+ toDirDisp = Left. Left. Left+ toDirDispDir = toDirDisp. Right+ toDirDispCompletions = toDirDisp. Left+ toFileInput= Left. Right. Left. Right+ toFileCompletion=Left. Right. Left. Left+ toButtons=Left. Right. Right++partsF btns =+ vBoxF ((dirDispF>+<gotoButtonsF btns)>+<(fileInputF>+<endButtonsF'))++dirDispF =+ stripEither >^=< vBoxF (pathDispF >+< dirListF) >=^^< concatMapSP pre+ where+ pre (Left completions) = [Right (Left completions)]+ pre (Right path) = [Left newdir,Right (Right newdir)]+ where newdir = filePath path++ pathDispF = displayF' pm+ where pm = setAlign aCenter.+ setBgColor bgColor.+ setBorderWidth 0.+ setFont labelFont++ dirListF = loopThroughRightF (mapstateF ctrl []) (pickListF fst >+< lsF)+ where+ ctrl list = either (either fromPickListF fromLsF) fromInput+ where+ fromInput = either completions newDir+ completions cs = put (toPickListF hilite)+ where+ hilite = highlightItems+ [i|(i,(n,_))<-zip [0..] list,n `elem` ns]+ ns = [pre++compl|(pre,compl)<-cs]+ newDir = put . toLsF+ fromPickListF msg =+ put2 (outPick . mapInp (snd.snd) $ msg)+ (toPickListF.highlightItems.(:[]).fst.stripInputMsg $ msg)+ fromLsF list' = (list',[outDir list',toPickListF (replaceAll list')])++ put x = (list,[x])+ put2 x y = (list,[x,y])++ out = Right+ outDir = out . Right+ outPick = out . Left+ loop = Left+ toPickListF = loop . Left+ toLsF = loop . Right++ lsF = showFilesF>==<paths>^=<readDirF+ where+ paths (dir,resp) =+ case resp of+ Right files -> (map (extendPath sdir) . sortFiles) files+ Left err -> [extendPath sdir (show err)]+ where sdir = aFilePath dir+ sortFiles files =+ case partition isDotFile files of+ (dfs,fs) -> sort fs +++ sort [ f | f<-dfs, f `notElem` [".",".."]]+ isDotFile ('.':_) = True+ isDotFile _ = False++ showFilesF = contMapF showFiles+ showFiles = conts showFile+ showFile = if argFlag "slowshowfile" True+ then slowShowFile+ else fastShowFile++ slowShowFile path c =+ isDirF (filePath path)+ (c (file++"/",path))+ (c (file,path))+ where file = pathTail path++ fastShowFile path c = c (pathTail path,path)++gotoButtonsF btns =+ haskellIOF (GetEnv "HOME") $ \ homeresp ->+ noStretchF False True $+ matrixF 4 (untaggedListF ([rootF,parentF]++homeF homeresp++extra btns))+ where+ rootF = fButtonF (const rootPath) "r" "/ Root"+ parentF = fButtonF (compactPath.flip extendPath "..") "p" ".. Parent"++ homeF resp=+ case resp of+ Str d@(_:_) -> [fButtonF (const (aFilePath d)) "h" "Home"]+ _ -> []++ fButtonF f k lbl = const f >^=< buttonF' (setKeys [([metaKey],k)]) lbl++ extra = map (uncurry3 fButtonF)++fileInputF = "File" `labLeftOfF` completionStringF++pathPartsF path cont =+ isDirF (filePath path) yes no+ where+ yes = cont (path,"")+ no = cont (pathHead path,pathTail path)+ {-+ no = case path of+ [] -> cont ([],[]) -- not likely to happen, since the root is a dir+ file:dir -> cont (dir,file)+ -}+++--- Candidates for inclusion in the Fudget library:++isDirF file yes no =+ haskellIOF (StatusFile file) $ \ resp ->+ case resp of+ Str ('d':_) -> yes+ _ -> no++contMapF f =+ getF $ \ x ->+ f x $ \ y ->+ putF y $+ contMapF f++----++-- #ifdef __NHC__+--startDir = argKey "startdir" "/" -- hmm. should retreive current directory.+-- #else+startDir = unsafePerformIO getCurrentDirectory+-- #endif++{-+ - reloadknapp?+ - alltid absolut path+ - meddelande för att+ välja kataloger+ spara++ - completion och uppnerpilar+ -++ - pixlar kvar i picklistan+-}
+ Contrib/FileShellF.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE CPP #-}+module FileShellF(+#ifndef __NHC__+ fileShellF,fileShellF',+ textFileShellF,textFileShellF',+ showReadFileShellF,showReadFileShellF'+#endif+ ) where+import Fudgets+import FilePickPopupF+import TitleShellF(titleShellF')+import MenuBarF+#ifndef __NHC__+ (menuBarF,menu,idT,item,cmdItem,key)+#endif+import DialogueIO+import Prelude hiding (IOError)+import Data.Maybe(isJust,fromJust,fromMaybe)+import Data.Char(isSpace)++#ifndef __NHC__++textFileShellF = textFileShellF' standard+textFileShellF' customiser = fileShellF' customiser textConv+ where textConv = (id,Right,Just "")++showReadFileShellF empty = showReadFileShellF' standard empty+showReadFileShellF' customiser empty =+ fileShellF' customiser (show,parse,empty)+ where+ parse contents =+ case reads contents of+ [(x,cs)] | all isSpace cs -> Right x+ _ -> Left "Syntax error in input"++++fileShellF = fileShellF' standard++fileShellF' customiser conv title0 appF =+ stubF $ loopOnlyF $ titleShellF' customiser title0 mainF+ where+ mainF = ctrlF title0 conv >==<+ (popupsF>+<vBoxF (fileShellMenuBarF hasNew>+<appF))+ where hasNew = case conv of (_,_,e) -> isJust e++ popupsF = filePickPopupF' >+<(messagePopupF>+<nullF{-confirmPopupF-})+ where+ filePickPopupF' = putsF (map f (take 1 args)) filePickPopupF+ f x = ((Open,popup),x)+++messageF = putF . toMessage+toFilePick = Right . Left . Left+toMessage = Right . Left . Right . Left+--toConfirm = Right . Left . Right . Left+toApp = Right . Right . Right+toTitle = Left++ctrlF title0 (show,parse,optEmpty) = start+ where+ start = loop Nothing Nothing+ changeTitle name = putF (toTitle (title0++": "++name))+ loop filename document =+ getF $ {-either quitMsg-} (either fromPopups (either fromMenu fromApp))+ where+ same = loop filename document+ newName name document' = changeTitle name $ loop (Just name) document'+ errMsg err = messageF err same++ quitMsg () = terminateProgram++ fromPopups = either fromFilePick (either fromMessage fromConfirm)+ fromMessage _ = same+ fromConfirm _ = same -- !!++ fromMenu filecmd =+ case filecmd of+ Open -> putF (toFilePick (Open,("Open",Nothing))) same+ Save -> flip (maybe same) document $ \ doc ->+ flip (maybe (fromMenu SaveAs)) filename $ \ name ->+ saveF show name doc errMsg $+ same+ SaveAs -> flip (maybe same) document $ \ _ ->+ putF (toFilePick (SaveAs,("Save",Just (fromMaybe "" filename)))) same+ Quit -> terminateProgram+ New -> flip (maybe $ errMsg "New not implemented") optEmpty $ \empty ->+ changeTitle "Empty file" $+ putF (toApp empty) $+ start+ _ -> same++ terminateProgram = hIOSuccF (Exit 0) same++ fromFilePick ((action,_),filename) =+ case action of+ Open -> openF parse filename errMsg+ (\ contents ->+ putF (toApp contents) $+ newName filename (Just contents))+ SaveAs -> saveF show filename (fromJust document) errMsg $+ newName filename document+ _ -> undefined -- shouldn't happen++ fromApp inpmsg =+ case inputDone inpmsg of+ Just doc ->+ case filename of+ Just name -> saveF show name doc errMsg $+ loop filename (Just doc)+ Nothing -> putF (toFilePick (SaveAs,("Save",filename))) $+ loop filename (Just doc)+ Nothing -> loop filename (Just (stripInputMsg inpmsg))+++data FileMenuItem = New | Open | Save | SaveAs | Quit deriving (Eq)+++fileShellMenuBarF hasNew =+ fromLeft >^=< hBoxF (fileMenuF hasNew >+< gcWarnF) >=^< Left+ where gcWarnF = spacer1F (hvAlignS aRight aCenter) gcWarningF++fileMenuF hasNew =+ spacer1F (noStretchS True True `compS` leftS) (menuBarF menuBar)+ where+ menuBar = [item fileMenu "File"] -- more?+ fileMenu = menu idT $+ (if hasNew then (cmdItem New "New":) else id)+ [cmdItem Open "Open..." `key` "o",+ cmdItem Save "Save" `key` "s",+ cmdItem SaveAs "Save As..." `key` "a",+ cmdItem Quit "Quit" `key` "q" ]++saveF showdoc filename doc errcont cont =+ hIOerrF (WriteFile filename (showdoc doc))+ (errcont.show)+ (const cont)++openF parse filename errcont cont =+ hIOerrF (ReadFile filename) (errcont.show) $ \ (Str contents) ->+ either errcont cont (parse contents)++--messageF msg = contDynF $ (startupF [msg] messagePopupF>=^^<nullSP)+-- contDynF doesn't seem to work properly++#endif
+ Contrib/HandleF.hs view
@@ -0,0 +1,92 @@+module HandleF(hHandleF,vHandleF) where+import AllFudgets++hHandleF = handleF' Horizontal 108+vHandleF = handleF' Vertical 116++sepSize = max 2 defaultSep -- !! see note about layoutreq below+sepD dir =+ -- the size of the drawing must be sepSize (in the dir direction)+ placedD (margS d (d2-d) `spacerP` linearP dir 0) $+ boxD [fgD [shadowColor,"black"] l,fgD [shineColor,"white"] l]+ where l = g line+ d2 = sepSize-2+ d = d2 `div` 2++ margS = colinear dir hMarginS vMarginS+ line = colinear dir vFiller hFiller 1++handleF' dir cur alignment =+ --showCommandF "handleF" $+ nullSP >^^=<+ postMapLow post (groupF startcmds handleK0 (labelF (sepD dir)))+ >=^< Left+ --windowF startcmds handleK0+ where+ -- Hack: all layout requests must come from the same address, otherwise+ -- two boxes will be placed instead of one...+ post ([L],cmd@(LCmd _)) = ([R,R],cmd)+ post tcmd = tcmd++ startcmds =+ [--layoutRequestCmd layoutreq,+ XCmd $ ChangeWindowAttributes [CWEventMask eventmask,+ CWBackPixmap parentRelative]]++ eventmask = [ButtonPressMask,ButtonReleaseMask,ButtonMotionMask]++ -- It's important that the size of sepD and this request agree!!+ layoutreq = plainLayout (diag sepSize) isHoriz (not isHoriz)+ isHoriz = dir==Horizontal+ wantposreq size p = layoutreq{wantedPos=Just(p,size,alignment)}++ handleK0 = + setFontCursor cur $+ handleK++ handleK = idleK 0 0+ where+ idleK parentp size = getK $ message low high+ where+ same = idleK parentp size+ high size' = idleK parentp size'+ low event =+ case event of+ XEvt ButtonEvent {type'=Pressed,rootPos=pabs} ->+ dragK parentp size (pabs-parentp) pabs+ LEvt (LayoutPos parentp') -> idleK parentp' size+ _ -> same++ dragK parentp size refp curp = getK $ message low high+ where+ moveto = dragK parentp size refp+ same = moveto curp+ putpos = putK . Low . layoutRequestCmd . wantposreq size++ high size' = dragK parentp size' refp curp++ low event =+ case event of+ LEvt (LayoutPos parentp') -> dragK parentp' size refp curp+ XEvt ButtonEvent {type'=Released,rootPos=curp0'} ->+ (if curp'==curp+ then id+ else putpos (curp'-refp)) $+ idleK parentp size+ where curp' = constrain size (curp0'-refp)+refp+ XEvt MotionNotify {rootPos=curp0',state=mods} ->+ if curp'==curp || Shift `elem` mods+ then same+ else putpos (curp'-refp) $+ moveto curp'+ where curp' = constrain size (curp0'-refp)+refp+ _ -> same++--constrain _ = id+--{-+-- Try to limit split position to reasonable values:+constrain size =+ if size>defaultSep+ then pmin (size-defaultSep) . pmax defaultSep+ else id+--}
+ Contrib/HelpBubbleF.hs view
@@ -0,0 +1,56 @@+module HelpBubbleF(helpBubbleF) where+import AllFudgets++data BubbleState = Idle | Armed | Up++helpBubbleF help fud =+ if useBubbles+ then loopCompThroughLeftF $+ groupF startcmds ctrlK0 ((timerF>+<bubbleF) >+< fud)+ else fud+ where+ bubbleF = bubbleRootPopupF (labelF' lblpm help)+ lblpm = setBgColor "white" . setFont helpFont+ eventmask = [EnterWindowMask,LeaveWindowMask]+ startcmds = [XCmd $ ChangeWindowAttributes [CWEventMask eventmask],+ XCmd $ ConfigureWindow [CWBorderWidth 0]]++ ctrlK0 = ctrlK 0 0 Idle++ toTimer = High . Left+ toBubble = High . Right++ ctrlK size pos bubbleState =+ getK $ message event (either fromTimer fromBubble)+ where+ same = ctrlK size pos bubbleState+ idle = ctrlK size pos Idle+ newSize size' = ctrlK size' pos bubbleState+ timerOff s = putK (toTimer Nothing) $ ctrlK size pos s+ timerOn pos' = putK (toTimer (Just (0,500))) $ ctrlK size pos' Armed++ fromBubble _ = same++ fromTimer Tick =+ case bubbleState of+ Armed ->+ putK (toBubble (Popup (pos+offset) ())) $+ timerOff Up+ where offset = pP (xcoord size `div` 2) 3+ _ -> same+ event e =+ --echoK (show e) $+ case e of+ XEvt EnterNotify { pos=pos,rootPos=rootPos } -> timerOn (rootPos-pos)++ XEvt LeaveNotify { } ->+ case bubbleState of+ Idle -> same+ Armed -> timerOff Idle+ Up -> putK (toBubble Popdown) $ idle++ LEvt (LayoutSize size') -> newSize size'+ _ -> same++useBubbles = argFlag "helpbubbles" True+helpFont = argKey "helpfont" "-*-new century schoolbook-medium-r-*-*-12-*-*-*-*-*-iso8859-1"
+ Contrib/HyperGraphicsF2.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE CPP #-}+module HyperGraphicsF2(+ module HyperGraphicsF2,+ GfxCommand(..),GfxChange(..),GfxEvent(..),replaceGfx,highlightGfx+ ) where+import AllFudgets+import Data.Maybe(fromJust,mapMaybe)+import HbcUtils(mapFst)+import qualified Data.Map as Map+--import Fudget+--import Defaults(paperColor)+--import InputMsg(inputDone)+--import Utils(swap)+--import Xtypes(ColorName)+--import Loops(loopThroughRightF)+--import SerCompF(mapstateF)+--import Graphic+--import Drawing+--import DrawingOps+--import GraphicsF+--import FDefaults+--import ListUtil(assoc)+--import Sizing(Sizing(..))+--import GCAttrs() -- instances+--import Event(Pressed(..))+--import Maptrace(ctrace) -- debugging+--import SpyF(teeF) -- debugging+--import CompOps((>==<)) -- debugging++#include "../hsrc/exists.h"++hyperGraphicsF2 x = hyperGraphicsF2' standard x++hyperGraphicsF2' custom init =+ loopThroughRightF+ (mapstateF ctrl state0)+ ({-teeF show "\n" >==<-} graphicsDispF' (custom . params))+ where+ --tr x = ctrace "hyper" (show x) x -- debugging+ params = setInitDisp init .+ setGfxEventMask [GfxButtonMask] .+ setSizing Dynamic+ state0 = (annotPaths init,init)++ ctrl state@(paths,drawing) = either gfxEvent gfxCommand+ where+ same = (state,[])+ lbl2path lbl = fromJust (Map.lookup lbl paths)++ gfxCommand lcmd =+ case mapGfxCommandPath lbl2path lcmd of+ cmd@(ChangeGfx changes) -> (changeState changes,[Left cmd])+ cmd -> (state,[Left cmd])+ where+ changeState changes = (paths',drawing')+ where+ drawing' = foldr replace drawing changes++ replace (path,GfxReplace (_,Just d)) drawing =+ replacePart drawing path d+ replace (path,GfxReplace _) drawing = drawing+ replace (path,GfxGroup from count) drawing =+ updatePart drawing path (groupParts from count)+ replace (path,GfxUngroup pos) drawing =+ updatePart drawing path (ungroupParts pos)++ paths' = annotPaths drawing'+ -- Space leak: drawing' isn't used until user clicks+ -- in the window, so the old drawing is retained in+ -- the closure for drawing'++ gfxEvent msg = (state,[Right msg'])+ where+ msg' = mapGfxEventPath path2lbl msg++ path2lbl path = do let part = drawingAnnotPart drawing path+ LabelD a _ <- maybeDrawingPart drawing part+ return a++ annotPaths = Map.fromList . map swap . drawingAnnots++mouseClicksSP = mapFilterSP isMouseClick++isMouseClick msg =+ case msg of+ GfxButtonEvent { gfxType=Pressed, gfxPaths=(path,_):_ } -> Just path+ _ -> Nothing++---++mapGfxCommandPath f cmd =+ case cmd of+ ChangeGfx changes -> ChangeGfx (mapFst f changes)+ ShowGfx path a -> ShowGfx (f path) a+ GetGfxPlaces paths -> GetGfxPlaces (map f paths)+ -- _ -> cmd -- Operationally, the rest is the same as this line.+ ChangeGfxBg c -> ChangeGfxBg c+ ChangeGfxBgPixmap pm b -> ChangeGfxBgPixmap pm b+#ifdef USE_EXIST_Q+ ChangeGfxBgGfx gfx -> ChangeGfxBgGfx gfx+#endif+ ChangeGfxCursor cursor -> ChangeGfxCursor cursor+ ChangeGfxFontCursor shape -> ChangeGfxFontCursor shape+ BellGfx n -> BellGfx n+++mapGfxEventPath f event =+ case event of+ GfxButtonEvent t s ty b ps -> GfxButtonEvent t s ty b (mapPaths ps)+ GfxMotionEvent t s ps -> GfxMotionEvent t s (mapPaths ps)+ GfxKeyEvent t m k l -> GfxKeyEvent t m k l+ GfxFocusEvent b -> GfxFocusEvent b+ GfxPlaces rs -> GfxPlaces rs+ GfxResized s -> GfxResized s+ where+ -- mapPats :: [(a,(Point,Rect))] -> [(b,(Point,Rect))]+ mapPaths = mapMaybe f'+ -- f' :: (a,(Point,Rect)) -> Maybe (b,(Point,Rect))+ f' (path,place) = fmap (\p->(p,place)) (f path)++-- nullPath = null . gfxPaths -- would be ok if gfxPaths was a total function+nullPath = maybe False null . gfxEventPaths++gfxEventPaths event =+ case event of+ -- enumerate all constructors that have a path argument:+ GfxButtonEvent {gfxPaths=ps} -> Just ps+ GfxMotionEvent {gfxPaths=ps} -> Just ps+ _ -> Nothing++isGfxButtonEvent (GfxButtonEvent {gfxType=Pressed,gfxButton=b}) = Just b+isGfxButtonEvent _ = Nothing
+ Contrib/KeyGfx.hs view
@@ -0,0 +1,34 @@+module KeyGfx(keyGfx) where+import Fudgets+import Data.Char(toUpper)++keyGfx gfx k = hboxD' 12 [g gfx,keyD (keyCap k)]+ where+ keyD c = spacedD (hAlignS aRight `compS` hMarginS 0 3) $+ hboxD' 0 [diamondD,spacedD alignKeysS $ g c]+ diamondD = spacedD vCenterS $ g $ FlexD 10 False False d+ d (Rect p (Point w h)) = [FillPolygon Convex CoordModeOrigin+ [p+pP w2 0,p+pP w h2,p+pP w2 h,p+pP 0 h2]]+ where w2 = w `div` 2+ h2 = h `div` 2++alignKeysS = minSizeS (pP 12 10) `compS` hCenterS+ -- This is a hack to make the keybord shortcuts align nicely in a column.+ -- It assumes that no character is wider than 12 pixels.++--ctrlkey = argFlag "menuctrlkey" False++keyCap k =+ case k of+ [c] -> [toUpper c]+ "period" -> "."+ "comma" -> ","+ "plus" -> "+"+ "minus" -> "-"+ "slash" -> "/"+ "asterisk" -> "*"+ "apostrophe" -> "'"+ "question" -> "?"+ "less" -> "<"+ "greater" -> ">"+ _ -> k -- ??
+ Contrib/LinearSplitP.hs view
@@ -0,0 +1,64 @@+module LinearSplitP where+import AllFudgets+--import ListUtil(chopList)+import HbcUtils(apFst,chopList)+import Data.Maybe(isJust,listToMaybe)++horizontalSplitP = horizontalSplitP' defaultSep+verticalSplitP = verticalSplitP' defaultSep++horizontalSplitP' = linearSplitP Horizontal+verticalSplitP' = linearSplitP Vertical++linearSplitP dir sep = P linearSplitP'+ where+ linearSplitP' [] = linearP' []+ linearSplitP' [r] = linearP' [r]+ linearSplitP' reqs0 = (req,placer2)+ where+ reqss = chopReqs reqs0+ (reqs1,placers2) = unzip (fmap linearP' reqss)+ --reqs2 = zipWith adjSize (sizes reqss) reqs1+ (req,placer2a) = linearP' reqs1+ positions = fmap ( \ r->listToMaybe r >>= wantedPos) reqss+ placer2 r@(Rect _ s) =+ concat . zipWith id placers2 . adjPlaces s positions . placer2a $ r++ adjPlaces asize (_:ps) (r:rs) = adjPlaces' ps r rs+ where+ adjPlaces' (optp:ps) r1@(Rect p1 s1) (r2@(Rect p2 s2):rs) =+ case optp of+ Nothing -> r1:adjPlaces' ps r2 rs -- shouldn't happen+ Just (p0,s,a) -> r1' : adjPlaces' ps r2' rs+ where v = mkp dir d 0+ where+ d = max 1 (d0+d1)-d1 -- try to avoid sizes <= 0+ d0 = xc dir p-xc dir (rectpos r2)+ d1 = xc dir s1+ p = p0 + scalePoint a (asize-s)+ r1' = Rect p1 (s1+v)+ r2' = Rect (p2+v) (s2-v)+ adjPlaces' [] r [] = [r]+++ chopReqs = chopList splitReqs++ splitReqs (r:rs) = apFst (r:) (break wantPos rs)+ splitReqs [] = ([],[])++ wantPos = isJust . wantedPos++ linearP' = unP (linearP dir sep)++ {-+ adjSize Nothing req = req+ adjSize (Just s1) req@(Layout{minsize=s2}) =+ req{minsize=size, wAdj=const size, hAdj=const size}+ where size = mkp dir (xc dir s1) (yc dir s2)++ sizes = sizes' . (Just 0:) . tail . positions+ sizes' ps = zipWith size ps (tail ps++[Nothing])+ where size optp1 optp2 = do p1 <- optp1+ p2 <- optp2+ return (p2-p1-mkp dir sep 0)+ -}
+ Contrib/MenuBarF.hs view
@@ -0,0 +1,199 @@+{-# LANGUAGE CPP #-}+module MenuBarF(+#ifndef __NHC__+ menuF,menuBarF,MenuBar(..),Menu(..),MenuItem'(..),+ Item,item,item',key,itemValue,+ cmdItem,subMenuItem,toggleItem,sepItem,+ radioGroupItem,dynRadioGroupItem,+ delayedSubMenuItem,+ MenuItem(..),menu,Transl(..),idT,compT,+ menuIcon+#endif+ ) where+import Control.Monad((<=<))+import AllFudgets hiding (menuF)+import HbcUtils(mapFst)+--import MonadUtil((@@))+import DynRadioGroupF+import KeyGfx++#ifndef __NHC__+#include "../hsrc/exists.h"++tr x = ctrace "menubar" x x++--- Top level calls, eta expanded because of the monomorphism restriction+menuBarF menu = menuListF Horizontal menu+menuF menu = menuListF Vertical menu++type MenuBar a = Menu a+type Menu a = [MenuItem' a]+type Keys = [(ModState,KeySym)]++type MenuItem' a = Item (MenuItem a)++data Item a = Item a Gfx Keys+item i = item' [] i -- eta expanded because of the monomorphism restriction+item' k i g = Item i (G g) k+itemValue (Item a _ _) = a++key (Item a g _) k = Item a (G (keyGfx g k)) [([metaKey],k)]+ -- this creates some unnecessary nested G (G ..)++instance Graphic (Item a) where+ measureGraphicK (Item _ gfx _) = measureGraphicK gfx++instance Eq a => Eq (Item a) where+ Item x _ _ == Item y _ _ = x==y++cmdItem x = item . MenuCommand $ x -- eta expanded because of the monomorphism restriction+toggleItem tr = item . MenuToggle tr+subMenuItem tr = item . SubMenu False tr+delayedSubMenuItem tr = item . SubMenu True tr+radioGroupItem tr items = item . MenuRadioGroup tr items+dynRadioGroupItem tr items = item . MenuDynRadioGroup tr items+sepItem = item MenuLabel (padD 3 $ g $ hFiller 1)++data MenuItem a+ = MenuCommand a+ | MenuToggle (Transl Bool a) Bool+ | EXISTS(b) (Eq EQV(b)) => MenuRadioGroup (Transl EQV(b) a) [Item EQV(b)] EQV(b)+ | EXISTS(b) (Eq EQV(b)) => MenuDynRadioGroup (Transl ([Item EQV(b)],EQV(b)) a) [Item EQV(b)] EQV(b)+ | EXISTS(b) (Eq EQV(b)) => SubMenu Bool (Transl EQV(b) a) (Menu EQV(b))+ | MenuLabel++-- eta expanded because of the monomorphism restriction:+menu t = SubMenu False t++type MMsg a = Either MenuState a+type MF a b = F (MMsg a) (MMsg b)++data Transl l g = Transl (l->g) (g->Maybe l)++--- +menuItemF :: Eq a => LayoutDir -> MenuItem' a -> MF a a+menuItemF dir (Item item gfx keys) =+ case item of+ MenuCommand a -> translF (click a) (buttonF' (setAlign aLeft . pm) gfx)+ MenuToggle tr init ->+ translF tr (delayItF>==<startupF [init] (toggleButtonF' pm gfx))+ MenuRadioGroup tr items init ->+ translF tr (delayItF>==<gfx `labAboveF` radioGroupF' pm alts init)+ where alts = [(a,g)|Item a g _<-items]+ pm = setFont menuFont .+ setPlacer (verticalP' 0) -- (the default is verticalLeftP' 0)+ MenuDynRadioGroup tr items init ->+ translF tr' (delayItF>==<gfx `labAboveF` dynRadioGroupF' pm alts init)+ where alts = [(a,g)|Item a g _<-items]+ pm = setFont menuFont .+ setPlacer (verticalP' 0) -- (the default is verticalLeftP' 0)+ tr' = compT tr dynRadioT+ dynRadioT = Transl f g+ where+ f (alts,alt) = ([Item i g []|(i,g)<-alts],alt)+ g (items,alt) = Just ([(a,g)|Item a g _<-items],alt)++ SubMenu d tr m -> translMenuF tr (btnMenuF d dir gfx ({-delayF' d $-} subMenuF m))+ MenuLabel -> graphicsLabelF gfx+-- MenuDelayed item' -> delayF' $ menuItemF dir (Item item' gfx keys)+ where+ --pm = setKeys keys . setFont menuFont+ -- becuase of the mononorphism restriction:+ pm x = setKeys keys . setFont menuFont $ x++{-+ delayF' delayed =+ if delayed+ then delayF''+ else id++ delayF'' fud =+ if argFlag "teemenu" False+ then delayF fud >==< idRightF (teeF show "menuItemF: ")+ else delayF fud+-}++btnMenuF :: Bool -> LayoutDir -> Gfx -> F (MMsg a) a -> MF a a+btnMenuF delayed dir gfx mF =+ buttonMenuF' delayed dir menuFont agfx [] mF >=^< mapEither id Right+ where+ agfx = hboxcD' 3 [g gfx,g menuIcon]++translF (Transl f g) fud =+ Right . f >^=< fud >=^^< mapFilterSP (either (const Nothing) g)++translMenuF (Transl f g) fud =+ mapEither id f >^=< fud >=^^< idLeftSP (mapFilterSP g)++click a = Transl (const a) (\b->if a==b then Just Click else Nothing)+idT = Transl id (const Nothing)+--idT = Transl id Just -- why not this?+compT (Transl f1 g1) (Transl f2 g2) = Transl (f1 . f2) (g2 <=< g1)++-- There should be only one grabberF outside the top level menu.+menuListF :: Eq a => LayoutDir -> Menu a -> F a a+menuListF dir menu = grabberF (menuKeys menu) $ menuListF' dir menu+ where+ menuKeys :: Menu a -> [(a,Keys)]+ menuKeys = concatMap itemKeys+ itemKeys (Item m _ keys) =+ case m of+ SubMenu _ (Transl f _) menu -> mapFst f (menuKeys menu)+ MenuRadioGroup (Transl f _) items init ->+ [(f a,ks)|Item a _ ks<-items]+ --MenuCommand cmd -> [(cmd,keys)]+ --MenuToggle (Transl f _) init -> [(f init,keys)] -- hmm+ _ -> []++subMenuF :: Eq a => Menu a -> F (MMsg a) a+subMenuF menu = filterRightSP >^^=< menuListF' Vertical menu++menuListF' :: Eq a => LayoutDir -> Menu a -> MF a a+menuListF' dir m =+ loopLeftF $+ concatMapSP post >^^=< placerF (linearP dir 0) (listF nms)+ >=^^< concatMapSP pre+ where+ nms = [(i,menuItemF dir e) | (i,e) <- number 0 m]+ ns = map fst nms+ post (i,Right x) = [Right $ Right x]+ post (i,Left b) = [Right $ Left b,Left (i,b)]+ pre (Right (Right x)) = ctrace "menubar" "got input" [(i,Right x) | i<-ns]+ pre (Right (Left b)) = [(i,Left b) | i<-ns]+ pre (Left (j,b)) = [(i,Left b) | i<-ns, i/=j]++delayItF = idF+{-+delayItF = loopThroughRightF (absF idleSP) timerF+ where+ idleSP = getSP $ either (const idleSP) delaySP+ delaySP x = putSP (Left (Just (0,delay))) $ waitSP x+ waitSP x = getSP $ either doneSP waitSP+ where doneSP _ = putSP (Left Nothing) $ putSP (Right x) idleSP++ delay = argReadKey "delay" 200+-}++--- temporary hack:+{-+--subMenuF gfx mF = menuPopupF mF >==< throughF (buttonF agfx>=^^<nullSP)+menuPopupF mF =+ post >^=<+ inputPopupF "Menu" (inputMsg>^=<mF>=^^<filterRightSP) Nothing+ >=^< pre+ where+ pre cmd = (Nothing,Just cmd)+ post = snd+-}++menuIcon =+ FixD 12 [+ DrawRectangle (rR 1 0 8 10),+ DrawLine (lL 4 3 6 3),+ DrawLine (lL 4 5 6 5),+ DrawLine (lL 4 7 6 7),+ DrawLine (lL 3 11 10 11),+ DrawLine (lL 10 2 10 11)]+ ++#endif
+ Contrib/MeterF.hs view
@@ -0,0 +1,33 @@+module MeterF where+import AllFudgets+import Data.Ratio++meterF :: RealFrac v => InF v (Ratio Int) -- because of the monomorphism restr+meterF = meterF' standard++meterF' pm =+ post >^^=< border3dF True 1 (graphicsDispF' params) >=^< pre+ where+ params = pm .+ --setSizing Static .+ --setGfxEventMask [GfxButtonMask,GfxDragMask] .+ setBgColor meterBg .+ setFgColorSpec meterFg .+ setBorderWidth 0+ pre = Right . replaceAllGfx . meterD+ post = mapFilterSP pick+ pick (GfxButtonEvent {gfxType=Pressed,gfxPaths=p:_}) = change p+ pick (GfxButtonEvent {gfxType=Released,gfxPaths=p:_}) = done p+ pick (GfxMotionEvent {gfxPaths=p:_}) = change p+ pick _ = Nothing+ change = Just . inputChange . extr+ done = Just . inputMsg . extr+ extr (_,(p,Rect p0 s)) = xcoord (p-p0) % xcoord s++meterD r = FlexD (Point 50 5) False True drawfun+ where+ drawfun (Rect p (Point w h)) = [FillRectangle (Rect p (Point w' h))]+ where w' = scale r w++meterFg = colorSpec $ argKeyList "meterfg" ["blue2",fgColor,"black"]+meterBg = colorSpec $ argKeyList "meterbg" [bgColor,"white"]
+ Contrib/ReactionM.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE CPP #-}+module ReactionM where+import Data.Maybe(isJust)+import Control.Applicative+import Control.Monad(ap)+#if MIN_VERSION_base(4,12,0)+#if MIN_VERSION_base(4,13,0)+#else+import Control.Monad.Fail+#endif+#endif++-- | Writer & State & Exception monad+newtype ReactionM s o a = M (s -> [o] -> Maybe (s,[o],a))++instance Functor (ReactionM s o) where+ fmap f m = do x <- m; return (f x)++instance Applicative (ReactionM s o) where+ pure = return+ (<*>) = ap++instance Monad (ReactionM s o) where+ return x = M (\s o->Just (s,o,x))+ (M f1) >>= xm2 =+ M $ \ s0 o0 ->+ let r1 = f1 s0 o2+ Just (s1,o1,x1) = r1+ M f2 = xm2 x1+ r2 = f2 s1 o0+ Just (s2,o2,x2) = r2+ in if isJust r1 && isJust r2+ then Just (s2,o1,x2)+ else Nothing+#if MIN_VERSION_base(4,12,0)+instance MonadFail (ReactionM s o) where+#endif+ fail _ = rfail++react (M f) s0 = case f s0 [] of Just (s,o,_) -> (s,o); _ -> (s0,[])+put o = M $ \ s os -> Just (s,o:os,())+set s = M $ \ _ os -> Just (s,os,())+get = M $ \ s os -> Just (s,os,s)+field f = f <$> get+update f = M $ \ s os -> Just (f s,os,())++rfail = M $ \ _ _ -> Nothing++lift m = maybe rfail return m+nop = return ()+nop :: Monad m => m ()
+ Contrib/ReactiveF.hs view
@@ -0,0 +1,9 @@+-- | Program stateful abstract fudgets in a monadic style+module ReactiveF(reactiveF,reactiveSP,module ReactionM) where+import Fudgets+import ReactionM++reactiveF = mapstateF . mf+reactiveSP = mapstateSP . mf++mf rM s m = react (rM m) s
+ Contrib/ShapedButtonsF.hs view
@@ -0,0 +1,298 @@+module ShapedButtonsF (radioF1, radioGroupF1, toggleF1, toggleButtonF1, RBBT (..)) where+import AllFudgets+import HbcUtils(lookupWithDefault)++data RBBT = Circle | Square | Triangle+type RadioButtonBorderType = RBBT++radioF1 bbt fname alts startalt =+ radioGroupF1 bbt fname (map fst alts) startalt + (lookupWithDefault alts (error "radioF"))++radioGroupF1 :: Eq a => RadioButtonBorderType -> FontName -> [a] -> a -> + (a -> String) -> F a a+radioGroupF1 bbt fname alts startalt show_alt =+ let radioAlts = radioButtonsF1 bbt fname alts show_alt+ buttons = radioAlts >=^< stripEither+ in loopLeftF (excludeF1 startalt >==< buttons) >=^<+ (\x -> pair x True)++radioButtonsF1 bbt fname alts show_alt =+ let radiobutton alt =+ (+ alt,+ noStretchF False True + (toggleButtonF1 bbt fname [] (show_alt alt))+ )+ in listLF (verticalP' 0) (map radiobutton alts)++excludeF1 start =+ let excl last' =+ let same = excl last'+ cont last'' = excl last''+ in getSP (\msg ->+ case msg of+ (new, False) -> if new == last' then+ putsSP [Left (new, True)] (cont new)+ else+ same+ (new, True) -> if new == last' then+ putsSP [Right new] (cont new)+ else+ putsSP [Left (last', False), Right new]+ (cont new))+ in absF (putsSP [Left (start, True)] (excl start))++toggleF1 bbt keys f =+ case bbt of+ Square ->+ let edgew = 3+ dsize = Point 10 10+ innersep = 3+ fudgetsep = 5+ toggleK =+ let cid False = 0+ cid True = 1+ in allocNamedColorPixel defaultColormap+ onColor1+ (\onC ->+ allocNamedColorPixel defaultColormap+ offColor1+ (\offC ->+ let toggle s =+ map (Low . XCmd)+ [ChangeWindowAttributes [CWBackPixel (if s then onC else offC)],+ ClearWindow]+ k (High s) = toggle s+ k _ = []+ in putsK (Low (layoutRequestCmd (plainLayout dsize True True)) :+ toggle False)+ (K $ concmapSP k)))+ toggleb =+ buttonBorderF1 bbt edgew+ (marginF innersep+ (windowF [{-ConfigureWindow [CWBorderWidth 0]-}] toggleK))+ togglebd =+ let post (Left a) = Left a+ post (Right b) = stripEither b+ in stripEither >^=<+ (marginHVAlignF 0 aCenter aCenter toggleb >+#<+ (fudgetsep, LeftOf, f))+ in toggleGroupF keys (marginHVAlignF 0 aLeft aCenter togglebd)+ Triangle ->+ let edgew = 3+ dsize = Point 12 12+ innersep = 6+ fudgetsep = 5+ toggleK =+ let cid False = 0+ cid True = 1+ in allocNamedColorPixel defaultColormap+ onColor1+ (\onC ->+ allocNamedColorPixel defaultColormap+ offColor1+ (\offC ->+ let toggle s =+ map (Low . XCmd)+ [ChangeWindowAttributes [CWBackPixel (if s then onC else offC)],+ ClearWindow]+ k (High s) = toggle s+ k _ = []+ in putsK (Low (layoutRequestCmd (plainLayout dsize True True)) :+ toggle False)+ (K $ concmapSP k)))+ vormT punt = [FillPolygon Nonconvex CoordModeOrigin [origin, padd origin (Point 0 ((ycoord punt)-1)),+ padd origin (Point ((xcoord punt)-1) (((ycoord punt)`div`2)-1))]]+ toggleb =+ buttonBorderF1 bbt edgew+ (marginF innersep+ (windowF [{-ConfigureWindow [CWBorderWidth 0]-}]+ (shapeK vormT toggleK)))+ togglebd =+ let post (Left a) = Left a+ post (Right b) = stripEither b+ in stripEither >^=<+ (marginHVAlignF 0 aCenter aCenter toggleb >+#<+ (fudgetsep, LeftOf, f))+ in toggleGroupF keys (marginHVAlignF 0 aLeft aCenter togglebd)+ Circle ->+ let edgew = 3+ dsize = Point 16 16+ innersep = 2+ fudgetsep = 5+ toggleK =+ let cid False = 0+ cid True = 1+ in allocNamedColorPixel defaultColormap+ onColor1+ (\onC ->+ allocNamedColorPixel defaultColormap+ offColor1+ (\offC ->+ let toggle s =+ map (Low . XCmd)+ [ChangeWindowAttributes [CWBackPixel (if s then onC else offC)],+ ClearWindow]+ k (High s) = toggle s+ k _ = []+ in putsK (Low (layoutRequestCmd (plainLayout dsize True True)) :+ toggle False)+ (K $ concmapSP k)))+ vormC punt = [FillArc (Rect origin (Point ((xcoord punt)-1) ((ycoord punt)-1))) (0*64) (360*64)]+ toggleb =+ buttonBorderF1 bbt edgew+ (marginF innersep+ (windowF [{-ConfigureWindow [CWBorderWidth 0]-}]+ (shapeK vormC toggleK)))+ togglebd =+ let post (Left a) = Left a+ post (Right b) = stripEither b+ in stripEither >^=<+ (marginHVAlignF 0 aCenter aCenter toggleb >+#<+ (fudgetsep, LeftOf, f))+ in toggleGroupF keys (marginHVAlignF 0 aLeft aCenter togglebd)++toggleButtonF1 :: RadioButtonBorderType -> String -> [(ModState, KeySym)] -> String -> F Bool Bool+toggleButtonF1 bbt fname keys text =+ stripEither >^=<+ toggleF1 bbt keys (noStretchF True True (labelF' (setFont fname) text))+ >=^< Left++offColor1 = argKey "toggleoff" bgColor++onColor1 = argKey "toggleon" fgColor++buttonBorderF1 :: RadioButtonBorderType -> Int -> (F a b) -> F (Either Bool a) b+buttonBorderF1 = stdButtonBorderF1++stdButtonBorderF1 bbt edgew f =+ let kernel =+ allocNamedColorDefPixel defaultColormap shineColor "white" $ \shine ->+ allocNamedColorDefPixel defaultColormap shadowColor "black" $ \shadow ->+ wCreateGC rootGC [GCFunction GXcopy, GCForeground shadow,+ GCBackground shine] $ \drawGC ->+ wCreateGC rootGC [GCFunction GXcopy, GCForeground shine, GCBackground shine] $ \extraGC ->+ wCreateGC rootGC (invertColorGCattrs shine shadow) $ \invertGC ->+ let+ dRAWS s =+ let bpx = edgew+ bpy = edgew+ upperLeftCorner = Point bpx bpy+ size@(Point sx sy) = psub s (Point 1 1)+ rect = Rect origin size+ upperRightCorner = Point (sx - bpx) bpy+ lowerLeftCorner = Point bpx (sy - bpy)+ lowerRightCorner = psub size upperLeftCorner+ leftBorder = Line upperLeftCorner lowerLeftCorner+ upperBorder = Line upperLeftCorner upperRightCorner+ upperLeftLine = Line origin upperLeftCorner+ lowerRightLine = Line lowerRightCorner size+ incx = padd (Point 1 0)+ incy = padd (Point 0 1)+ decx = padd (Point (-1) 0)+ decy = padd (Point 0 (-1))+ lowerBorderPoints = [lowerLeftCorner, lowerRightCorner,+ upperRightCorner, Point sx 0, size, Point 0 sy]+ borderPoints =+ [pP 1 1, pP 1 sy, size, pP sx 1, origin, upperLeftCorner,+ incy lowerLeftCorner, (incx . incy) lowerRightCorner,+ incx upperRightCorner, upperLeftCorner]+ rectPoints = [origin, padd origin (Point (sx-1) 0), size, padd origin (Point 0 (sy-1))]+ in (map Low [+ wFillPolygon extraGC Convex CoordModeOrigin rectPoints,+ wFillPolygon drawGC Nonconvex CoordModeOrigin lowerBorderPoints,+ wDrawLine drawGC leftBorder,+ wDrawLine drawGC upperBorder,+ wDrawLine drawGC upperLeftLine,+ wDrawLine invertGC lowerRightLine,+ wDrawRectangle drawGC rect+ ],+ [Low (wFillPolygon invertGC Nonconvex CoordModeOrigin borderPoints)])+ dRAWT s =+ let bpx = edgew+ bpy = edgew+2+ upperLeftCorner = Point bpx bpy+ size@(Point sx sy) = psub s (Point 1 1)+ ap = padd origin (Point 5 2)+ bp = padd origin (Point 5 (sy-3))+ cp = Point (sx) (((sy - bpy)`div`2)+2)+ dp = padd ap (Point bpx bpy)+ ep = padd bp (Point bpx (-bpy))+ fp = psub cp (Point (bpx+4) 0)+ l1 = Line ap bp+ l2 = Line bp cp+ l3 = Line cp ap+ l4 = Line dp ep+ l5 = Line ep fp+ l6 = Line fp dp+ l7 = Line ap dp+ l8 = Line bp ep+ l9 = Line cp fp+ incx = padd (Point 1 0)+ incy = padd (Point 0 1)+ decx = padd (Point (-1) 0)+ decy = padd (Point 0 (-1))+ tBorderPoints = [(incx . incy) ap, decy bp, decx cp, (incx . incy) ap, dp, fp, ep, dp]+ tLowerBorderPoints = [ep,bp,cp,fp]+ trianglePoints = [ap,bp,cp]+ in (map Low [+ wFillPolygon extraGC Nonconvex CoordModeOrigin trianglePoints,+ wFillPolygon drawGC Nonconvex CoordModeOrigin tLowerBorderPoints,+ wDrawLine drawGC l1,+ wDrawLine drawGC l2,+ wDrawLine drawGC l3,+ wDrawLine drawGC l4,+ wDrawLine drawGC l5,+ wDrawLine drawGC l6,+ wDrawLine drawGC l7,+ wDrawLine drawGC l8,+ wDrawLine drawGC l9+ ],+ [+ Low (wFillPolygon invertGC Nonconvex+ CoordModeOrigin tBorderPoints)+ ])+ dRAWC s =+ let bpx = edgew+ bpy = edgew+ upperLeftCorner = Point bpx bpy+ size@(Point sx sy) = psub s (Point 1 1)+ groteRechthoek = Rect origin size+ groteRechthoek2 = Rect (psub origin (Point 1 1)) size+ kleineRechthoek = Rect (padd origin (Point edgew edgew)) (Point (sx-(2*edgew)) (sy-(2*edgew)))+ in (map Low [+ wFillArc extraGC groteRechthoek (0*64) (360*64),+ wFillArc drawGC groteRechthoek (-135*64) (180*64),+ wDrawArc drawGC groteRechthoek (0*64) (360*64),+ wFillArc extraGC kleineRechthoek (0*64) (360*64),+ wDrawArc drawGC kleineRechthoek (0*64) (360*64)+ ],+ [Low (wFillArc invertGC groteRechthoek2 (0*64) (360*64))])+ proc pressed size =+ getK $ \bmsg ->+ let same = proc pressed size+ (drawit_size, pressit_size) = case bbt of+ Square -> dRAWS size+ Triangle -> dRAWT size+ Circle -> dRAWC size+ redraw b = if (b == pressed) then [] else pressit_size+ in case bmsg of+ Low (XEvt (Expose _ 0)) -> putsK (drawit_size +++ (if pressed then pressit_size else [])) same+ Low (LEvt (LayoutSize newsize)) -> proc pressed newsize+ High change -> putsK (redraw change) (proc change size)+ _ -> same+ proc0 pressed =+ getK $ \msg ->+ case msg of+ Low (LEvt (LayoutSize size)) -> proc pressed size+ High change -> proc0 change+ _ -> proc0 pressed+ in proc0 False++ startcmds =+ [XCmd $ ConfigureWindow [CWBorderWidth 0],+ XCmd $ ChangeWindowAttributes [CWEventMask [ExposureMask]]]+ in stripEither >^=< (((groupF startcmds (changeBg bgColor kernel)) . marginF (edgew + 1)) f)+
+ Contrib/SmileyF.hs view
@@ -0,0 +1,28 @@+module SmileyF where+import Fudgets++data SmileyMode = Sad | Indifferent | Happy deriving (Eq,Ord,Enum,Show)++smileyF = smileyF' standard++smileyF' :: Customiser (DisplayF SmileyMode) -> F SmileyMode void+smileyF' pm = displayF' pm'+ where pm' = pm .+ setInitDisp Indifferent .+ setInitSize Indifferent .+ setStretchable (False,False) .+ (setMargin 1 :: (Customiser (DisplayF SmileyMode)))++smileyD mode =+ FixD (Point 15 15) [+ drawCircle (Point 2 2) 2, -- eye+ drawCircle (Point 10 2) 2, -- eye+ DrawLine (lL 7 5 7 9), -- nose+ case mode of+ Sad -> DrawArc (rR 3 11 8 4) 0 (64*180) -- mouth+ Indifferent -> DrawLine (lL 3 12 11 12) -- mouth+ Happy -> DrawArc (rR 3 9 8 4) (64*180) (64*180) -- mouth+ ]++instance Graphic SmileyMode where+ measureGraphicK = measureGraphicK . smileyD
+ Contrib/SocketServer.hs view
@@ -0,0 +1,41 @@+module SocketServer(ClientMsg(..),SocketMsg(..),mapSocketMsg,socketServerF) where+import AllFudgets+import DialogueIO hiding (IOError)++data ClientMsg a = ClientMsg a | ClientEOS | ClientNew deriving (Show)+data SocketMsg a = SocketMsg a | SocketEOS deriving (Show)++mapSocketMsg f (SocketMsg a) = SocketMsg (f a)+mapSocketMsg f SocketEOS = SocketEOS++instance Functor SocketMsg where fmap = mapSocketMsg++socketServerF port f = + loopThroughRightF (concatMapF router) (listenerF >+< dynListF)+ where+ router = either (either fromListener fromDynList) fromOutside+ where+ fromListener (i,f) = [todyn (i,DynCreate f), out (i,ClientNew)]++ fromDynList (i,m) =+ case m of+ SocketMsg m' -> [out (i,ClientMsg m')]+ SocketEOS -> [out (i,ClientEOS), todyn (i,DynDestroy)]++ fromOutside (i,m) = [todyn (i,DynMsg m)]++ todyn = Left . Right+ out = Right++ listenerF =+ openLSocketF port $ \lsocket ->+ select [LSocketDe lsocket] $+ accepter 0+ where+ accepter i = + getMessageFu $ \e ->+ case e of+ Low (DResp (AsyncInput (_,SocketAccepted socket peer))) ->+ putF (i,f socket peer) $+ accepter (i+1)+ _ -> accepter i
+ Contrib/SplitF.hs view
@@ -0,0 +1,39 @@+module SplitF where+import AllFudgets+import HandleF(vHandleF,hHandleF)+import LinearSplitP(linearSplitP)++hSplitF = hSplitF' aCenter+vSplitF = vSplitF' aCenter++hSplitF' = splitF' Horizontal+vSplitF' = splitF' Vertical++splitF' dir alignment fud1 fud2 =+ loopCompThroughRightF $+ groupF startcmds sizeK $+ placerF (linearSplitP dir defaultSep) $+ fud1>+<hF>+<fud2+ where+ startcmds = [XCmd $ ChangeWindowAttributes [CWBackPixmap parentRelative]]++ hF = colinear dir hHandleF vHandleF alignment++ toLoop = Just . High . Left+ out = Just . High . Right+ toHandle = toLoop . Left . Right+ toFud1 = toLoop . Left . Left+ toFud2 = toLoop . Right++ sizeK = K (mapFilterSP route)+ route = message low high++ low (LEvt (LayoutSize size)) = toHandle size+ low event = ignore event+ + high = either fromLoop (either toFud1 toFud2)+ fromLoop = either (either fromFud1 ignore) fromFud2+ fromFud1 = out . Left+ fromFud2 = out . Right++ ignore _ = Nothing
+ Contrib/SuperMenuF.hs view
@@ -0,0 +1,239 @@+module SuperMenuF (superMenuF, MenuItem (..)) where+--module SuperMenuF where+import AllFudgets+import Data.Maybe(fromJust) --,fromMaybe+import HbcUtils(breakAt)++data MenuItem a =+ Item a+ | Submenu (String, [MenuItem a])+ deriving (Eq, Ord, Show)++data MenuTag a =+ ItemTag a+ | SubTag String+ deriving (Eq, Ord)++data PopupSubMenu =+ PopupSub Point+ | PopdownSub+ +mainTag = SubTag "Joost Bossuyt"++modstate = []++mousebutton = Button 1++menuButtonF1 gcs optrect text =+ let mask =+ [EnterWindowMask, LeaveWindowMask, ButtonPressMask, ButtonReleaseMask,+ ExposureMask]+ startcmds =+ [XCmd $ ChangeWindowAttributes [CWEventMask mask, CWBackingStore Always]]+ optsize = fmap rectsize optrect+ in swindowF startcmds+ optrect+ (buttonDisplayK gcs optsize text)++lxcmd = Low . XCmd++buttonDisplayK (drawGC,invertGC,fs) opsize text =+ let Rect spos ssize = string_rect fs text+ margin = Point 3 1+ size =case opsize of+ Just s -> s+ Nothing -> padd ssize (padd margin margin)+ invertitif b size' =+ if b then [Low (wFillRectangle invertGC (Rect origin size'))]+ else []+ drawit state size' =+ let textpos = psub margin spos+ in [lxcmd ClearWindow, Low (wDrawImageString drawGC textpos text)]+ ++ invertitif (state == BMInverted) size'+ buttonproc bstate size' =+ let same = buttonproc bstate size'+ cont b = buttonproc b size'+ redraw b s = putsK (drawit b s) (buttonproc b s)+ in getK $ \bmsg ->+ case bmsg of+ Low (XEvt (Expose _ 0)) -> redraw bstate size'+ Low (LEvt (LayoutSize size'')) -> redraw bstate size''+ Low (XEvt (ButtonEvent _ _ _ _ Released _)) ->+ putsK (invertitif (bstate == BMInverted) size'+ ++ [High (BMClick, Nothing)])+ (cont BMNormal)+ Low (XEvt (EnterNotify {pos=winpos,rootPos=rootpos})) ->+ let width = Point (xcoord size') (-1) + pos = padd (psub rootpos winpos) width+ in putsK (invertitif (bstate /= BMInverted) size'+ ++ [High (BMInverted, Just pos)])+ (cont BMInverted)+ Low (XEvt (LeaveNotify {})) ->+ putsK (invertitif (bstate /= BMNormal) size') (cont BMNormal)+ _ -> same+ in putsK [Low (layoutRequestCmd (plainLayout size True True))]+ (buttonproc BMNormal size)++menuListF gcs alts show_alt =+ let --show_MenuTag :: MenuTag a -> String+ show_MenuTag x =+ case x of+ ItemTag a -> show_alt a+ SubTag s -> s+ altButton alt = (alt, menuButtonF1 gcs Nothing (show_MenuTag alt))+ in listLF (verticalP' 0) (map altButton alts)++subMenuF gcs optrect alts show_alt =+ let wattrs = [CWEventMask [], CWSaveUnder True, CWOverrideRedirect True]+ startcmds = [lxcmd $ ChangeWindowAttributes wattrs,+ lxcmd $ ConfigureWindow [CWBorderWidth 1]]+ fudget = menuListF gcs alts show_alt + in delayF $+ loopCompThroughRightF $+ shellKF' (setMargin 0.setVisible False) (putsK startcmds subMenuK) fudget++subMenuK =+ let popdown = map lxcmd [UnmapWindow]+ popup p = map lxcmd [moveWindow p, MapRaised]+ downK =+ getK (\msg ->+ case msg of+ High (Right (PopupSub p )) -> putsK (popup p) upK+ _ -> downK)+ upK =+ getK (\msg ->+ case msg of+ High (Right PopdownSub) -> putsK popdown downK+ High (Left (alt, (bm, pos))) ->+ putsK [High (Right (alt, (bm, pos)))] upK+ _ -> upK)+ in setFontCursor 110 downK++controlF list = loopCompThroughRightF (kernelF controlK >+< listF list)++controlK ::+ (Eq a) =>K (Either (MenuTag a,(MenuTag a,(BMevents,Maybe Point))) PopupSubMenu)+ (Either (MenuTag a,PopupSubMenu) a)+controlK =+ let proc active =+ getK (\msg ->+ case msg of+ High (Left (tag, (SubTag s, (bm, opoint)))) ->+ (case bm of+ BMClick ->+ let oldlist = map (\x -> High (Left (x, PopdownSub))) active+ in putsK oldlist (proc [])+ BMInverted ->+ let (olist, nlist) = breakAt tag active+ newlist = [SubTag s, tag] ++ nlist+ oldlist = map (\x -> High (Left (x, PopdownSub))) olist+ pos = fromJust opoint+ in putsK (oldlist ++ [High(Left(SubTag s, PopupSub pos))])+ (proc newlist)+ _ -> proc active)+ High (Left (tag, (ItemTag a, (bm, opoint)))) ->+ (case bm of+ BMClick ->+ let oldlist = map (\x -> High (Left (x, PopdownSub))) active+ in putsK (oldlist ++ [High (Right a)]) (proc [])+ BMInverted ->+ let (olist, nlist) = breakAt tag active+ newlist = [tag] ++ nlist+ oldlist = map (\x -> High (Left (x, PopdownSub))) olist+ in putsK oldlist (proc newlist)+ _ -> proc active)+ High (Right (PopupSub pos)) ->+ putsK [High (Left (mainTag, PopupSub pos))] (proc [mainTag])+ High (Right PopdownSub) ->+ let oldlist = map (\x -> High (Left (x, PopdownSub))) active+ in putsK oldlist (proc [])+ _ -> proc active)+ in proc []++clickF1 gcs optrect name =+ let topopup = High . Left+ routeClick = Left+ optsize = fmap rectsize optrect+ proc (Low (XEvt (ButtonEvent _ winpos rootpos [] Pressed (Button 1)))) =+ topopup (True, PopupSub (psub rootpos winpos))+ proc (Low (XEvt (ButtonEvent _ _ _ _ Released (Button 1)))) =+ topopup (False, PopdownSub)+ proc (Low (XEvt (LeaveNotify {mode=NotifyUngrab}))) =+ topopup (False, PopdownSub)+ proc (Low msg) = Low msg+ proc (High hi) = High (Right hi)+ wattrs =+ [CWEventMask [ExposureMask, ButtonPressMask, ButtonReleaseMask,+ OwnerGrabButtonMask, LeaveWindowMask, EnterWindowMask]]+ startcmds = [XCmd $ ChangeWindowAttributes wattrs,+ XCmd $ ConfigureWindow [CWBorderWidth 1]]+ K cdisp = clickDisplayK gcs optsize name+ in swindowF startcmds+ optrect+ (K $ preMapSP cdisp proc)++clickDisplayK (drawGC,invertGC,fs) optsize name0 =+ let Rect spos ssize = string_rect fs name0+ strsize = string_box_size fs+ margin = Point 3 1+ size = fromMaybe (padd ssize (padd margin margin)) optsize+ invertitif b size' =+ if b+ then [Low (wFillRectangle invertGC (Rect origin size'))]+ else []+ drawname name hi size =+ let textpos = scalePoint 0.5 (size `psub` strsize name) `psub` spos+ in [lxcmd ClearWindow, Low (wDrawImageString drawGC textpos name)]+ ++ invertitif hi size+ buttonproc highlighted size' name =+ let fixpos (PopupSub p) =+ PopupSub (p `padd` pP (-1) (ycoord size'))+ fixpos msg = msg+ same = buttonproc highlighted size' name+ cont b = buttonproc b size' name+ contn n = buttonproc highlighted size' n+ redraw b s = putsK (drawname name b s) (buttonproc b s name)+ newname name' = putsK (drawname name' highlighted size')+ (contn name')+ in getK $ \bmsg ->+ case bmsg of+ Low (XEvt (Expose _ 0)) -> redraw highlighted size'+ Low (LEvt (LayoutSize size'')) -> redraw highlighted size''+ Low (XEvt (LeaveNotify {})) ->+ putsK (invertitif highlighted size') (cont False)+ Low (XEvt (EnterNotify {})) ->+ putsK (invertitif (not highlighted) size') (cont True)+ High (Left (hi, msg)) ->+ putsK (invertitif (hi /= highlighted) size' +++ [High (fixpos msg)])+ (cont hi)+ High (Right name') -> newname name'+ _ -> same+ in putsK [Low (layoutRequestCmd (plainLayout size True True))]+ (buttonproc False size name0)++superMenuF :: (Eq a) => (Maybe Rect) -> FontName -> String -> [MenuItem a]+ -> (a -> String) -> F String a+superMenuF oplace fname text alts show_alt =+ safeLoadQueryFont fname $ \fs ->+ allocNamedColorPixel defaultColormap "black" $ \ black ->+ allocNamedColorPixel defaultColormap "white" $ \ white ->+ wCreateGC rootGC [GCFunction GXcopy, GCFont (font_id fs)] $ \drawGC ->+ wCreateGC drawGC (invertColorGCattrs black white) $ \invertGC ->+ let gcs = (drawGC,invertGC,fs)+ parse tag source current done =+ if source == []+ then if current == []+ then done+ else done ++ [(tag, subMenuF gcs Nothing current show_alt)]+ else let (x : xs) = source+ in case x of+ Item y -> parse tag+ xs + (current ++ [ItemTag y])+ done+ Submenu (s, z) -> parse tag+ xs+ (current ++ [SubTag s])+ (parse (SubTag s) z [] done)+ in controlF (parse mainTag alts [] []) >==< clickF1 gcs oplace text
+ Contrib/TitleShellF.hs view
@@ -0,0 +1,26 @@+module TitleShellF where+import AllFudgets++titleShellF = titleShellF' standard++--titleShellF' :: Customiser ShellF -> String -> F (Either () i) (Either String o) -> F i o++titleShellF' pm title fud =+ filterRightSP >^^=< wmShellF' pm' title fud >=^< mapEither Left id+ where+ pm' = pm . setDeleteWindowAction (Just DeleteQuit)++wmShellF = wmShellF' standard++wmShellF' pm0 title fud =+ shellKF' pm titleK0 fud+ where pm = setDeleteWindowAction Nothing . pm0+ action = maybe (Just reportK)+ (fmap action')+ (getDeleteWindowActionMaybe' pm0)+ where+ action' DeleteQuit = exitK+ action' DeleteUnmap = unmapWindowK++ titleK0 = startupK [High (Left title)] titleK+ titleK = wmK action
+ Contrib/TreeBrowser.hs view
@@ -0,0 +1,144 @@+module TreeBrowser(Tree(..),treeBrowserF',treeDisplayF') where+import AllFudgets hiding (Tree(..))+import qualified ReactiveF as R++data Tree leaf node+ = Leaf leaf+ | Node node [Tree leaf node]+ deriving (Show)+++--treeBrowserF = treeBrowserF standard++treeDisplayF' t = treeBrowserF'' drawStaticTree t+treeBrowserF' t = treeBrowserF'' drawTree t++--treeBrowserF' ::Tree n l -> F (Tree n l) ([n],Maybe l)+treeBrowserF'' drawTree t =+ wCreateGCtx rootGCtx (gcFgA linecolor) $ \ lgc ->+ wCreateGCtx rootGCtx (gcFgA paperColor) $ \ bggc ->+ treeBrowserF''' drawTree (bggc,lgc) t+++treeBrowserF''' drawTree gcs@(bggc,lgc) t =+ loopThroughRightF (R.reactiveF ctrl d0) (graphicsDispF' pm)+ where+ pm1 :: Graphic a => Customiser (GraphicsF a)+ pm1 = setBgColor bgColor . setSizing Dynamic+ pm = pm1 . setInitDisp d0+ d0 = drawTree gs t+ ctrl = either fromLoop fromOutside+ where+ fromOutside t = do let d = drawTree gs t + R.set d+ R.put (toLoop $ replaceAllGfx d)++ fromLoop gfxevent =+ do (path,lbl) <- clickedpart gfxevent+ case lbl of+ Left vis -> toggle path (not vis)+ Right part -> R.put (toOutside part)++ toggle path vis =+ do (ppath,LabelD rt@(Right (Node n _))+ (ComposedD _ (_:ds))) <- parentpathpart path+ let td' = LabelD rt (nodeD gs vis n ds)+ R.update $ \ d -> replacePart d ppath td'+ R.put (toLoop $ replaceGfx ppath td')++ toLoop = Left+ toOutside = Right++ --gd = softAttribD [GCLineStyle LineOnOffDash] . g+ --gd x = g x+ gl = hardAttribD lgc . g+ gbg = hardAttribD bggc . g+ gs = (gbg,gl)++clickedpart gfxevent =+ case gfxevent of+ GfxButtonEvent{gfxType=Pressed, gfxPaths=(path,_):_} -> pathlbl path+ _ -> R.rfail++pathlbl path =+ do (lpath,LabelD lbl _) <- pathpart path+ return (lpath,lbl)++pathpart path =+ do drawing <- R.get+ let lpath = drawingAnnotPart drawing path+ part <- R.lift $ maybeDrawingPart drawing lpath+ return (lpath,part)++parentpathpart = pathpart . up++drawStaticTree gs t = placedD (verticalLeftP' 0) $ drawTree' gs Nothing t+drawTree gs t = placedD (verticalLeftP' 0) $ drawTree' gs opendepthlimit t++staticNodeD gs n ds = boxD (hboxD' 0 [sframeD 3 gs (g n)]:ds)++nodeD gs@(gbg,gl) vis n ds =+ boxVisibleD vcnt (hboxD' 0 [sframeD 3 gs (g n),gl hLineFD,markD]:ds)+ where+ vcnt = 1+(if vis then length ds else 0)+ markD = labelD (Left vis) $ circleD (if vis then g "-" else g "+")++ circleD d =+ spacedD centerS $+ stackD [gbg filledEllipse,gl ellipse,spacedD sqpadS d]+ where sqpadS = resizeS sq `compS` centerS+ sq (Point w h) = Point m m where m = max w h++sframeD sep gs d = spacedD (vMarginS sep 0) $ frameD gs d++frameD (gbg,gl) d =+ stackD [gbg $ filler False False 1,gl frame,padD 2 d]+++nodeD' gs Nothing = staticNodeD gs+nodeD' gs (Just d) = nodeD gs (d>0)++drawTree' gs@(_,gl) depth t =+ spacedD leftS $+ labelD (Right t) $+ case t of+ Leaf l -> --hboxD' 0 [gl hLineFD,frameD gs $ g l]+ sframeD 1 gs $ g l+ Node n ts -> nodeD' gs depth n [drawTrees gs (fmap (+(-1)) depth) ts]++drawTrees gs@(_,gl) depth ts = vboxlD' 0 $ zipWith drawSubTree [n-1,n-2..0] ts+ where+ n = length ts+ drawSubTree i t = placedD (tableP' 2 Vertical 0) $+ boxD [fork i,line i,drawTree' gs depth t]+ --drawSubTree i t = hboxD' 0 [fork i,drawTree' gs depth t]+ fork 0 = gl lowerRightFD+ fork _ = gl forkRightFD+ line 0 = blankD 0+ line _ = gl vLineFD+++---++lowerRightFD = flex' (pP 14 10) f+ where f (Rect p s) =+ [DrawLines CoordModePrevious [p+pP mw 0,pP 0 mh,pP mw 0]]+ where Point mw mh = rectMiddle (Rect 0 s)++forkRightFD = flex' (pP 14 10) f+ where f (Rect p s@(Point w h)) =+ [DrawLine (Line (p+pP mw 0) (p+pP mw h)),+ DrawLine (Line (p+m) (p+pP w mh))]+ where m@(Point mw mh) = rectMiddle (Rect 0 s)++vLineFD = flex' (pP 10 1) f+ where f (Rect p s@(Point _ h)) = [DrawLine (Line (p+pP mw 0) (p+pP mw h))]+ where Point mw _ = rectMiddle (Rect 0 s)++hLineFD = flex' 10 f+ where f (Rect p s@(Point w _)) = [DrawLine (Line (p+pP 0 mh) (p+pP w mh))]+ where Point _ mh = rectMiddle (Rect 0 s)++linecolor = argKey "linecolor" "blue"+opendepthlimit = argReadKey "opendepthlimit" (Just opendepth) -- not a good name+opendepth = argReadKey "opendepth" 1::Int
+ Contrib/TypedSockets.hs view
@@ -0,0 +1,44 @@+-- | Type-safe network sockets, as described in+-- [Client/Server Applications with Fudgets](http://www.altocumulus.org/Fudgets/ftp/client-server.pdf).+module TypedSockets(TPort,tPort,tSocketServerF,TServerAddress,tServerAddress,tTransceiverF,ClientMsg(..),SocketMsg(..)) where++import Fudgets+import SocketServer+import Debug.Trace+--import DialogueIO hiding (IOError)++newtype TPort a b = TPort Port++tPort :: (Show a, Read a,Show b,Read b) => Port -> TPort a b+tPort p = TPort p++newtype TSocket t r = TSocket Socket+newtype TLSocket t r = TLSocket LSocket+data TServerAddress c s = TServerAddress Host (TPort c s)++tServerAddress host port = TServerAddress host port++tSocketServerF ::+ (Read c, Show s) => + TPort c s -> (Peer -> F s (SocketMsg c) -> F a (SocketMsg b)) ->+ F (Int, a) (Int, ClientMsg b)+tSocketServerF (TPort p) f = socketServerF p (\ s p -> f p (textTransceiver s))++--texttransceiver :: (Show t,Read r) => Socket -> F t (SocketMsg r)+textTransceiver s = postSP >^^=< transceiverF s >=^< pre+ where+ pre s = shows s "\n"++ postSP = prepostMapSP eos stripEither $+ idLeftSP (mapFilterSP reader -==- inputLinesSP)++ eos "" = Left SocketEOS+ eos s = Right s++ reader s = case reads s of + [(a,"")] -> Just (SocketMsg a)+ _ -> trace ("No parse from socket: "++s) Nothing++tTransceiverF :: (Show c, Read s) => TServerAddress c s -> F c (SocketMsg s)+tTransceiverF (TServerAddress host (TPort port)) = + openSocketF host port textTransceiver
+ Demos/Mandelbrot/Explore.hs view
@@ -0,0 +1,82 @@+import AllFudgets+import Data.Array+import Mandelbrot+import ZoomF+import UserCoords+import Control.Parallel+--import Trace++main = fudlogue $ shellF "Mandelbrot Explorer" mainF++mainF =+ allocColorScale $ \ colors ->+ loopCompThroughLeftF (zoomF (dispF colors >=^^< preSP)) >==< resetF+ where+ dispF colors = nullSP>^^=<graphicsDispF >=^< replaceAllGfx . image colors+ resetF = const area0>^=<buttonF "Reset"+ preSP = putSP area0 $ mapstateSP zoom area0+ zoom area = either zoom reset+ where+ reset area' = new area'+ zoom msg =+ case msg of+ ZoomIn s p -> new (zoomin s p area)+ ZoomOut s p -> new (zoomout s p area)+ ZoomRect size (Rect p s) ->+ if s =.> 2+ then new (zoomrect (size,area) p (p+s))+ else same+ _ -> same+ same = (area,[])+ new area' = (area',[area'])++--sizeF = "Size:" `labLeftOfF` startupF [100] intInputF++image :: Array Int Pixel -> Area -> Drawing nothing FlexibleDrawing+image grays area = atomicD (FlexD 700 False False drawfunc)+ where+ drawfunc (Rect p size0@(Point w0 h0)) =+ stripes 5 (CreatePutImage (Rect p size) zPixmap pixels)+ where+ w = min w0 h0+ size = diag w -- keep it square+ pixels = {-parallel-} [grays!g (Point ix iy) | iy <- [0..w-1], ix<-[0..w-1]]+ g = pickColor . mandelbrot . userp (size,area)+ pickColor z = z `mod` colorCount+ rw = real w++-- Color department++-- We interpolate a scale of colors from two specified end colors+allocColorScale return =+ allocNamedColor defaultColormap color1 $ \ (Color _ rgb1) ->+ allocNamedColor defaultColormap color2 $ \ (Color _ rgb2) ->+ conts (allocColorPixelF defaultColormap) (rgbs rgb1 rgb2) $+ return . listArray (0,high)+ where+ rgbs rgb1 rgb2 = [mixRGB rgb1 rgb2 i | i<-[0..high]]+ high = colorCount-1+ mixRGB (RGB r1 g1 b1) (RGB r2 g2 b2) k = RGB (m r1 r2) (m g1 g2) (m b1 b2)+ where m i1 i2 = (i1*(high-k) + i2*k) `div` high++colorCount = argReadKey "colorcount" 16 :: Int+color1 = argKey "color1" "navyblue"+color2 = argKey "color2" "white"++-- Extra++-- stripes splits one big CreatePutImage command into a number of smaller+-- so you don't have wait for the entire image to be computed before you+-- can see anything.+stripes sh dcmd@(CreatePutImage (Rect p (Point w h)) fmt pxls) =+ if h<=sh+ then [dcmd]+ else let rect' = Rect (p+(Point 0 sh)) (Point w (h-sh))+ (pxls1,pxls2) = splitAt (w*sh) pxls+ ss = stripes sh (CreatePutImage rect' fmt pxls2)+ in par ss $ par (pxls1==pxls1) $+ CreatePutImage (Rect p (Point w sh)) fmt pxls1 :+ ss++parallel [] = []+parallel xxs@(x:xs) = seq (parallel xs) $ par x xxs
+ Demos/Mandelbrot/Mandelbrot.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE CPP #-}+module Mandelbrot where+--import UnsafePerformIO(unsafePerformIO)++area0 = ((-2.0,2.0),(-2.0,2.0))++#if 0+-- The code generated by GHC is about as fast as this:+mandelbrot :: (Double,Double) -> Int+mandelbrot (x0,y0) =+ unsafePerformIO $+ _casm_ ``+ {int n=0;+ double x0=%0,y0=%1,x=0,y=0;+ while(n<200 && x*x+y*y<=4) n++,x=x*x-y*y+x0,y=2*x*y+y0;+ %r=n;+ };'' x0 y0+#else++mandelbrot :: (Double,Double) -> Int+mandelbrot (x0,y0) = m 0 0 0+ where m :: Int -> Double -> Double -> Int+ m n x y = if sqabs x y<= 4 && n< 1024+ then m (n+1) (x*x-y*y+x0) (2*x*y+y0)+ else n++ sqabs :: Double -> Double -> Double+ sqabs x y = x*x+y*y++#endif
+ Demos/SpaceInvaders/BitmapOps.hs view
@@ -0,0 +1,44 @@+module BitmapOps(doubleBM,explodeBM,bm,Bitmap(..),E(..),Size,Byte) where+--import AllFudgets(BitmapData(..),Point(..),Size)+--import Data.List.Split(chunksOf)++data Bitmap = Bitmap Size [Byte]+data E = E Size [[Bit]] deriving Eq+type Bit = Bool+type Byte = Int+type Size = (Int,Int)++doubleBM = implodeE . doubleE . explodeBM++doubleE (E (w,h) rows) = E (2*w,2*h) (double (map double rows))++double = foldr (\x r->x:x:r) []++{-+instance Show E where+ show (E _ rows) = unlines [[".*"!!fromEnum b|b<-row]|row<-rows]+ showList = (++) . unlines . map show+-}++explodeBM (Bitmap s@(w,h) bytes) = E s rows+ where+ b = (w+7) `div` 8+ rows = map (take w . concatMap explode) (chunksOf b bytes)++implodeE (E s@(w,h) rows) = Bitmap s bytes+ where+ bytes = concatMap (map implode . chunksOf 8) rows++implode = foldr (\b r->fromEnum (b::Bit)+2*r) 0++explode = take 8.expl+ where+ expl n = (n `mod` 2 /= 0):expl (n `div` 2)++bm w h = Bitmap (w,h)++---++chunksOf n [] = []+chunksOf n xs = xs1:chunksOf n xs2+ where (xs1,xs2) = splitAt n xs
+ Demos/SpaceInvaders/GUI.hs view
@@ -0,0 +1,184 @@+module GUI(Draw(..),HasSize(..),PlacedPict,pp,clear,clearpm,clearRect,wDraw,+ Pict,GCId,objGC,readPict,rectangles,text,+ overlaps,diffRect,message,Move(..),Rect(..),Point(..),pP,lL,Drawing,+ line2rect,inRect,rR,hboxD,atomicD,Click,Tick,+ argReadKey,reactiveSP,+ putLivesMkc,G,putGUI,putsGUI,putLives,putScore,getG,+ spaceF,spaceF',--nullG,+ shotColor, shelterColor, ufoColor, readObjPict,readObjPicts,+ bmScale,spaceSize,spaceWidth,spaceHeight+ ) where+import Control.Applicative+import AllFudgets hiding (draw,wDraw,size,state,rect,put)+import ReactiveF+import ReadPic+import InvaderTypes+import Metrics++{-+type G i o = K i o++nullG = nullK+putLives l = putK (High (Left l))+putScore s = putK (High (Right s))+putGUI gfx = putK (Low gfx)+putsGUI gfx = putsK (map Low gfx)+-}+type G i o = KSP i o++--nullG = nullSP+putLivesMkc _ l = toMkc $ putSP (High (Left l))+putLives _ l = put (High (Left l))+putScore s = put (High (Right s))+putGUI gfx = put (Low gfx)+putsGUI gfx = mapM_ (put . Low) gfx++spaceF' = spaceF++m = if argFlag "1x" False then metrics1 else metrics2++spaceF initK playK =+ windowF startcmds (changeBg "black" (K playKSP)) >==<idRightF tickF+ where+ playKSP = unMk (initK m) (\ w0 ->playK m w0 `serCompSP` getGSP)+ + startcmds = [layoutRequestCmd (plainLayout (spaceSize m) True True),+ XCmd $ ChangeWindowAttributes [CWEventMask eventmask]]+ eventmask = [KeyPressMask,KeyReleaseMask,+ ButtonPressMask,ButtonReleaseMask,+ LeaveWindowMask,EnterWindowMask,ExposureMask]++ tickF = startupF [False] (timerF>=^<pre)+ where+ pre True = Nothing+ pre False = Just (dt,dt)++dt = argReadKey "dt" 20::Int++--------------------------------------------------------------------------------++getGSP = getG $ flip putSP getGSP++getG return = loop+ where+ loop = getSP (message low high)++ high = return . High++ retLow = return . Low++ low (XEvt ev) = event ev+ low _ = loop++ event ev =+ case ev of+ Expose r 0 -> retLow Redraw+ ButtonEvent {} -> btn (type' ev) (button ev)+ KeyEvent {} -> key (type' ev) (keySym ev)+ _ -> loop++ btn Pressed (Button 2) = retLow (Key Fire Down)+ btn pressed (Button 1) = updown pressed MoveLeft+ btn pressed (Button 3) = updown pressed MoveRight+ btn _ _ = loop++ key Pressed "space" = retLow (Key Fire Down)+ key pressed "Shift_L" = updown pressed MoveLeft+ key pressed "Shift_R" = updown pressed MoveRight+ key pressed "Left" = updown pressed MoveLeft+ key pressed "Right" = updown pressed MoveRight+ key pressed "comma" = updown pressed MoveLeft+ key pressed "period" = updown pressed MoveRight+-- key Pressed _ = putGUI bell loop+ key _ _ = loop++ updown Pressed a = retLow (Key a Down)+ updown Released a = retLow (Key a Up)+ updown _ _ = loop++--------------------------------------------------------------------------------++data PlacedPict = PP Pict Point+type Pict = FixedColorDrawing++pp = PP+drawPP (PP (FixCD s gcdcmds) p) = [(gc,move p dcmds)|(gc,dcmds)<-gcdcmds]+drawIt obj = concatMap drawPP (drawing obj)+wDraw obj = wDrawMany (drawIt obj)++class Draw obj where drawing :: obj -> [PlacedPict]++instance Draw obj => Draw [obj] where drawing = concatMap drawing++instance (Draw o1,Draw o2) => Draw (o1,o2) where+ drawing (o1,o2) = drawing o1++drawing o2++instance (Draw o1,Draw o2,Draw o3) => Draw (o1,o2,o3) where+ drawing (o1,o2,o3) = drawing o1++drawing o2++drawing o3++--------------------------------------------------------------------------------+unMkc op ksp = ksp'+ where K ksp' = unMk op (\c->K (ksp c))++objGC fg = Mk $ unMkc (objGC' fg)++objGC' fg =+ do ~(Just bgpixel) <- Mk (tryConvColorK "black")+ ~(Just fgpixel) <- Mk (tryConvColorK [fg,"white"])+ let attrs = [GCBackground bgpixel,GCForeground fgpixel]+ Mk (wCreateGC rootGC (GCGraphicsExposures False:attrs))+++readObjPicts m (obj1,obj2) = (,) <$> readObjPict m obj1 <*> readObjPict m obj2++readObjPict m obj = flip (readPict m) obj =<< objGC (objectColor obj)++readPict m gc path = pmPict gc <$> readPic' m path++readPic' m path = Mk $ unMkc (readPic m path)++pmPict gc pm@(PixmapImage size _) = FixCD size (copy gc pm 0)++rectangles gc s rs = FixCD s [(gc,map FillRectangle rs)]++text gc s = FixCD (pP (6*length s) 13) [(gc,[DrawString 0 s])] -- !!++clearpm p pict = clear p (size pict)++clear p size = clearRect (Rect p size) False++clearRect r e = XCmd $ ClearArea r e++copy gc pm p = [(gc,[copy' pm p])]+copy' (PixmapImage size pm) p = CopyPlane (Pixmap pm) (Rect origin size) p 0++bell = XCmd (Bell 0)++--------------------------------------------------------------------------------++class HasSize a where size :: a -> Size++instance HasSize PixmapImage where size (PixmapImage s pm) = s+instance HasSize FixedColorDrawing where size (FixCD s _) = s+instance HasSize FixedDrawing where size (FixD s _) = s++--------------------------------------------------------------------------------++objectColor obj =+ case obj of+ Vader r _ -> vaderColor r+ VExplode r -> vaderColor r+ VShot _ -> vshotColor+ Base -> baseColor+ Explode -> baseColor+ Ufo -> ufoColor++baseColor = argKey "baseColor" "cyan"+shotColor = argKey "shotColor" "lavender"+vshotColor = argKey "vshotColor" "orange"+shelterColor = argKey "shelterColor" "yellow"+ufoColor = argKey "ufoColor" "grey"++vaderColor r = argKey ("vader"++show (rowNum r)++"Color") (rowColor r)++rowColor r = case r of R1-> "blue"; R2 -> "green"; R3 -> "red"
+ Demos/SpaceInvaders/InvaderTypes.hs view
@@ -0,0 +1,18 @@+module InvaderTypes where++data GEvent = Redraw | Key Action UpDown+data Action = MoveLeft | MoveRight | Fire+data UpDown = Up | Down++data Phase = A | B deriving (Eq,Show)+data Row = R1 | R2 | R3 deriving (Eq,Enum,Show)++rows = [R1,R2,R3]+phases f = (f A,f B)++rowNum :: Row -> Int+rowNum = succ . fromEnum++data Object = Vader Row Phase | VExplode Row | VShot Phase+ | Base | Explode | Ufo+ deriving (Eq,Show)
+ Demos/SpaceInvaders/MainF.hs view
@@ -0,0 +1,34 @@+module MainF where+import Fudgets+import AllFudgets(toggleButtonF')+import ScoreF++--{- +mainF worldF = nameLayoutF layout spaceInvadersF+ where+ layout = vBoxNL' 2 [a s,w,hBoxNL [l,n,p]]+ where+ [w,n,p,l,s] = map leafNL ["w","n","p","l","s"]+ a = marginHVAlignNL 0 aRight aTop++ spaceInvadersF = outF>==<nameF "w" worldF>==<inF++ inF = nameF "p" pauseF>+<nameF "n" (buttonF "New")+ pauseF = toggleButtonF' (setKeys [([Control],"p")]) "Pause"++ outF = nameF "l" livesF >+< nameF "s" scoreF++ livesF = displayF' (setBgColor "black" . setFgColor "white")+--}+{-+mainF worldF = spaceInvadersF+ where+ spaceInvadersF = vBoxF (outF>==<worldF (Point 480 390)>==<inF)++ inF = swapEither >^=< hBoxF (buttonF "New" >+< pauseF)+ pauseF = toggleButtonF' (setKeys [([Control],"p")]) "Pause"++ outF = hBoxF (livesF >+< scoreF)++ livesF = displayF' (setBgColor "black" . setFgColor "white")+--}
+ Demos/SpaceInvaders/Metrics.hs view
@@ -0,0 +1,16 @@+module Metrics where+import Pics as P2+import Pics1 as P1+import BitmapOps(Bitmap)+import InvaderTypes(Object)+import AllFudgets++metrics1 = M 1 (pP 240 195) P1.pics+metrics2 = M 2 (scaleP 2 (spaceSize metrics1)) P2.pics++data Metrics = M { bmScale::Int, spaceSize::Size, pics::Object->Bitmap }++spaceWidth = xcoord . spaceSize+spaceHeight = ycoord . spaceSize++scaleP k (Point x y) = Point (k*x) (k*y)
+ Demos/SpaceInvaders/Pics.hs view
@@ -0,0 +1,39 @@+module Pics where+import BitmapOps(doubleBM,bm)+import Pics1+import InvaderTypes++bmScale = 2 :: Int++pics obj =+ case obj of+ Base -> doubleBM base1+ Explode -> explode2+ Ufo -> spacer2+ VExplode _ -> vexplode2+ _ -> doubleBM (Pics1.pics obj)++explode2 = bm 30 20 explode2_bits+explode2_bits = [+ 0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xf0,0x03,0x00,0x00,0xf0,0x03,+ 0x00,0x00,0xf0,0x03,0x00,0x00,0xf0,0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,+ 0x0f,0x00,0xfc,0xff,0xff,0x0f,0xfc,0xff,0xff,0x0f,0x07,0x00,0x00,0x38,0xf3,+ 0x00,0x00,0x33,0x33,0x01,0x80,0x33,0x33,0x01,0xc0,0x30,0x33,0x39,0xce,0x30,+ 0xf3,0x6c,0xdb,0x31,0x33,0x6c,0xdb,0x30,0x33,0x38,0xce,0x30,0xff,0xff,0xff,+ 0x3f,0xff,0xff,0xff,0x3f]++spacer2 = bm 32 16 spacer2_bits+spacer2_bits = [+ 0x00,0xf0,0x0f,0x00,0x00,0xf0,0x0f,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,+ 0x00,0xc0,0xff,0xff,0x03,0xc0,0xff,0xff,0x03,0xf0,0xff,0xff,0x0f,0xf0,0xff,+ 0xff,0x0f,0x38,0xcf,0xf3,0x1c,0x38,0xcf,0xf3,0x1c,0xfc,0xff,0xff,0x3f,0xfc,+ 0xff,0xff,0x3f,0xf0,0x03,0xc0,0x0f,0xf0,0x03,0xc0,0x0f,0xc0,0x00,0x00,0x03,+ 0xc0,0x00,0x00,0x03]+ +vexplode2 = bm 28 16 vexplode2_bits+vexplode2_bits = [+ 0x00,0x20,0x00,0x00,0x00,0x24,0x01,0x00,0x00,0xa8,0x10,0x00,0xc0,0xa8,0x0c,+ 0x00,0x00,0x03,0x02,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,+ 0xf0,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x10,0x00,0x60,0x04,0x64,0x00,0x00,+ 0x53,0x09,0x00,0xc0,0x50,0x11,0x00,0x00,0x48,0x02,0x00,0x00,0x40,0x00,0x00,+ 0x00,0x00,0x00,0x00]
+ Demos/SpaceInvaders/Pics1.hs view
@@ -0,0 +1,93 @@+module Pics1 where+import BitmapOps(bm)+import InvaderTypes++bmScale = 1 :: Int++pics obj =+ case obj of+ Base -> base1+ Explode -> explode1+ Ufo -> spacer1+ VShot A -> sperma1+ VShot B -> spermb1+ Vader R1 A -> vader1a1+ Vader R1 B -> vader1b1+ Vader R2 A -> vader2a1+ Vader R2 B -> vader2b1+ Vader R3 A -> vader3a1+ Vader R3 B -> vader3b1+ VExplode _ -> vexplode1++{-+Copyright notice:++This is mine. I'm only letting you use it. Period. Feel free to rip off+any of the code you see fit, but have the courtesy to give me credit.+Otherwise great hairy beasties will rip your eyes out and eat your flesh+when you least expect it.++Jonny Goldman <jonathan@think.com>++Wed May 8 1991+-}++--pics1 = [base1,explode1,spacer1,sperma1,spermb1,+-- vader1a1,vader1b1,vader2a1,vader2b1,vader3a1,vader3b1,vexplode1]++base1 = bm 15 10 base1_bits+base1_bits = [+ 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xfe, 0x3f, 0xff, 0x7f,+ 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f]++explode1 = bm 15 10 explode1_bits+explode1_bits = [+ 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01, 0x20, 0x02, 0x3e, 0x3e, 0x0d, 0x50,+ 0x15, 0x48, 0x6d, 0x5b, 0x65, 0x4b, 0xff, 0x7f]++spacer1 = bm 16 8 spacer1_bits+spacer1_bits = [+ 0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xb6, 0x6d, 0xff, 0xff,+ 0x1c, 0x38, 0x08, 0x10]++sperma1 = bm 3 7 sperma1_bits+sperma1_bits = [0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02]++spermb1 = bm 3 7 spermb1_bits+spermb1_bits = [0x02, 0x04, 0x02, 0x01, 0x02, 0x04, 0x02]++vader1a1 = bm 10 8 vader1a1_bits+vader1a1_bits = [+ 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xb6, 0x01, 0xfe, 0x01, 0xb4, 0x00,+ 0x02, 0x01, 0x84, 0x00]++vader1b1 = bm 10 8 vader1b1_bits+vader1b1_bits = [+ 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xb6, 0x01, 0xfe, 0x01, 0xb4, 0x00,+ 0x48, 0x00, 0x84, 0x00]++vader2a1 = bm 12 8 vader2a1_bits+vader2a1_bits = [+ 0x08, 0x01, 0x90, 0x00, 0xf8, 0x01, 0x6c, 0x03, 0xfe, 0x07, 0xfa, 0x05,+ 0x0a, 0x05, 0x90, 0x00]++vader2b1 = bm 12 8 vader2b1_bits+vader2b1_bits = [+ 0x08, 0x01, 0x92, 0x04, 0xfa, 0x05, 0x6e, 0x07, 0xfc, 0x03, 0xf8, 0x01,+ 0x08, 0x01, 0x04, 0x02]++vader3a1 = bm 14 8 vader3a1_bits+vader3a1_bits = [+ 0xe0, 0x01, 0xfc, 0x0f, 0xfe, 0x1f, 0xce, 0x1c, 0xfe, 0x1f, 0x38, 0x07,+ 0xcc, 0x0c, 0x18, 0x06]++vader3b1 = bm 14 8 vader3b1_bits+vader3b1_bits = [+ 0xe0, 0x01, 0xfc, 0x0f, 0xfe, 0x1f, 0xce, 0x1c, 0xfe, 0x1f, 0x38, 0x07,+ 0xcc, 0x0c, 0x06, 0x18]++vexplode1 = bm 14 8 vexplode1_bits+vexplode1_bits = [+ 0x48, 0x04, 0x50, 0x02, 0x00, 0x00, 0x06, 0x18, 0x10, 0x02, 0x88, 0x04,+ 0x80, 0x00, 0x00, 0x00]+
+ Demos/SpaceInvaders/ReadPic.hs view
@@ -0,0 +1,16 @@+module ReadPic(readPic,readPics,bmScale) where+import Control.Applicative+import AllFudgets+--import Pics+import BitmapOps+import Metrics++readPics m (file1,file2) = (,) <$> readPic m file1 <*> readPic m file2++readPic m name =+ case pics m name of+ Bitmap (w,h) bytes ->+ do bmr <- Mk (bitmapFromData (BitmapData (Point w h) Nothing bytes))+ case bmr of+ BitmapReturn size _ pm -> return (PixmapImage size pm)+ BitmapBad -> error ("Can't read bitmap "++show name)
+ Demos/SpaceInvaders/ScoreF.hs view
@@ -0,0 +1,20 @@+module ScoreF where+import Fudgets+import AllFudgets(appStorageF)++scoreF = placerF autoP (currentF>*<highF)>=^^<sumSP++highF = dispF "High:" >==<+ loopThroughRightF (toBothF >=^^< maxSP >=^< stripEither) storageF+ where+ storageF = appStorageF "SpaceInvaders.highscore" 0++currentF = dispF "Score:"++sumSP = accSP (\s->maybe 0 (s+)) 0+maxSP = accSP max 0++accSP f = mapstateSP (\s x->let x'=f s x in (x',[x']))++dispF lbl = lbl `labLeftOfF` intDispF' custom+ where custom = setFgColor "white" . setBgColor "black" . setInitSize 999999
+ Demos/SpaceInvaders/SpaceInvaders2.hs view
@@ -0,0 +1,8 @@++import System.Random(newStdGen)+import Fudgets+import WorldF+import MainF++main = do g <- newStdGen+ fudlogue (shellF "Space Invaders" (mainF (worldF g)))
+ Demos/SpaceInvaders/WorldF.hs view
@@ -0,0 +1,490 @@+-- | The entire world, implemented as a single fudget, instead of one fudget+-- per object in the world.+module WorldF(worldF,worldF') where+import System.Random+import Control.Applicative+import Control.Monad(when)+import Data.List(nub)+import ReactionM+import GUI+import InvaderTypes hiding (Phase(..))++data World = W {rnd::StdGen, shelters::Shelters, base::Base, ufo::Ufo,+ torpedo::Torpedo, vshots::VShots, invaders::Invaders}+data Base = B {bPict,exbPict::Pict, bPos::Point, lives::Int, bSpeed::Speed}+ | ExB {bPict,exbPict::Pict, bPos::Point, lives::Int, exbAge::Int}+--data Shelters = Sh [PlacedPict] -- hmm+type Shelters = [Shelter]+data Shelter = Sh {shGC::GCId,shBR::Rect,shRs::[Rect]}+data Torpedo = T Pict (Maybe Point)+data Ufo = U Pict GCId UfoState+data UfoState = Wait Ticks | Moving Score Speed Point | Hit Ticks Score Point+data VShots = V Speed (Pict,Pict) [Point]+data VShot = V1 Speed (Pict,Pict) Point+data Invaders = Invs {invs::[Invader], level::Int, step::Speed, delay::Ticks}+data Invader = Inv {invPict::(Pict,Pict),exvPict::Pict,+ invScore::Int,invPos::Point}+ | Exv {exvPict::Pict, invPos::Point} -- exploded+type ExVader = Pict+type Speed = Int+type Ticks = Int+type Score = Int++modBase = update . updateBase+updateBase f w@W{base=b} = w{base=f b}+--updateTorpedo f =w@W{torpedo=t} = w{torpedo=f b}++exBase (B pm ex p l v) = ExB pm ex p l 0+exBase base = base++alive w = case base w of B {} -> True; _-> False++spare pm n = if n>=0+ then hboxD (replicate n (atomicD (Right pm)))+ else atomicD (Left "Game over!")++--------------------------------------------------------------------------------++worldF g = spaceF (initWorldK g) objectsK+worldF' g = spaceF' (initWorldK g) objectsK++--------------------------------------------------------------------------------++initWorldK g m =+ W g <$> initSheltersK m <*> initBaseK m <*> initUfoK m+ <*> initTorpedoK m <*> initVShotsK m <*> initInvadersK m++initSheltersK metrics =+ do gc <- objGC shelterColor+ let sh p = Sh gc (Rect p s) (move p shape)+ return $ map sh ps+ where+ s@(Point w h) = shelterSize metrics+ m = (spaceWidth metrics -3*3-7*w) `div` 2+ y = spaceHeight metrics-margin metrics-3*h+ xs = [m+2*(w+3)*i|i<-[0..3]]+ ps = [Point x y|x<-xs]++ shape = [v x roofy h|x<-[0..roofx-1]]+++ [v x 0 h|x<-[roofx..legx-1]]+++ [v x 0 (h-legy)|x<-[legx..w-legx-1]]+++ [v x 0 h|x<-[w-legx..w-roofx-1]]+++ [v x roofy h|x<-[w-roofx..w-1]]+ v x y1 y2 = rR x y1 1 (y2-y1)+ legx = w `div` 3 - 1+ legy = h `div` 4+ roofy = legy+ roofx = w `div` 10++initBaseK m =+ do pict <- readObjPict m Base+ ex <- readObjPict m Explode+ let startpos = (baseStartPos m pict){xcoord= -width pict}+ lives = 3+ putLivesMkc m (spare pict lives)+ return (ExB pict ex startpos (lives+1) 50)++baseStartPos m pict = Point (margin m) (spaceHeight m-height pict-margin m)++initUfoK m =+ do gc <- objGC ufoColor+ pict <- readPict m gc Ufo+ return $ U pict gc (Wait ufoDelay)+ +initTorpedoK m =+ do gc <- objGC shotColor+ let s = torpedoSize m+ pict = rectangles gc s [Rect 0 s]+ return (T pict Nothing)++initVShotsK m = flip (V (vshotDy m)) [] <$> readObjPicts m (phases VShot)++initInvadersK m =+ invaders <$> mapM (readObjPicts m . phases . Vader) rows+ <*> mapM (readObjPict m . VExplode) rows+ where+ invaders is es = Invs invs startLevel dx0 16+ where+ invs = zipWith centerI (concatMap row [i3,i3,i2,i2,i1]) places + [i1,i2,i3] = zip3 is es [30,20,10]+ row = replicate hcount+ places = [Point (margin m+hsep*x) (margin m+vsep*y+offset)|+ y<-[5,4..1],x<-[0..hcount-1]]+ offset = invHeight m * min 8 startLevel++ centerI (pm@(pm1,_),ex,score) p =+ Inv pm ex score (p + pP ((invWidth m-width pm1) `div` 2) 0)+ hsep = invWidth m+2*bmScale m+ vsep = invHeight m+4*bmScale m+ dx0 = invDx m++--------------------------------------------------------------------------------++type Output = Either Bases (Maybe Score)+type Input = Either Tick Click+type Bases = Drawing () Pict++--getGs = toMs getG+--putLivesMs l = toMsc (putLives l)+--putScoreMs s = toMsc (putScore s)+--putGUIMs g = toMsc (putGUI g)+--puatsGUIMs gs = toMsc (putsGUI gs)++--objectsK :: Size -> World -> Mk (G Input Output) ()+objectsK m world0 = reactiveSP (objectsKs m world0) world0++--objectsKs :: Size -> World -> Ms (G Input Output) World noreturn+objectsKs m world0 = playK+ where+ playK = message low high+ where+ high = either (const tickK) (const newK)++ newK = do set world1+ putGUI (clearRect (Rect 0 (spaceSize m)) True)+ putScore Nothing+ b <- field base+ putLives m (spare (bPict b) (lives b-1))+ where+ world1 = world0{invaders=invs1}+ invs1 = invs0{invs=[],delay=100}+ invs0 = invaders world0++ low ev =+ case ev of+ Redraw -> draw =<< get+ Key Fire Down -> fireTorpedo+ Key a p -> modBase (accelerate p a)++ accelerate pressed button b@ExB{} = b+ accelerate pressed button b@B{bSpeed=v} = b{bSpeed=v'}+ where+ v' = case pressed of Down -> bdir ; _ -> 0+ bdir = case button of+ MoveLeft -> -baseDx m+ MoveRight -> baseDx m+ _ -> 0+ ++ tickK =+ do tickInvadersK+ tickUfoK+ W g shelters base ufo torpedo vshots invaders <- get+ base' <- tickBaseK base+ (torpedo',invaders',shelters',ufo')<-+ tickTorpedoK torpedo invaders shelters ufo+ set (W g shelters' base' ufo' torpedo' vshots invaders')+ tickVShotsK vshots base'++ tickInvadersK =+ do state@W{invaders=inv} <- get+ let t = delay inv-1+ case t of+ 0 -> do let invcnt = length (invs inv)+ l = level inv+1+ offset = pP 0 (invHeight m*(min 8 l-startLevel))+ inv' = if invcnt==0+ then move offset (invaders world0){level=l}+ else inv{delay=(invcnt+6) `div` 4}+ set state{invaders=inv'}+ moveInvadersK+ update fireVShot+ _ -> do let inv' = inv{delay=t}+ set state{invaders=inv'}++ --tickBaseK :: Base -> Ms (G hi (Either Bases x)) s Base+ tickBaseK b@(ExB pm ex p@(Point x y) l t) =+ case t of+ 50 -> putGUI (clearpm p pm) >> return b'{bPos=Point (-width pm) y}+ 95 | l>0 -> putLives m (spare pm (l-2)) >> return b'+ 100 | l>1 -> do let b' = B pm ex (baseStartPos m pm) (l-1) 0+ draw b'+ return b'+ _ -> return b'+ where+ b' = b{exbAge=t+1}+ new = B pm ex+ tickBaseK b@(B pm ex p@(Point x y) l v) =+ case v of+ 0 -> return b+ _ -> putGUI (clearpm p pm) >> draw b' >> return b'+ where b' = B pm ex p' l v+ p' = Point x' y+ x' = min (spaceWidth m-margin m-width pm) (max (margin m) (x+v))++ tickUfoK =+ do state@W{rnd=g,ufo=u@(U pm gc s)} <- get+ let ufoWidth = xcoord (size pm)+ case s of+ Wait 0 -> do let u'=U pm gc (Moving score dx (pP x0 (margin m)))+ score = 50*n+ (x0,dx) = if rev+ then (spaceWidth m,-ufoDx m)+ else (-ufoWidth,ufoDx m)+ (n,g') = randomR (1,6) g+ (rev,g'') = random g'+ draw u'+ set state{rnd=g'',ufo=u'}+ Wait t -> set state{ufo=U pm gc (Wait (t-1))}+ Hit 0 s p -> do putGUI (clearpm p pm)+ set state{ufo=U pm gc (Wait ufoDelay)}+ Hit t s p -> set state{ufo=U pm gc (Hit (t-1) s p)}+ Moving s dx p ->+ if dx>0 && xcoord p>=spaceWidth m ||+ dx<0 && xcoord p< -ufoWidth+ then do putGUI (clearpm p pm)+ set state{ufo=U pm gc (Wait ufoDelay)}+ else do let p' = p + pP dx 0+ u' = U pm gc (Moving s dx p')+ putGUI (clearpm p pm)+ draw u'+ set state{ufo=u'}++ tickTorpedoK t@(T pm optp) inv sh ufo = + case optp of+ Nothing -> return (t,inv,sh,ufo)+ Just p@(Point x y) ->+ if y<torpedoDy m+ then putGUI (clearpm p pm) >> return (T pm Nothing,inv,sh,ufo)+ else case p `invHit` inv of+ (inv1,Inv (p1,_) ex score ip:inv2) ->+ do putsGUI [clear p (torpedoSize m), clearpm ip p1]+ draw exv+ putScore (Just score)+ return (T pm Nothing,inv{invs=inv'},sh,ufo)+ where+ inv' = inv1++exv:inv2+ exv = Exv ex ip+ _ -> case shelterHit' sh r d of+ Just sh' -> do putGUI (clearRect d False)+ return (T pm Nothing,inv,sh',ufo)+ _ -> case Rect p (size pm) `ufoHit` ufo of+ Just ufo'@(U upm _ (Hit _ score up)) ->+ do putGUI (clearpm p pm)+ putGUI (clearpm up upm)+ draw ufo'+ putScore (Just score)+ return (T pm Nothing,inv,sh,ufo')+ _ -> do let t' = move (pP 0 (-torpedoDy m)) t+ putGUI (clearpm p pm)+ draw t'+ return (t',inv,sh,ufo)+ where s = size pm+ r = Rect (p+pP 0 (torpedoDy m `div` 2)) s+ d = Rect (p-pP 1 0) (s+pP 2 0)++ r `ufoHit` U pm gc (Moving s dx p)+ | overlaps r (Rect p (size pm)) = Just (U pm gc (Hit 100 s p))+ r `ufoHit` _ = Nothing++ p `invHit` Invs{invs=is} = break isHit is+ where+ isHit Exv{} = False+ isHit (Inv (p1,_) _ _ ip) = p `inRect` r+ where r = Rect (ip + Point 2 0) (size p1 - Point 4 0)++ fireTorpedo = do a <- field alive+ when a $ do update fire; draw =<< field torpedo+ + fire w@W{torpedo=T gc t} =+ case t of+ Nothing -> w{torpedo=T gc (Just (firePos m (base w)))}+ _ -> w++ fireVShot w@W{vshots=V dy pm@(p1,_) ps,invaders=Invs{invs=is},rnd=g0} =+ if null is || length ps>5 + then w+ else if r<9+ then w{rnd=g1}+ else w{vshots=V dy pm (p:ps),rnd=g'}+ where+ p = Point (x+(invWidth m-width p1) `div` 2) (y+invHeight m-3*bmScale m)+ y = maximum [ycoord p|Inv{invPos=p}<-is,abs (xcoord p-x)<h]+ h = invWidth m `div` 2+ x = xs !! ix+ xs = nub [xcoord p|Inv{invPos=p}<-is]+ + (ix,g') = randomR (0,length xs-1) g1+ (r,g1) = randomR (0,9::Int) g0+ + tickVShotsK (V dy pm@(p1,_) ps) base =+ do ps0' <- mapM moveVShot ps+ w <- get+ set w{vshots=V dy pm [p|Just p<-ps0']}+ where+ br = Rect (bPos base) (size base)++ v = pP 0 dy+ ss@(Point w h) = size p1++ moveVShot p =+ if hitBase+ then do putGUI (clearpm p p1)+ let base' = exBase base+ draw base'+ modBase (const base')+ return Nothing+ else do sh <- field shelters+ case shelterHit' sh hr dr of+ Just sh' -> do w<-get+ set w{shelters=sh'}+ putGUI (clearRect dr False)+ --draw sh'+ return Nothing+ _ -> if ycoord p' < spaceHeight m+ then do putsGUI [clearpm p p1,wDraw (V1 dy pm p')]+ return (Just p')+ else do putGUI (clearpm p p1)+ return Nothing+ where+ p' = p+v+ sr = Rect p ss+ hr = move (pP 0 (dy-h)) sr+ dr = sr+ hitBase = overlaps br sr++ moveInvadersK =+ do w@W{invaders=invs0,shelters=ss} <- get+ let (movecmds,br',invs') = moveInvaders invs0+ putsGUI (concat movecmds)+ ss' <- if any (overlaps br' . shBR) ss+ then let shHit ss i@Inv{} = maybe ss id.shelterHit ss $ rect i+ shHit ss _ = ss+ in return $ foldl shHit ss (invs invs')+ else return ss+ set w{invaders=invs',shelters=ss'}++ moveInvaders (Invs is l dx dt) = (movecmds,br,Invs is' l dx' dt')+ where+ dt' = if null is' then 200 else if off_bottom then -1 else dt+ (dx',d) = if dx>0 && off_right || dx<0 && off_left+ then (-dx,pP 0 (invDy m))+ else (dx,pP dx 0)+ (xs,ys) = unzip [(x,y)|Inv{invPos=Point x y}<-is]+ off_left = min_x < margin m+ off_right = max_x > spaceWidth m-margin m+ off_bottom = max_y > spaceHeight m-margin m+ min_x = minimum xs+ min_y = minimum ys+ max_x = maximum xs + invWidth m+ max_y = maximum ys + invHeight m+ br = if null xs+ then Rect 0 0+ else move d $ line2rect (lL min_x min_y max_x max_y)++ (movecmds,is0') = unzip (map moveInvader is)+ is' = [i|Just i<-is0']++ moveInvader (Exv p1 p) = ([clearpm p p1],Nothing)+ moveInvader (Inv (p1,p2) ex s p) =+ case ycoord d of+ 0 -> ([wDraw i'],Just i')+ _ -> ([clearpm p p1,wDraw i'],Just i')+ where+ i' = Inv (p2,p1) ex s (p+d)++shelterHit ss r = shelterHit' ss r r++shelterHit' ss r d =+ case break (hitSh r) ss of+ (pps1,Sh gc br rs:pps2) ->+ if any (overlaps r) rs && rs' /= rs+ then if null rs'+ then Just (pps1++pps2)+ else Just (pps1++Sh gc br rs':pps2)+ else Nothing+ where+ rs' = concat [diffRect sr d|sr<-rs]+ _ -> Nothing++hitSh r (Sh _ br _) = overlaps r br++--------------------------------------------------------------------------------++draw obj = putGUI (wDraw obj)++instance Draw World where+ drawing w =drawing (ufo w,(shelters w,base w,torpedo w),(vshots w,invaders w))++--instance Draw Shelters where+-- drawing (Sh pps) = pps++instance Draw Shelter where+ drawing (Sh gc (Rect p s) rs) = [pp (rectangles gc s rs) 0]++instance Draw Base where+ drawing (B pm ex p _ _) = [pp pm p]+ drawing (ExB pm ex p _ _) = [pp ex p]++instance Draw Torpedo where+ drawing (T _ Nothing) = []+ drawing (T pm (Just p)) = [pp pm p]++instance Draw Ufo where+ drawing (U pm _ (Moving s dx p)) = [pp pm p]+ drawing (U pm gc (Hit t s p)) = [pp (text gc (show s)) (p+pP 0 (height pm))]+ drawing _ = []++instance Draw Invaders where+ drawing = drawing . invs++instance Draw Invader where+ drawing (Inv (pm,_) _ _ p) = [pp pm p]+ drawing (Exv pm p) = [pp pm p]++instance Draw VShots where+ drawing (V dy pm ps) = drawing [V1 dy pm p|p<-ps]++instance Draw VShot where+ drawing (V1 dy (pm1,pm2) p) = [pp pm p]+ where+ pm = if even (ycoord p `div` dy) then pm1 else pm2++--------------------------------------------------------------------------------+class HasSize a => HasRect a where rect :: a -> Rect++width obj = xcoord (size obj)+height obj = ycoord (size obj)++instance HasSize Base where size = size . bPict+instance HasRect Base where rect (B pm _ p _ _) = Rect p (size pm)++--instance HasSize Torpedo where size _ = torpedoSize++instance HasSize Invader where+ size inv@Inv{invPict=(p1,_)} = size p1+ size inv@Exv{exvPict=p1} = size p1++instance HasRect Invader where+ rect inv = Rect (invPos inv) (size inv)++instance Move Base where move v (B pm ex p l dx) = B pm ex (p+v) l dx+instance Move Torpedo where move v (T pm op) = T pm (move v op)+instance Move Invaders where move v (Invs is l dx dt) = Invs (move v is) l dx dt+instance Move Invader where move v inv@Inv{invPos=p} = inv{invPos=move v p}+instance Move VShots where move v (V dy pm ps) = V dy pm (move v ps)++--------------------------------------------------------------------------------+firePos m base = bPos base + pP (width base `div` 2) (-torpedoHeight m)++shelterSize m = pP (20*bmScale m) (16*bmScale m)++torpedoSize m = pP 1 (torpedoHeight m)+torpedoHeight m = 8*bmScale m+torpedoDy m = 6*bmScale m++ufoDelay = argReadKey "ufodelay" 2500+ufoDx = bmScale++vshotDy m = 2*bmScale m++invHeight m = 8*bmScale m+invWidth m = 12*bmScale m+invDy m = 3*invHeight m `div` 4+invDx = bmScale++margin m = 5*bmScale m+baseDx m = argReadKey "dx" (2*bmScale m-1)::Int -- base speed++hcount = argReadKey "hcount" 11::Int+startLevel = argReadKey "level" 0::Int
+ Demos/Tiles/BoardF.hs view
@@ -0,0 +1,53 @@+module BoardF(boardF) where++import AllFudgets+import DrawingF+import Tiles+import MyUtils++boardF :: F (Either ChangeTileNo [Tile]) a+boardF = marginHVAlignF 0 aCenter aCenter (noStretchF True True (loopLeftF ((Left >^=< gridUF) >==< gridControlF)))++--left :: a -> Either a b+--left x = Left x++gridUF = (gridF,Above) >#+< updateF++updateF = buttonF "update with new current tile"++gridControlF :: F (Either (Either (Int, Event) Click) (Either ChangeTileNo [Tile])) + (Either (Int, ChangeTile) a)+gridControlF =+ let startState = (sameTN, [[]|x<-[0..7]], [NoTile|x<-[0..24]])+ step (cn, ts, ns) m = + -- cn = function to change a tile number+ -- ts = set of rotations/reflections of current tile+ -- ns = tile numbers associated with each grid position+ let toGrid = Left+ in case m of+ -- looped back from Grid+ (Left (Left (n, _))) -> ((cn, ts, nns), ct nn)+ where nn = cn (ns!!n)+ nns = (take n ns) ++ [nn] ++ (drop (n+1) ns)+ ct bt = case bt of+ NoTile -> []+ TileNo t -> [toGrid (n,changeToT (ts!!t))]+ -- looped back from Update button+ (Left (Right Click)) -> ((cn, ts, ns), changeAll)+ where changeAll = [ct n | n <- [0..24]]+ ct n = case (ns!!n) of+ NoTile -> toGrid (n, sameT)+ TileNo t -> toGrid (n, changeToT (ts!!t))+ -- from Tools+ (Right (Left ncn)) -> ((ncn, ts, ns), [])+ -- from Choice+ (Right (Right nts)) -> ((cn, nts, ns), [])+ in absF (mapstateSP step startState)++gridF :: F (Int, ChangeTile) (Int, Event)+gridF = + let b v = drawDisplayCF (Point 50 50) v+ tiles = [ (x, b []) | x <- [0..24] ]+ layout = matrixP' 5 Horizontal 0+ in listLF layout tiles+
+ Demos/Tiles/ChoiceF.hs view
@@ -0,0 +1,31 @@+module ChoiceF(choiceF) where++import Fudgets+import RadioDrawF+import Tiles+import MyUtils++choiceF = marginHVAlignF 0 aCenter aCenter (noStretchF True True choice')+choice' = loopLeftF (throRight (radioDrawDF layout choices) >==< choiceControlF)++layout = verticalP++choices = [tile n | n <- [0..3]]++choiceControlF :: F (Either (Int, Tile) Tile) + (Either (Int, Tile) (Either Tile (Either [Tile] [Tile])))+choiceControlF =+ let startstate = 0+ step c m = + let toButtons = Left+ toDesign = Right. Left+ toTools = Right. Right. Left+ toBoard = Right. Right. Right+ in case m of+ -- from Buttons+ (Left (n, t)) -> (n, [toDesign t, toTools (setT t), + toBoard (setT t)])+ -- from Design+ (Right t) -> (c, [toButtons (c, t), toTools (setT t),+ toBoard (setT t)])+ in absF (mapstateSP step startstate)
+ Demos/Tiles/DesignF.hs view
@@ -0,0 +1,74 @@+module DesignF(designF) where++import AllFudgets+import DrawingF+import MyUtils+import Tiles++data DesignState = Init | Start Point++designSize = 250+gridNo = 10++designF :: F Tile Tile+designF = marginHVAlignF 0 aCenter aCenter (loopLeftF ((throRight padF) >==< designControlF))++padF = (drawDisplayCKF (Point designSize designSize) gridlines,Above)+ >#+< updateBF++updateBF = buttonF "finished design -> current tile"++designControlF :: F (Either (Either Event Click) Tile) (Either (Either ChangeTile a) Tile)+designControlF = + let startstate = ([], Init)+ step (c, s) m = + let grid = gridlines + grow = magT dtRatio+ toDesign = Left. Left. changeToT+ toChoice = Right+ in case m of+ -- from the grid+ (Left (Left (ButtonEvent _ ap _ _ Pressed (Button b)))) -> (+ let p = snap ap + in case s of+ Init -> ((c, Start p), [toDesign ((mark p)++(grow c))])+ Start f -> ((newDraw, Init), [toDesign (grow newDraw)])+ where newDraw = case b of+ 3 -> delLine x1 y1 x2 y2 c+ otherwise -> (line x1 y1 x2 y2) ++ c+ Point x1 y1 = scalePoint tdRatio f+ Point x2 y2 = scalePoint tdRatio p )+ -- from the update button+ (Left (Right Click)) -> ((c, s), [toChoice c])+ -- from Choice+ (Right t) -> ((t, Init), [toDesign (grow t)])+ in absF (mapstateSP step startstate)++snap :: Point -> Point+snap p = sp+ where sp = Point sx sy+ sx = ((px+halfGridSize) `div` gridSize) * gridSize+ sy = ((py+halfGridSize) `div` gridSize) * gridSize+ Point px py = p ++delLine _ _ _ _ [] = [] +delLine x1 y1 x2 y2 (c:cs) = + let rest = delLine x1 y1 x2 y2 cs+ in case c of+ DrawLine (Line (Point x3 y3) (Point x4 y4)) -> + if ((x1==x3) && (y1==y3) && (x2==x4) && (y2==y4)) ||+ ((x1==x4) && (y1==y4) && (x2==x3) && (y2==y3))+ then rest else c:rest+ otherwise -> c:rest++mark p = circle x y (designSize `div` 50)+ where Point x y = p++gridlines = concat [(line (l*gridSize) 0 (l*gridSize) designSize) +++ (line 0 (l*gridSize) designSize (l*gridSize)) | + l <- [1..(gridNo-1)]]++gridSize = designSize `div` gridNo+halfGridSize = gridSize `div` 2+tdRatio = (fromIntegral tileSize) / (fromIntegral designSize)+dtRatio = designSize `div` tileSize
+ Demos/Tiles/DrawingF.hs view
@@ -0,0 +1,107 @@+module DrawingF where++import AllFudgets+import MyUtils++{-+drawDisplayF size drawing =+ let startcmds = [ ConfigureWindow [CWBorderWidth 0],+ layoutRequestCmd (plainLayout size True True),+ ChangeWindowAttributes [ CWEventMask [ExposureMask]+ --,CWBackingStore WhenMapped+ ]+ ]+ in windowF startcmds (drawDisplayK drawing)++drawDisplayK drawing =+ wCreateGC rootGC [GCFunction GXcopy] (\gc -> drawDisplayP gc drawing)++drawDisplayP gc drawing0 =+ let draw drawing = map (Low . Draw MyWindow gc) drawing+ in let step drawing msg =+ case msg of+ Low (Expose _ 0) -> (drawing, draw drawing)+ High drawing' -> (drawing',Low ClearWindow:(draw drawing'))+ _ -> (drawing,[])+ in putsK (draw drawing0) $ mapstateSP step drawing0+-}+------++drawDisplayCF size drawing =+ let startcmds = [ XCmd $ ConfigureWindow [CWBorderWidth 0],+ layoutRequestCmd (plainLayout size True True),+ XCmd $ ChangeWindowAttributes [ CWEventMask [ExposureMask+ ,ButtonPressMask]+ --,CWBackingStore WhenMapped+ ]+ ]+ in windowF startcmds (drawDisplayCK drawing)++drawDisplayCK drawing =+ wCreateGC rootGC [GCFunction GXcopy] (\gc -> drawDisplayCP gc drawing)++drawDisplayCP gc drawing0 =+ let draw drawing = map (Low . wDraw gc) drawing+ in let step drawing msg =+ case msg of+ Low (XEvt (Expose _ 0)) -> (drawing, draw drawing)+ High drawingf' -> let drawing' = drawingf' drawing+ in (drawing',Low (XCmd ClearWindow):(draw drawing'))+ Low (XEvt (ButtonEvent t x y m Pressed b)) -> + (drawing,High (ButtonEvent t x y m Pressed b):(draw drawing))+ _ -> (drawing,[])+ in putsK (draw drawing0) $ K $ mapstateSP step drawing0++------++drawDisplayCKF size drawing =+ let startcmds = [ XCmd $ ConfigureWindow [CWBorderWidth 0],+ layoutRequestCmd (plainLayout size True True),+ XCmd $ ChangeWindowAttributes [ CWEventMask [ExposureMask+ ,ButtonPressMask]+ --,CWBackingStore WhenMapped+ ]+ ]+ in windowF startcmds (drawDisplayCKK drawing)++drawDisplayCKK drawing =+ wCreateGC rootGC [GCFunction GXcopy] (\gc -> drawDisplayCKP gc drawing)++drawDisplayCKP gc drawing0 =+ let draw drawing = map (Low . wDraw gc) (drawing0++drawing)+ in let step drawing msg =+ case msg of+ Low (XEvt (Expose _ 0)) -> (drawing, draw drawing)+ High drawingf' -> let drawing' = drawingf' drawing+ in (drawing',Low (XCmd ClearWindow):(draw drawing'))+ Low (XEvt (ButtonEvent t x y m Pressed b)) -> + (drawing,High (ButtonEvent t x y m Pressed b):(draw drawing))+ _ -> (drawing,[])+ in putsK (draw []) $ K $ mapstateSP step drawing0++------++drawDisplayDF size drawing =+ let startcmds = [ XCmd $ ConfigureWindow [CWBorderWidth 0],+ layoutRequestCmd (plainLayout size True True),+ XCmd $ ChangeWindowAttributes [ CWEventMask [ExposureMask+ ,ButtonPressMask]+ --,CWBackingStore WhenMapped+ ]+ ]+ in windowF startcmds (drawDisplayDK drawing)++drawDisplayDK drawing =+ wCreateGC rootGC [GCFunction GXcopy] (\gc -> drawDisplayDP gc drawing)++drawDisplayDP gc drawing0 =+ let draw drawing = map (Low . wDraw gc) drawing+ in let step drawing msg =+ case msg of+ Low (XEvt (Expose _ 0)) -> (drawing, draw drawing)+ High drawingf' -> let drawing' = drawingf' drawing+ in (drawing',Low (XCmd ClearWindow):(draw drawing'))+ Low (XEvt (ButtonEvent _ _ _ _ Pressed _)) -> + (drawing,High (drawing):(draw drawing))+ _ -> (drawing,[])+ in putsK (draw drawing0) $ K $ mapstateSP step drawing0
+ Demos/Tiles/Main.hs view
@@ -0,0 +1,38 @@+module Main(main) where++import Fudgets+import BoardF+import ToolsF+import ChoiceF+import Tiles+import DesignF+import MyUtils++main = fudlogue (shellF "Escher" escherF)++escherF = placerF (revP (horizontalP' 10)) (playF >==< workF)++playF :: F (Either [Tile] [Tile]) c+playF = vBoxF (boardF >==< throRight toolsF)++workF :: F b (Either [Tile] [Tile])+workF = loopLeftF (hBoxF (worka >==< workb))++workb :: F (Either Tile c) (Either Tile (Either [Tile] [Tile]))+workb = choiceF >=^< fromLeft++worka :: F (Either Tile a) (Either Tile a)+worka = throRight (designF)++{--- older versions: ---++escherF = (playF >==#< (10, LRightOf, workF)) >==#< (10, LRightOf, quitButtonF)++playF = (boardF,Above) >#==< throRight toolsF++workF = loopLeftF ((worka,LeftOf) >#==< workb)++fromLeft :: Either a b -> a+fromLeft (Left x) = x++--}
+ Demos/Tiles/MyUtils.hs view
@@ -0,0 +1,11 @@+module MyUtils where++import Fudgets++throRight :: F a b -> F (Either a c) (Either b c)+throRight = idRightF++line x1 y1 x2 y2 = [DrawLine (Line (Point x1 y1) (Point x2 y2))]++circle x y r =+ [FillArc (Rect (psub (Point x y) (Point r r)) (Point (2*r) (2*r))) 0 (64*360)]
+ Demos/Tiles/RadioDrawF.hs view
@@ -0,0 +1,44 @@+module RadioDrawF(radioDrawCF, radioDrawDF) where++import AllFudgets+import ToggleDrawGroupF+import Tiles+import MyUtils++radioDrawCF l c = loopLeftF (throRight (toggleDrawGroupCF l c) + >==< radioControlCF)++radioControlCF :: F (Either (Int, Event) (Int, Tile)) + (Either (Int, (Either Bool ChangeTile)) (Int, Event))+radioControlCF = + let outsideC n e = High (Right (n, e))+ toggleButC n b = High (Left (n, Left b))+ changeButC n d = High (Left (n, Right (changeToT d)))+ startStateC = 0+ press = ButtonEvent 0 (Point 0 0) (Point 0 0) [] Pressed (Button 1)+ firstMsgC = [toggleButC 0 True, outsideC 0 press]+ stepC c m = case m of+ High (Left (n, b)) -> (n, [toggleButC c False, + toggleButC n True, + outsideC n b])+ High (Right (n, t)) -> (c, [changeButC n t, outsideC c press])+ in putMessagesF firstMsgC $ F $ mapstateSP stepC startStateC+++radioDrawDF l c = loopLeftF (throRight (toggleDrawGroupDF l c) + >==< radioControlDF (head c))++radioControlDF :: Tile -> F (Either (Int, Tile) (Int, Tile)) + (Either (Int, (Either Bool ChangeTile)) (Int, Tile))+radioControlDF t0 = + let outsideD n t = High (Right (n, t))+ toggleButD n b = High (Left (n, Left b))+ changeButD n d = High (Left (n, Right (changeToT d)))+ startStateD = 0+ firstMsgD = [toggleButD startStateD True,+ outsideD startStateD t0]+ stepD c m = case m of+ High (Left (n, t)) -> (n, [toggleButD c False, + toggleButD n True, outsideD n t])+ High (Right (n, t)) -> (c, [changeButD n t])+ in putMessagesF (firstMsgD) $ F $ mapstateSP stepD startStateD
+ Demos/Tiles/Tiles.hs view
@@ -0,0 +1,83 @@+module Tiles where++import AllFudgets+import MyUtils++type Tile = [DrawCommand]+type ChangeTile = (Tile -> Tile)+type ChangeTileNo = (BoardTileNo -> BoardTileNo)+data BoardTileNo = NoTile | TileNo Int++tileSize :: Int+tileSize = 50++-- functions ending in 'T' manipulate tiles+-- functions ending in 'TN' manipulate tile numbers+-- (setT defines the relationship between tiles and tile numbers)++changeToT t = (\x -> t)+changeToTN :: BoardTileNo -> (BoardTileNo -> BoardTileNo)+changeToTN t = (\x -> t)++sameT = (\t -> t)+sameTN :: BoardTileNo -> BoardTileNo+sameTN = (\t -> t)++rotateT :: Tile -> Tile+rotateT [] = []+rotateT (t:ts) = let rest = rotateT ts+ in case t of+ DrawLine (Line (Point x1 y1) (Point x2 y2)) -> + DrawLine (Line (Point (tileSize-y1) x1) (Point (tileSize-y2) x2)):rest+rotateTN tn = case tn of+ NoTile -> NoTile+ otherwise -> let TileNo n = tn+ d = n `div` 4 in+ TileNo (((n+1) `mod` 4) + (d*4))++mirrorVT [] = []+mirrorVT (t:ts) = let rest = mirrorVT ts+ in case t of+ DrawLine (Line (Point x1 y1) (Point x2 y2)) -> + DrawLine (Line (Point (tileSize-x1) y1) (Point (tileSize-x2) y2)):rest+mirrorVTN tn = + case tn of+ NoTile -> NoTile+ otherwise -> let TileNo n = tn+ d = n `div` 4+ m = n `mod` 4 in + TileNo (((d+1) `mod` 2)*4 + m)++mirrorHT [] = []+mirrorHT (t:ts) = let rest = mirrorHT ts+ in case t of+ DrawLine (Line (Point x1 y1) (Point x2 y2)) -> + DrawLine (Line (Point x1 (tileSize-y1)) (Point x2 (tileSize-y2))):rest+mirrorHTN tn = case tn of+ NoTile -> NoTile+ otherwise -> let TileNo n = tn+ d = n `div` 4 in+ TileNo (((d+1) `mod` 2)*4 + ((n+2) `mod` 4))++magT m [] = []+magT m (t:ts) = let rest = magT m ts+ in case t of+ DrawLine (Line (Point x1 y1) (Point x2 y2)) -> + DrawLine (Line (Point (x1*m) (y1*m)) (Point (x2*m) (y2*m))):rest++setT :: Tile -> [Tile]+setT t = [t, rotateT t, (rotateT.rotateT) t, (rotateT.rotateT.rotateT) t,+ mirrorVT t, (rotateT.mirrorVT) t, (rotateT.rotateT.mirrorVT) t,+ (rotateT.rotateT.rotateT.mirrorVT) t]++tile 0 = (line 0 25 25 0) ++ (line 25 50 50 25)+tile 1 = (line 25 0 25 50) ++ (line 0 25 50 25)+tile 2 = (line 0 25 25 0) ++ (line 25 0 25 50) ++ (line 25 50 50 25)+tile 3 = (line 0 25 25 0) ++ (line 25 0 50 25) ++ (line 50 25 25 50) +++ (line 25 50 0 25)+tileRotL = (line 10 25 10 10) ++ (line 10 10 40 10) ++ (line 40 10 40 25) +++ (line 40 25 35 20) ++ (line 40 25 45 20)+tileRotR = mirrorVT tileRotL+tileMirH = (line 25 5 25 45) ++ (line 20 10 25 5) ++ (line 25 5 30 10) +++ (line 20 40 25 45) ++ (line 25 45 30 40)+tileMirV = rotateT tileMirH
+ Demos/Tiles/ToggleDrawGroupF.hs view
@@ -0,0 +1,24 @@+module ToggleDrawGroupF(toggleDrawGroupCF, toggleDrawGroupDF) where++import Fudgets+import DrawingF++--toggleDrawCF :: size -> drawing -> F (Either Bool ChangeTile) Event+toggleDrawCF size init = buttonBorderF 5 (drawDisplayCF size init)++--toggleDrawGroupCF :: layout -> choices +-- -> F (Int, (Either Bool ChangeTile)) (Int, Event)+toggleDrawGroupCF layout choices = + let t v = toggleDrawCF (Point 50 50) v+ toggles = zip [0..((length choices) - 1)] (map t choices)+ in listLF layout toggles++--toggleDrawDF :: size -> drawing -> F (Either Bool ChangeTile) Tile+toggleDrawDF size init = buttonBorderF 5 (drawDisplayDF size init)++--toggleDrawGroupDF :: layout choices +-- -> F (Int, (Either Bool ChangeTile)) (Int, Tile)+toggleDrawGroupDF layout choices = + let t v = toggleDrawDF (Point 50 50) v+ toggles = zip [0..((length choices) - 1)] (map t choices)+ in listLF layout toggles
+ Demos/Tiles/ToolsF.hs view
@@ -0,0 +1,46 @@+module ToolsF(toolsF) where++import Fudgets+import DrawingF+import RadioDrawF+import Tiles+import MyUtils++toolsF = loopLeftF ((throRight (radioDrawCF layout choices)) >==< toolControlF)++layout = matrixP 6 --matrixL 6 Horizontal 5++choices = [[], [], [], []] ++ [tileRotL] ++ [tileRotR] +++ [[], [], [], []] ++ [tileMirH] ++ [tileMirV]++--toolControlF :: F (Either (Int, XEvent) [Tile]) (Either (Int, Tile) ChangeTileNo)+toolControlF = + let toButtons = Left+ toBoard = Right+ startstate = 0+ step c m = case m of+ -- from Buttons+ (Left (n, _)) -> (n, [toBoard (t n)])+ -- from Choice+ (Right nt) -> (c, [toButtons (0, nt!!0),+ toButtons (1, nt!!1),+ toButtons (2, nt!!2),+ toButtons (3, nt!!3),+ toButtons (6, nt!!4),+ toButtons (7, nt!!5),+ toButtons (8, nt!!6),+ toButtons (9, nt!!7)])+ in absF (mapstateSP step startstate)++t 0 = changeToTN (TileNo 0)+t 1 = changeToTN (TileNo 1)+t 2 = changeToTN (TileNo 2)+t 3 = changeToTN (TileNo 3)+t 4 = rotateTN+t 5 = rotateTN . rotateTN . rotateTN+t 6 = changeToTN (TileNo 4)+t 7 = changeToTN (TileNo 5)+t 8 = changeToTN (TileNo 6)+t 9 = changeToTN (TileNo 7)+t 10 = mirrorHTN+t 11 = mirrorVTN
+ Demos/clock/ClockF.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE CPP #-}+module ClockF(clockShellF) where+import AllFudgets+--import DialogueIO hiding (IOError)+import Data.Maybe(fromMaybe)+#ifdef VERSION_old_time+import System.Time(CalendarTime(..))+#else+import Data.Time(TimeOfDay(..),localTimeOfDay,zonedTimeToLocalTime)+#endif++--default(Int)++trace x y = y+--ctr s x = ctrace s (show x) x++data ClockMode = Analog | Digital deriving (Show,Eq)++clockShellF =+ let size = fsize+ gcattrs = [GCFont digFont,+ GCLineWidth width,+ GCCapStyle CapRound]+ clockShellK = safeLoadQueryFont digFont (\font ->+ dynShapeK gcattrs (const [])+ (clockK startMode (digsize font)+ (Point 0 (font_ascent font))+ size))+ menuF = menuAltsF menuFont [Analog,Digital] show -- >=^<Left+ tickF = (Left. Right. Right)>^=<startupF [Just (update,1000)] timerF+ startcmds = map (Low . XCmd) [StoreName "ClockFudget"+ --,ConfigureWindow [CWBorderWidth 5] -- testing+ ]+ route msg =+ case msg of+ Left (Right (Left shape)) -> Left (Left shape)+ Left (Right (Right pop)) -> Right pop+ Right mode -> Left (Right (Left mode))+ in loopOnlyF (route>^=<shellKF (putsK startcmds clockShellK) menuF)>==<tickF++clockK :: ClockMode -> Size -> Point -> Size -> K (Either ClockMode Tick) (Either (Point->[DrawCommand]) PopupMenu)+clockK dig digsize bp size =+ let clockP dig size =+ let redraw s t = putsK [--Low (ConfigureWindow [CWBorderWidth 5]), -- testing+ High (Left (clockface dig bp t))] (clockP dig s)+ --gettime dig s = putLow (DReq GetLocalTime) (clockP dig s)+#ifdef VERSION_old_time+ gettime dig s = getLocalTime (redraw s)+#else+ gettime dig s = getZonedTime (redraw s)+#endif+ same = clockP dig size+ in getK $ \msg ->+ case msg of+ --Low (Expose _ 0)-> gettime dig size -- ??+ --Low (DResp (Dbl t))-> redraw size t+ Low (XEvt ev@(ButtonEvent _ _ rootpos _ Pressed _)) ->+ putK (High (Right (PopupMenu rootpos ev))) same+ Low (XEvt (ButtonEvent _ _ _ _ Released _))->+ putK (High (Right PopdownMenu)) same+ High (Right _) -> gettime dig size+ High (Left mode) -> if mode==dig+ then same+ else putK (layout mode) (gettime mode size)+ _-> same++ layout mode =+ let s = case mode of+ Digital-> digsize+ Analog-> size+ in Low (layoutRequestCmd (plainLayout s False False))+ layout0 = layout dig+ startcmds =+ [ layout0,+ Low (XCmd $ GrabButton True AnyButton [] [ButtonPressMask,ButtonReleaseMask])+ ]+ in changeBg color (putsK startcmds (clockP dig size))++#ifdef VERSION_old_time+timeofday CalendarTime{ctHour=h,ctMin=min,ctSec=s} =+ let t = s+60*(min+60*h)+ m = itof t / 60.0+ in (fmod (m/60.0) 24.0 ,fmod m 60.0)+#else+timeofday zt = (fmod (m/60.0) 24.0 ,fmod m 60.0)+ where+ t = round s+60*(min+60*h)+ m = itof t / 60+ TimeOfDay h min s = localTimeOfDay (zonedTimeToLocalTime zt)+#endif++clockface mode bp t size =+ case mode of+ Digital-> [DrawString bp (digits t)]+ Analog-> hands t size ++ scalemarks size++digits t =+ let (h,m) = aboth floor' (timeofday t)+ in show h ++ ":" ++ drop 1 (show (100+m))++hands t size =+ let (h,m) = timeofday t+ in hand h 12 0.6 size ++ hand m 60 0.95 size++hand v d r size =+ let a = v / itof d * 2.0 * pi+ h = scalePoint 0.5 size+ in [DrawLine (Line h (toRect r h a))]++scalemarks size =+ let r = scalePoint 0.5 size+ w2 = width*2+ in let mark n =+ let a = itof n*pi/6.0+ in Rect (psub (toRect 0.9 r a) (Point width width)) (Point w2 w2)+ in [FillArc (mark n) 0 (64*360) | n<-[0..11]]++toRect k (Point w h) r = Point (w+floor' (k*itof w*sin r)) (h+floor' (k*itof (-h)*cos r))++fmod :: Double -> Double -> Double+fmod a b =+ let y = a - b * fromIntegral (floor' (a/b))+ in {-if y<0.0 && argFlag "floor" False + then trace (show (a,b,y)) y+ else -}y++digsize font = string_box_size font "88:88"++width = argReadKey "width" 10+fsize = fromMaybe (diag (argReadKey "size" 200)) defaultSize+color = argKey "color" "gold"+update = (argReadKey "update" 20) * 1000+startMode = if argKey "mode" "analog" == "digital" then Digital else Analog+digFont = defaultFont++itof=fromIntegral++rightadj s n pad = [pad|i<-[length s+1..n]]++s++floor' x = floor x+-- Solves a problem on slip-02 with direct calls to PfloorDouble2Int. TH 970314.
+ Demos/clock/fudgetclock.hs view
@@ -0,0 +1,5 @@+module Main where+import Fudgets+import ClockF++main = fudlogue clockShellF
+ Demos/graph/Compat.hs view
@@ -0,0 +1,18 @@+--+-- Library with LML compatible functions.+--+module Compat where+import Data.Char(isAlpha,isDigit)++mix :: [[a]] -> [a] -> [a]+mix [] d = []+mix (x:xs) d = x++case xs of [] -> []; _ -> d ++ mix xs d++takeWord :: String -> (String, String)+takeWord [] = ([],[])+takeWord (' ':cs) = takeWord cs+takeWord ('\n':cs) = takeWord cs+takeWord ('\t':cs) = takeWord cs+takeWord (c:cs) | isAlpha c = let (w,cs') = span (\c->isAlpha c || isDigit c || c=='_') cs in (c:w,cs')+ | isDigit c = let (w,cs') = span isDigit cs in (c:w, cs')+ | otherwise = ([c], cs)
+ Demos/graph/Diff.hs view
@@ -0,0 +1,42 @@+module Diff(diff,diffCmd) where+import Exp+import Ops+import Simp++diffCmd cmd =+ case cmd of+ Fun e -> Fun (diff e)+ Approx a n e -> Approx a n (diff e)++diff e =+ case e of+ Var -> one+ Const _ -> zero'+ Pow b e -> ce e `mul` diff b `mul` pow b (e-1)+ Binop bop e1 e2 -> diffbinop bop e1 e2+ Unop uop e -> mul (diff e) (uopdiff uop e)+++diffbinop bop e1 e2 =+ case bop of+ Badd -> add (diff e1) (diff e2)+ Bsub -> sub (diff e1) (diff e2)+ Bmul -> add (mul e1 (diff e2)) (mul (diff e1) e2)+ Bdiv -> div' (sub (mul (diff e1) e2) (mul e1 (diff e2))) (mul e2 e2)+ _ -> unimpl+++uopdiff unop e =+ case unop of+ Uneg -> neg one+ Usin -> Unop Ucos e+ Ucos -> neg (Unop Usin e)+ Uexp -> Unop Uexp e+ Utan -> add one (mul (Unop Utan e) (Unop Utan e))+ Uln -> inv e+ Uabs -> Unop Usgn e+ _ -> unimpl+++unimpl = error "Unimplemented diff\n"+
+ Demos/graph/Eval.hs view
@@ -0,0 +1,28 @@+module Eval where+import Exp+import Ops+--import List(union)++eval e =+ case e of+ Var -> id+ Const k -> const k+ Pow b e -> let bv = eval b+ in \ x -> bv x ^^ e+ Binop bop e1 e2 ->+ let f = binopfun bop+ v1 = eval e1+ v2 = eval e2+ in \x -> f (v1 x) (v2 x)+ Unop unop e ->+ let f = unopfun unop+ in f . eval e++{-+freevars e =+ case e of+ Var x -> [x]+ Const _ -> []+ Binop _ e1 e2 -> union (freevars e1) (freevars e2)+ Unop _ e -> freevars e+-}
+ Demos/graph/Exp.hs view
@@ -0,0 +1,29 @@+module Exp where+import Ops++data Cmd+ = Fun Exp+ | Approx Approx Int Exp++data Approx = Trapets | RectU | RectO++--type Id = (Char, Int)++type Value = Double++data Exp+ = Var+ | Const Value+ | Pow Exp Int+ | Binop Bop Exp Exp+ | Unop Uop Exp+ deriving (Eq)++{-+stoid :: String -> Id+stoid (a:ds) = (a,read ds)++idtos :: Id -> String+idtos (c,n) = c:show n++-}
+ Demos/graph/ExpF.hs view
@@ -0,0 +1,42 @@+module ExpF(expF) where+import Fudgets+import Show+import Parser+import Lex+import Diff+import Exp(Exp)++expF =+ noStretchF False True $+ loopLeftF (toBothF>==<((throughExpInputF,LeftOf)>#==<diffF))+ --loopLeftF (toBothF>==<(throughExpInputF>==<diffF))++throughExpInputF = stripEither >^=< throughF expInputF++expInputF =+ concatMapF parse>==<+ (inputDoneSP>^^=<spacerF vCenterS (labLeftOfF "f(x)=" stringF))>=^<+ show_Cmds++parse s =+ case (cmds . lex') s of+ Right (e,[])-> [e]+ _ -> [] -- should generate error message++diffF = map diffCmd>^=<+ (bufSP>^^=<+ (idF>+<buttonF "Derivate"))++bufSP =+ let buf b =+ getSP $ \x->+ case x of+ Left d -> buf (Just d)+ Right _ -> case b of+ Nothing -> buf b+ Just d -> putSP d $ buf b+ in buf Nothing++++
+ Demos/graph/Graph.hs view
@@ -0,0 +1,46 @@+import Fudgets+import PlotF+import ExpF+import Exp(Cmd(..))+import Eval+import Root+import Show(showf,showp)++main = fudlogue $ shellF' (setSizing Static) "Graph" $+ if argFlag "namel" True+ then nameLayoutF layout mainF+ else mainF++layout = v [l f,+ l gr,+ h [v [--l p,+ l a]{-,l q-}]]+ where --al = alignSepNL 0 aCenter aCenter+ h = hBoxNL+ v = vBoxNL+ l = leafNL++f:gr:a:p:q:_ = map show [(1::Int)..]+ +mainF = --nameF q (stubF quitButtonF)>==<+ (nameF a showareaF>+<nullF{-nameF p showpointF-})>==<+ nameF gr grF>==<+ nameF f funcF++funcF =(Left . map evalr)>^=<expF+ where+ evalr cmd =+ case cmd of+ Fun e -> RFunc (eval e,root e)+ Approx a n e -> RLines a n (eval e)++grF = plotF Nothing++showareaF = displayF >=^<showarea+--showpointF = displayF >=^<showp++showarea (xa,(y1,y2)) =+ "x: " ++ showinterval xa ++ ", y: " ++ showinterval (y2,y1)++showinterval (a,b) = "[" ++ showf a ++ ", " ++ showf b ++ "]"+
+ Demos/graph/Lex.hs view
@@ -0,0 +1,23 @@+module Lex where+import HbcUtils(chopList,breakAt)+import Compat(takeWord)+import Data.Char++lex' = lexfix . filter (/=[]) . chopList taketoken++lexfix [] = []+lexfix (a:".":b:xs) = if isDigit (head a) && isDigit (head b)+ then (a++"."++b):lexfix xs+ else a:".":lexfix (b:xs)+lexfix (x:xs) = x:lexfix xs++-- taketoken = takeword++taketoken [] = ([],[])+taketoken ccs@(c:cs) =+ case c of+ '\"' -> let (s,rest) = breakAt '"' cs+ in (c:s,rest)+ _ -> takeWord ccs++
+ Demos/graph/Ops.hs view
@@ -0,0 +1,87 @@+module Ops(Bop(..),Uop(..),unops,addops,mulops,binoplex,binopfun,unoplex,unopfun,+ show_Bop,show_Uop,addopt,mulopt{-,powopt-})+where++data Bop = Badd | Bsub | Bmul | Bdiv | Bmin -- | Bpow+ deriving (Eq)++data Uop = Uneg | Usin | Ucos | Utan | Uexp | Ulog | Uln | Usqrt |+ Uabs | Ufloor | Uceil | Uround | Utanh | Ucosh | Usinh | Ugamma |+ Uatan | Uacos | Uasin | Usgn | Utheta+ deriving (Eq)++assocdef x xs e = maybe e id $ lookup x xs++binoplex binop = fst (assocdef binop binoptab (error "undefined binop"))+binopfun binop = assocdef binop (map snd binoptab) (error "undefined binop")++binoptab = addopfuncs ++ mulopfuncs -- ++ powopfuncs++addopfuncs =+ [("+",(Badd,(+))),+ ("-",(Bsub,(-)))+ ]++mulopfuncs =+ [("*",(Bmul,(*))),+ ("/",(Bdiv,(/))),+ ("!",(Bmin,min))+ ]++{-+powopfuncs =+ [("^",(Bpow,pow))+ ]+-}++addops = map fst addopfuncs+mulops = map fst mulopfuncs+--powops = map fst powopfuncs++addopt = map (fst . snd) addopfuncs+mulopt = map (fst . snd) mulopfuncs+--powopt = map (fst . snd) powopfuncs++unoplex unop = fst (assocdef unop unoptab (error "undefined unop"))+unopfun unop = assocdef unop (map snd unoptab) (error "undefined unop")++unoptab =+ [("-",(Uneg,negate)),+ ("sin",(Usin,sin)),+ ("cos",(Ucos,cos)),+ ("tan",(Utan,tan)),+ ("exp",(Uexp,exp)),+ ("log",(Ulog,log)),+ ("ln",(Uln,log)),+ ("log",(Uln,log)),+ ("sqrt",(Usqrt,sqrt)),+ ("fabs",(Uabs,abs)),+ ("abs",(Uabs,abs)),+ ("floor",(Ufloor,fromIntegral.floor)),+ ("round",(Uround,fromIntegral.round)),+ --("ceil",(Uceil,ceil)),+ ("tanh",(Utanh,tanh)),+ ("cosh",(Ucosh,cosh)),+ ("sinh",(Usinh,sinh)),+ --("gamma",(Ugamma,gamma)),+ ("atan",(Uatan,atan)),+ ("acos",(Uacos,acos)),+ ("asin",(Uasin,asin)),+ ("sgn",(Usgn,sgn)),+ ("theta",(Utheta,theta))+ ]++theta :: Double->Double+theta x = if x<0.0 then 0.0 else 1.0+sgn x = theta x - theta (0.0-x)++--pow x y = exp (y * log x)+--pow x y = x**y+--pow x y = x^^y++unops = map fst unoptab++show' tab x = assocdef x (map (\(x,(y,_))->(y,x)) tab) (error "show' in Ops.hs")++show_Uop = show' unoptab+show_Bop = show' binoptab
+ Demos/graph/Parser.hs view
@@ -0,0 +1,64 @@+module Parser(parse_Exp,expr,cmds,complete) where+import Parsop+import Exp+import Ops+import Compat(mix)+import Data.Char++cmds = seq' cmd (lit ",")++cmd+ = (lit "A" +<+ approx +++ int +++ expr ==> approxcmd)+ ||| (expr ==> Fun)+ where+ approxcmd ((a,n),e) = Approx a n e++approx+ = (lit "t" ==> const Trapets)+ ||| (lit "u" ==> const RectU)+ ||| (lit "o" ==> const RectO)++parse_Exp = complete . expr++--exprs = seq' expr (lit ",")+expr = leftAssoc term addop++term = leftAssoc factor mulop++factor = (aexp +++ optexponent) ==> (%%) (flip id)++aexp+ = num+ ||| var + ||| ((unop +++ factor) ==> (%%) Unop)+ ||| (lit "(" +<+ expr +>+ lit ")")++mulop = is (\t->elem t mulops) ==> binoplex+addop = is (\t->elem t addops) ==> binoplex+unop = is (\t->elem t unops) ==> unoplex+--ident = is iscellid ==> stoid+var = lit "x" ==> const Var+num = is (isDigit . head) ==> (Const . readf)++optexponent = cond exponent id+ where+ exponent = (lit "^" +<+ int) ==> (flip Pow)++int = is (all isDigit) ==> read++leftAssoc item op = item +++ (***) (op +++ item) ==> (%%) tree++tree e1 [] = e1+tree e1 ((op,e2):oes) = tree (Binop op e1 e2) oes++iscellid (c1:cs) = cs/=[] && isAlpha c1 && all isDigit cs++readf :: String -> Double+readf s = if '.' `elem` s then read s else read (s++".0")++complete ts =+ case ts of+ Right(e,[])->Right e+ Left ts-> Left ("Syntax error before: " ++ mix (take 10 ts) " ")+ Right(_,ts)-> Left ("Trailing garbage: " ++ mix (take 10 ts) " ")+
+ Demos/graph/Parsop.hs view
@@ -0,0 +1,83 @@+module Parsop where+infixl |||, +++, +>+, +<++{-+infix "==>";+prefix "***";+infix "+<+";+infix "+>+";+infix "iff";+prefix "%%";+-}+{-+export empty,+-- matches the empty string+ +++,+-- sequence, returns a pair+ |||,+-- alternative+ is,+-- terminal tested with a predicate+ `,+-- terminal tested with equality+ ***,+-- 0 or many (transitive closure)+ +<+,+-- sequence, throw away first part+ +>+,+-- sequence, throw away second part+ ==>,+-- transform+ cond,+-- 0 or one+ seq',+-- sequence of 0 or many with a separator+ seq1,+-- sequence of 1 or many with a separator+ iff,+-- conditional+ %%;+-- uncurry+-}+trycase pf fail succeed ws=+ case pf ws of+ Left _ -> fail ws+ Right(x,ws) -> succeed x ws+++failure ws= Left ws+success x ws = Right(x,ws)++try pf cont = trycase pf failure cont++is p [] = Left []+is p (w:ws) = if p w+ then Right(w,ws)+ else Left (w:ws)++lit w = is (==w)++pf1 +++ pf2 = try pf1 (\x ->try pf2 (\y -> success(x,y)))++pf1 ||| pf2 = trycase pf1 pf2 success++pf ==> f = try pf (success . f)++(***) pf = ((pf +++ (***) pf) ==> (%%) (:)) ||| success []++sep +<+ pf1 = (sep +++ pf1) ==> snd+pf1 +>+ sep = (pf1 +++ sep) ==> fst++--seq1 pf sep = ((pf +++ (sep +<+ seq1 pf sep)) ==> %% (.)) ||| (pf ==> (:[]))+seq1 pf sep = (pf +++ ((sep +<+ seq1 pf sep) ||| empty [])) ==> (%%) (:)++seq' pf sep = seq1 pf sep ||| empty []++empty = success++cond pf x = pf ||| empty x++pf `iff` p = try pf (\x -> if p x+ then success x+ else failure)++(%%) = uncurry
+ Demos/graph/PlotF.hs view
@@ -0,0 +1,201 @@+module PlotF+ (plotF,ToPlot(..),Area(..),Interval(..),Func(..))+ where+import AllFudgets+import Data.List(sortBy)+import Data.Maybe(fromMaybe)+import ZoomF+import HbcUtils(apSnd)+import UserCoords+import Exp(Approx(..))++data Plot = Grid | Axes | Functions [Double->Double] | Lines [(Double,Double)]++plotReal size0 area plot = FlexD size0 False False draw+ where+ draw (Rect p size) = move p (drawgraph size area plot)++gridstep w xa h ya = max (gridstep' w xa) (gridstep' h (swap ya))+ where+ gridstep' w (x0,x1) =+ if mag>=minstep+ then mag+ else if mag2>=minstep+ then mag2+ else if mag5>=minstep+ then mag5+ else mag10+ where+ maxcnt = w `div` 8+ minstep = d / fromIntegral maxcnt+ mag = 10^^floor (log10 minstep)+ mag2 = 2*mag+ mag5 = 5*mag+ mag10 = 10*mag+ d = x1-x0+++drawgraph (Point w h) (xa,ya) plot =+ case plot of+ Grid -> drawgrid+ where+ drawgrid = hlines++vlines+ d = gridstep w xa h ya+ hlines = [DrawLine (lL 0 y xh y) |+ let lo=ceiling' d (snd ya),+ yu<-[lo,lo+d .. floor' d (fst ya)],+ let y=wdw h ya yu]+ vlines = [DrawLine (lL x 0 x yh) |+ let lo=ceiling' d (fst xa),+ xu<-[lo,lo+d .. floor' d (snd xa)],+ let x=wdw w xa xu]+ Axes -> drawaxes+ where+ drawaxes =+ [DrawLine (lL 0 y0 xh y0),+ drawLines [pP (xh-d) (y0-d),pP xh y0,pP (xh-d) (y0+d)],+ DrawLine (lL x1 (y0-d) x1 (y0+d)),+ DrawLine (lL x0 0 x0 yh),+ drawLines [pP (x0-d) d,pP x0 0,pP (x0+d) d],+ DrawLine (lL (x0-d) y1 (x0+d) y1)]+ Functions fs -> map drawfunc fs + where+ drawfunc f =+ drawLines [Point wx ((wdw h ya . f . user w xa) wx) | wx<-[0,2..w]]+ Lines ps -> [drawLines [Point (wdw w xa x) (wdw h ya y)|(x,y)<-ps]]+ where+ drawLines = DrawLines CoordModeOrigin+ y0 = wdw h ya 0.0+ y1 = wdw h ya 1.0+ x0 = wdw w xa 0.0+ x1 = wdw w xa 1.0+ yh = h-1+ xh = w-1+ d = 4++ceiling' d x = fromIntegral (ceiling (x/d)) * d+floor' d x = fromIntegral (floor (x/d)) * d+log10 x = log x / log 10++showroot (Point w h) ((xa@(x1,x2)),ya) roots p@(Point wx wy)=+ case sortroots [x | root<-roots, Just x<-[root (user w xa wx) eps]] of+ x:_ -> Popup (pP (wdw w xa x) (wdw h ya 0.0)) ("x=" ++ show x)+ [] -> Popup p "No root?"+ where+ sortroots = sortBy cmpdist+ cmpdist x1 x2 = compare (dist x1) (dist x2)+ dist x = abs (x-x0)+ x0 = user w xa wx+ eps = abs (x0/1.0e10)+ rnd x = real (round (x * r)) / r -- keep approx 5 significant digits+ where r = scaleFloat (17+exponent x) 0.5++rmroot = Popdown++data ToPlot+ = RFunc Func+ | RLines Approx Int (Double->Double)++type Func = (Double->Double,Double->Double->Maybe Double)++zoomDispF size = zoomF dispF+ where+ dispF = graphicsDispGroupF' custom rootDispF+ custom = setInitDisp initD . setSizing Static .+ (setBgColor paper :: (Customiser (GraphicsF a)))+ initD = plotD size startarea []++plotD size area@(xa,_) fs =+ stackD (fgD grid (g gr):+ softAttribD (gcattrs fgColor) (g axes):+ ps)+ where+ ps = zipWith p1 (cycle pens) fs+ p1 pen f = softAttribD (gcattrs pen) (g (p f))+ p :: ToPlot -> FlexibleDrawing+ p (RFunc (f,_)) = plotReal size area (Functions [f])+ p (RLines Trapets n f) = plotReal size area (Lines (trapets xa n f))+ p (RLines RectO n f) = plotReal size area (Lines (rect max xa n f))+ p (RLines RectU n f) = plotReal size area (Lines (rect min xa n f))+ gr = plotReal size area Grid+ axes = plotReal size area Axes+ gcattrs fg = [GCForeground (colorSpec fg), GCLineWidth lw,+ GCCapStyle CapProjecting+ ]++ rect :: (Double->Double->Double)->(Double,Double) -> Int -> (Double->Double) -> [(Double,Double)]+ rect est xa n = vlines . hlines . trapets xa n+ where+ hlines ((x1,y1):ps@((x2,y2):_)) = (x1,x2,est y1 y2):hlines ps+ hlines _ = []++ vlines [] = []+ vlines ((x1,x2,y):hs) = (x1,y):(x2,y):vlines' y hs++ vlines' y [] = []+ vlines' y ((x1,x2,y2):hs) =+ if y==y2+ then (x2,y2):vlines' y2 hs+ else (x1,y2):(x2,y2):vlines' y2 hs++ trapets :: (Double,Double) -> Int -> (Double->Double) -> [(Double,Double)]+ trapets (x1,x2) n f = [pairwith f (x i)|i<-[0..n]]+ where+ x i = x1+dx*fromIntegral i+ dx = (x2-x1)/fromIntegral n++startarea = ((-6.5,6.5),(6.5,-6.5))++--plotF :: Maybe Size -> F (Either [Func] Area) (Either Area (Double,Double))+plotF optsize =+ loopThroughRightF ctrlF (zoomDispF size)+ where+ size = fromMaybe (Point 400 400) optsize++ --f0 x = 0.0 -- dummy+ --r0 x dx = Just x -- dummy+ state0 = (startarea,[])++ plot area funcs = replaceAllGfx $ plotD size area funcs++ toGfx = Left . Right+ toDisp = toGfx . Left+ toRootDisp = toGfx . Right++ ctrlF = putF (Right (Left startarea)) $ mapstateF ctrl state0++ ctrl state@(area,func) = either fromLoop fromOutsize+ where+ output x = apSnd (Right x:)+ same = (state,[])+ redraw area' func' =+ ((area',func'),[toRootDisp rmroot,toDisp (plot area' func')])+ zoom area' = output (Left area') $ redraw area' func+ newfunc f = redraw area f++ fromOutsize = either newfunc zoom+ fromLoop = either fromZoom fromGfx+ fromGfx _ = same++ fromZoom zoomMsg =+ case zoomMsg of+ ZoomIn s p -> zoom (zoomin s p area)+ ZoomOut s p -> zoom (zoomout s p area)+ ZoomRect size (Rect p s) ->+ if s =.> 2+ then zoom (zoomrect (size,area) p (p+s))+ else same+ ZoomPick s p ->+ (state,[toRootDisp (showroot s area [r|RFunc (_,r)<-func] p)])+ ZoomResize _ -> (state,[toRootDisp rmroot])++rootDispF =+ --delayF $+ bubblePopupF (displayF' pm)+ where+ pm = setBorderWidth 0.setMargin 0.setSizing Dynamic. setBgColor "white"++pens = argKeyList "pens" ["blue3","red3","green4","orange"]+grid = argKey "grid" "grey"+paper = argKey "plotpaper" "grey90"+lw = argReadKey "linewidth" 2 -- 0 looks better than 1.
+ Demos/graph/Root.hs view
@@ -0,0 +1,23 @@+module Root where+import Eval+import Diff+import Exp+import Ops(Bop,Uop)++root e x0 dx =+ let f = eval e+ f' = eval (diff e)+ step x = let y'=f' x+ in if y'==0.0+ then Nothing+ else Just (x - f x / y')+ infapproxs x = x:(case step x of+ Nothing -> []+ Just x2 -> infapproxs x2)+ approxs = take 20 (infapproxs x0)+ root (x1:x2:xs) = if abs (x1-x2)<dx+ then Just x2+ else root (x2:xs)+ root _ = Nothing++ in root approxs
+ Demos/graph/Show.hs view
@@ -0,0 +1,57 @@+module Show(show_Exp,show_Cmds,show_Cmd,showf,showp) where+import Exp+import Ops+import Numeric(showGFloat)+import Compat(mix)+--import Printf -- From hbc_library, comment out if not compiling with hbc.++--- hbc version:+--showf x = printf "%.5g" [UDouble x]+--showp (x,y) = printf "(%.5g,%.5g)" [UDouble x,UDouble y]+--- standard version:+--showf = show+showf x = showGFloat (Just 5) x ""+showp (x,y) = "("++show x++","++show y++")"+---++show_Cmds cmds = mix (map show_Cmd cmds) ", "++show_Cmd cmd =+ case cmd of+ Fun e -> show_Exp e+ Approx a n e -> "A "++show_Approx a++" "++show n++" "++show_Exp e++show_Approx Trapets = "t"+show_Approx RectO = "o"+show_Approx RectU = "u"++--show_Exps es = mix (map show_Exp es) ", "+show_Exp e =+ case e of+ Binop Badd e1 e2 -> show_Exp e1 ++ show_Bop Badd ++ show_Exp e2+ Binop bop e1 e2 | bop `elem` addopt -> show_Exp e1 ++ show_Bop bop ++ show_term e2+ Unop uop e | uop==Uneg -> show_Uop Uneg ++ show_term e+ _ -> show_term e++show_term e =+ case e of+ Binop bop e1 e2 | bop `elem` mulopt -> show_term e1 ++ show_Bop bop ++ show_power e2+ _ -> show_power e++show_power e =+ case e of+ Pow b n -> show_aexp b ++ "^" ++ show n+ _ -> show_aexp e++show_aexp e =+ case e of+ Var -> "x"+ Const x -> show x+ Unop uop e | uop/=Uneg -> show_Uop uop ++ show_argexp e+ e -> "(" ++ show_Exp e ++ ")"+++show_argexp e =+ case show_aexp e of+ s@('(' : _) -> s+ s -> " " ++ s
+ Demos/graph/Simp.hs view
@@ -0,0 +1,61 @@+module Simp where+import Exp+import Ops++default(Int)++add (Const x) (Const y) = Const (x + y)+add (Const x) e = add e (Const x)+ -- || add (Unop Uneg e) e2 = sub e2 e -- changes the order of terms, confusing+add e (Unop Uneg e2) = sub e e2+add (Binop Badd e1 e2) e3 = add e1 (add e2 e3)+add e (Binop Bmul (k@(Const _)) e2) | e==e2 = mul (add k one) e+add (Binop Bmul (k1@(Const _)) e1) (Binop Bmul (k2@(Const _)) e2) | e1==e2 = mul (add k1 k2) e1+add e1 e2 = if e2==zero' then e1+ else if e1==e2 then mul two e1+ else Binop Badd e1 e2++sub (Const x) (Const y) = Const (x - y)+sub e1 (Unop Uneg e2) = add e1 e2+sub e1 e2 = if e2==zero' then e1+ else if e1==zero' then Unop Uneg e2+ else if e1==e2 then zero'+ else Binop Bsub e1 e2++mul (Const x) (Const y) = Const (x * y)+mul Var Var = pow Var 2+mul Var (Pow Var n) = Pow Var (n+1)+mul (Pow Var n) Var = Pow Var (n+1)+mul (Pow Var n) (Pow Var m) = Pow Var (n+m)+mul e (Const y) = mul (Const y) e+mul e1 (Unop Uneg e2) = neg (mul e1 e2)+mul (Unop Uneg e1) e2 = neg (mul e1 e2)+mul e1 (Binop Bmul e2 e3) = mul (mul e1 e2) e3+ -- || mul (k1 @ (Const _)) (Binop Bmul (k2 @ (Const _)) e) = mul (mul k1 k2) e+mul e1 e2 = if e1==one then e2+ else if e1==zero' then zero'+ else if e1==minusone then neg e2+ else Binop Bmul e1 e2++div' (Const x) (Const y) = Const (x / y)+div' e1 (Unop Uneg e2) = neg (div' e1 e2)+div' (Unop Uneg e1) e2 = neg (div' e1 e2)+div' (Binop Bmul (Const x) e) (Const y) = mul (Const (x/y)) e+div' e1 e2 = if e2==one then e1+ else Binop Bdiv e1 e2++pow b 0 | b/=zero'= one+pow b 1 = b+pow b e = if b==one then one else Pow b e++neg (Const x) = (Const (0.0 - x))+neg (Unop Uneg e) = e+neg e = Unop Uneg e++inv e = div' one e++zero' = Const 0.0+one = Const 1.0+two = Const 2.0+minusone = neg one+ce = Const . fromIntegral
+ Demos/graph/UserCoords.hs view
@@ -0,0 +1,41 @@+module UserCoords where+import Fudgets(Point(..))++type Interval =(Double,Double)+type Area = (Interval,Interval)++wdw h (u1,u2) u = ftoi' (0.5+(u-u1)/(u2-u1)*real h)+user w (u1,u2) u = (real u-0.5)/real w*(u2-u1)+u1++userp ((Point w h),(xa,ya)) (Point x y) = (user w xa x,user h ya y)+wdwp ((Point w h),(xa,ya)) (x,y) = Point (wdw w xa x) (wdw h ya y)++zoom k (Point w h) (Point x y) (xa,ya) = (zoom2 k w x xa,zoom2 k h y ya)+ where+ zoom2 k tot rel ua@(u1,u2) = (zoom1 k u1 u0,zoom1 k u2 u0)+ where+ u0 = user tot ua rel+ zoom1 k u u0 = k*(u-u0)+u0++zoomin = zoom 0.5+zoomout = zoom 2.0++zoomrect sa p1 p2 =+ let (nx1,ny1) = userp sa p1+ (nx2,ny2) = userp sa p2+ in ((nx1,nx2),(ny1,ny2))++--++real :: Int->Double+real = fromIntegral++ftoi :: Double->Int+ftoi = floor++ftoi' x = let maxint = 32767 -- Xlib limitation+ max = real maxint+ negmax = 0.0-max+ in if x>max then maxint+ else if x<negmax then -maxint+ else ftoi x
+ Demos/graph/ZoomF.hs view
@@ -0,0 +1,84 @@+module ZoomF(ZoomOutput(..),zoomF) where+import AllFudgets++data ZoomOutput+ = ZoomIn Size Point+ | ZoomOut Size Point+ | ZoomRect Size Rect+ | ZoomPick Size Point + | ZoomResize Size+ deriving (Eq,Show)++zoomF fud = groupF startcmds zoomK0 fud+ where+ startcmds = map XCmd $ + [ConfigureWindow [CWBorderWidth 0],+ ChangeWindowAttributes [CWEventMask eventmask],+ clickGrab 1,+ clickGrab 3,+ GrabButton False (Button 2) []+ [ButtonPressMask,+ PointerMotionMask,+ ButtonReleaseMask]]+ clickGrab n = GrabButton False (Button n) [] []+ eventmask = [ButtonPressMask]++ zoomK0 =+ setFontCursor 130 $+ allocNamedColorPixel defaultColormap bgColor $ \ bg ->+ allocNamedColorPixel defaultColormap fgColor $ \ fg ->+ wCreateGC rootGC (GCSubwindowMode IncludeInferiors:+ GCFunction GXxor:+ invertColorGCattrs fg bg) $ \ gcinv ->+ waitForMsg layoutsize $ \ size ->+ zoomK gcinv size+ where+ layoutsize (Low (LEvt (LayoutSize size))) = Just size+ layoutsize _ = Nothing++ zoomK gcinv size =+ getK $ message low high+ where+ same = zoomK gcinv size+ high _ = same+ low event =+ case event of+ XEvt ButtonEvent {pos=p,state=mods} | Shift `elem` mods ->+ put (ZoomPick size p) same+ XEvt ButtonEvent {pos=p,button=Button 1} -> put (ZoomIn size p) same+ XEvt ButtonEvent {pos=p,button=Button 3} -> put (ZoomOut size p) same+ XEvt ButtonEvent {pos=p,button=Button 2,type'=Pressed} ->+ putLow (wDrawRectangle gcinv (Rect p (Point 1 1))) $+ rubberBandK gcinv size p p $ \ size' ->+ zoomK gcinv size'+ --XEvt MotionNotify {} ->+ LEvt (LayoutSize size') ->+ put (ZoomResize size') $+ zoomK gcinv size'+ _ -> same++rubberBandK gcinv size p0 p1 return =+ getK $ message low high+ where+ cont p = rubberBandK gcinv size p0 p return+ resize size' = rubberBandK gcinv size' p0 p1 return+ same = cont p1+ toggle p0 p1 = putLow $ wDrawRectangle gcinv (rect' p0 p1)+ high _ = same+ low event =+ case event of+ XEvt MotionNotify {pos=p} ->+ toggle p0 p1 $+ toggle p0 p $+ cont p+ XEvt ButtonEvent {pos=p,type'=Released,button=Button 2} ->+ toggle p0 p1 $+ put (ZoomRect size (rect' p0 p1)) $+ return size+ LEvt (LayoutSize size') -> resize size'+ _ -> same++rect' p1 p2 =+ let p0 = pmin p1 p2+ p = pmax p1 p2+ in Rect p0 (p-p0+1)
+ Demos/life/Generate.hs view
@@ -0,0 +1,17 @@+module Generate where++import Utils2++generate (bounds,g) = (bounds,newg)+ where (xm,ym) = bounds+ wrap u m = (u+m) `mod` m+ newg = (cond g . foldl insert [] . reverse) [(wrap u xm, wrap v ym) | (x,y) <- g, u <- [x-1..x+1], v <- [y-1..y+1]]+ insert (pn@(p1,n):l) p | p == p1 = (p1,n+1):l+ | p > p1 = pn : insert l p+ insert l p = (p,1) : l+ cond l ((p,n):nbs) = if not lived && n == 3 || lived && (n == 3 || n == 4) then p : rest else rest+ where (l',lived) = mapgen (\l->(l,True)) (flip const) (\l->(l,False)) p l+ rest = cond l' nbs + cond _ [] = []++
+ Demos/life/Life.hs view
@@ -0,0 +1,40 @@+module Life{-(life)-} where+import AllFudgets+import Utils2++life :: Int -> Generation -> F LifeCmds LifeEvts+--life cellsize (bnds,gen) = simpleF "Life" lifeK (topoint s0 bnds) s0+life cellsize (bnds,gen) = simpleWindowF lifeK (topoint s0 bnds) False False s0+ where s0 = (cellsize,bnds,gen)++pointPair (x,y) = Point x y+pairPoint (Point x y) = (x,y)++--fillCircle pos d = let s = Point d d in FillArc (Rect pos s) 0 (64 * 360)++lifeK draw clear s event = + case event of+ High (NewCell (pos,l)) -> (s1, pattern s1 pos l) where s1 = sGen (setgen l pos (gen s)) s+ High (NewGen (nb,ng)) -> (s1, redrawgen s1) where s1 = sGen ng (sBnds nb s)+ High (NewCellSize ncs) -> (s1,[(High . NewBounds . topos s1 . topoint s . bnds) s]) where s1 = sCellsize ncs s+ Low (XEvt (Expose _ 0)) -> (s,redrawgen s)+ Low (XEvt (ButtonEvent _ p _ _ Pressed _)) -> (s,[(High . MouseClick . topos s) p])+ Low (LEvt (LayoutSize nsize)) -> (s, [(High . NewBounds . topos s) nsize])+ _ -> (s,[])++ where+ pattern s p l = map (Low . (if l then draw else clear)) [fillCircle (topoint s p) (truncate (cellsize s))]+ redrawgen s = Low (XCmd ClearWindow) : concat [pattern s p True | p <- gen s] ++ [Low $ XCmd Flush]++topoint s = scalePoint (cellsize s) . pointPair+topos s = pairPoint . scalePoint (1 / (cellsize s))++cellsize (cs,b,g) = (fromIntegral cs)+bnds (cs,b,g) = b+gen (cs,b,g) = g+xm = fst . bnds+ym = snd . bnds++sCellsize cs1 (cs,b,g) = (cs1,b,g)+sBnds b1 (cs,b,g) = (cs,b1,g)+sGen g1 (cs,b,g) = (cs,b,g1)
+ Demos/life/Main.hs view
@@ -0,0 +1,31 @@+module Main(main,control) where++import Fudgets+import Life+import Utils2+import Panel+import Generate++--import NonStdTrace++main = fudlogue $ shellF "Life" (hBoxF control)++control = loopLeftF ((Left >^=< life defaultcellsize s0) >==< absF (mapstateSP c s0)) >==< panel+ where c state@(bounds@(xm,ym), gen) msg = + case msg of+ Left fromMatrix ->+ case fromMatrix of+ MouseClick p -> ((bounds,newgen), [NewCell (p,newcell)])+ where (newgen,newcell) = togglegen p gen++ NewBounds (b@(xm,ym)) -> redraw (b,[(x,y) | (x,y) <- gen, x < xm, y < ym])+ Right fromPanel ->+ case fromPanel of+ Right newSize -> (state, [NewCellSize newSize])+ Left tick -> redraw (generate state)+ _ -> (state,[])+ redraw ns = (ns,[NewGen ns])+ +bounds0 = (20,20)++s0 = (bounds0,[])
+ Demos/life/Panel.hs view
@@ -0,0 +1,20 @@+module Panel where -- (panel,defaultcellsize) where++import Fudgets+import Timer+{-+quitShell title f = shellF title + (stripEither >^=< (f >+< quitButtonF) >=^< Left)+-}+panel = {-shellF "Panel"-}+ (noStretchF True True $ vBoxF $ runButton >+< sizegroup)++runButton = timer interval >==< toggleButtonF "Run" ++interval = argReadKey "interval" 200 -- milliseconds++sizegroup = radioGroupF sizes defaultcellsize++sizes = [(3::Int,"Tiny"), (5,"Small"),(10,"Medium"),(25,"Huge")]++defaultcellsize = fst (sizes !! 2)
+ Demos/life/Timer.hs view
@@ -0,0 +1,6 @@+module Timer(timer) where++import Fudgets++timer :: Int -> F Bool Tick+timer t = timerF >=^< \b -> if b then Just (t,0) else Nothing
+ Demos/life/Utils2.hs view
@@ -0,0 +1,20 @@+module Utils2 where++import HbcUtils(apFst)++type Life = Bool+type Pos = (Int, Int)+type Bounds = Pos+type Generation = (Bounds,[Pos])++data LifeCmds = NewCell (Pos, Life) | NewGen Generation | NewCellSize Int+data LifeEvts = NewBounds Bounds | MouseClick Pos++mapgen found more notfound p l = mg l+ where mg (p1:l) | (p == p1) = found l+ | (p > p1) = more p1 (mg l)+ mg l = notfound l++togglegen p = mapgen (\l->(l,False)) (apFst . (:)) (\l->(p:l,True)) p+setgen t p = mapgen c (:) c p where c = if t then (p:) else id+
+ Demos/mines/Box.hs view
@@ -0,0 +1,59 @@+module Box(boxF,readAllBitmaps) where+import AllFudgets+import HbcUtils(lookupWithDefault)+import MineField+import Pics++pictSize :: Size+pictSize = Point 32 32++initcmds = [XCmd $ ChangeWindowAttributes [CWEventMask [ExposureMask]], but 1, but 2, but 3] + where but t = XCmd $ GrabButton True (Button t) [] [ButtonPressMask, ButtonReleaseMask]++boxF :: [(Symbol,PixmapId)] -> F Symbol (Coord -> MInput)+boxF sps = windowF initcmds (simpleK (boxK sps) pictSize SBlank)++boxK :: [(Symbol,PixmapId)] -> Drawer -> Drawer -> Fms' Symbol Symbol (Coord -> MInput)+boxK ps draw _clear s event =+ case event of+ High s' -> (s', redraw ps s')+ Low (XEvt (Expose _ 0)) -> (s, redraw ps s)+ Low (XEvt (ButtonEvent _ _ _ ms Pressed (Button b))) ->+ (s, case (ms,b) of+ ([] ,1) -> [High Move]+ ([Control],1) -> [High Bomb]+ ([Shift] ,1) -> [High Free]+ (_ ,2) -> [High Bomb]+ (_ ,3) -> [High Free]+ _ -> [])+-- Low (LayoutSize nsize) -> (s, ??)+ _ -> (s,[])+ where redraw ps SBlank = [Low $ XCmd ClearWindow]+ redraw ps s = + let p = lookupWithDefault ps (error ("No bitmap for "++show s)) s+ in [Low $ XCmd ClearWindow, Low (draw (CopyPlane (Pixmap p) (Rect 0 pictSize) 0 0))]+{-+ redraw ps (SNumber 0) = [Low ClearWindow, Low (draw (CopyPlane (Pixmap ps) (Rect (Point 0 0) (Point 32 32)) (Point 0 0) 0))]+ redraw ps (SNumber n) = [Low ClearWindow, Low (draw (DrawImageString tp (show n)))]+ redraw ps (SCurrent n) = [Low ClearWindow, Low (draw (DrawImageString tp ("X"++show n)))]+ redraw ps SBombX = [Low ClearWindow, Low (draw (DrawImageString tp "BX"))]+ redraw ps SBombDone = [Low ClearWindow, Low (draw (DrawImageString tp "BD"))]+ redraw ps SBomb = [Low ClearWindow, Low (draw (DrawImageString tp "B"))]+ redraw ps SFree = [Low ClearWindow, Low (draw (DrawImageString tp "F"))]+tp = Point 10 18+-}++bitmaps = + [(SNumber n,num!!n) | n<-[0..5]] +++ [(SCurrent n,cur!!n) | n<-[0..5]] +++ [(SBombX, bombx), (SBombDone, bombdone), (SBomb, bomb), (SFree, free)]++readAllBitmaps f = readBitmaps bitmaps f++--readBitmaps :: [(Symbol,String)] -> ([PixmapId] -> K a b) -> K a b+readBitmaps ns f = readb [] ns f+ where readb ps [] f = f ps+ readb ps ((n,bm):ns) f = bitmapFromData bm $ \r ->+ case r of+ BitmapBad -> error ("Cannot read bitmap "++show n)+ BitmapReturn _ _ p -> readb (ps++[(n,p)]) ns f
+ Demos/mines/FUtil.hs view
@@ -0,0 +1,35 @@+module FUtil(module FUtil,F) where+import Fudgets++ignoreI :: F a b -> F aa b+ignoreI f = f >=^< (\x->error "ignoreI") +ignoreO :: F a b -> F a bb+ignoreO f = (\x->error "ignoreO") >^=< f++stripLeftF = concatMapF g where g (Left x) = [x]; g _ = []+stripRightF = concatMapF g where g (Right x) = [x]; g _ = []++{-+debugF :: (a ->String) -> (b->String) -> String -> F a b -> F a b+debugF iShow oShow title f =+ let disp s = labLeftOfF s displayF+ it = disp "Input: "+ im = disp " "+ ot = disp "Output:"+ om = im+ ts = ignoreI (untaggedListLF verticalP [it, ot])+ ms = untaggedListLF verticalP [im, om] >=^< (\x->case x of { Right x -> (0,iShow x); Left y -> (1,oShow y)})+ box = untaggedListLF horizontalP [ts, ms] >=^< (\x->(1,x))+ shell = shellF ("Debug - "++title) box+ tb :: F a b -> F a (Either b a)+ tb f = idRightF f >==< toBothF+-- g (Right (Left x)) = [x]+-- g _ = []+ in stripLeftF >==< stripRightF >==< tb shell >==< tb f++debugShowF t f = debugF show show t f+-}++intWF :: Int -> Int -> F Int (InputMsg Int)+intWF s n = startupF [n] intF+
+ Demos/mines/MineField.hs view
@@ -0,0 +1,186 @@+module MineField(MInput(..),MOutput(..),Symbol(..),Coord(..),play,playSP,initMineCount,mineFieldSize) where+--import RandomHBC(randomInts)+import System.Random(StdGen,randomRs,split)+import Data.List(union, intersect)+import Fudgets(getSP,putsSP) -- SP operations+import Data.Array+import Data.List((\\),nub)++type Coord = (Int,Int) -- mine field coordinate+type RandInt = Int+type MineCount = Int+type MineField = Array (Int,Int) Bool -- number of mines and the array representing the mine field+data Moves = Moves Coord [Coord] [Coord] -- current pos, places, border+ deriving (Eq, Ord{-, Text-})++mineFieldSizeX, mineFieldSizeY :: Int+mineFieldSizeX = 12+mineFieldSizeY = 12+mineFieldSize :: Coord+mineFieldSize = (mineFieldSizeX, mineFieldSizeY)++newField :: StdGen -> MineCount -> MineField -- random numbers gives a new field+newField g n =+ let (nx, ny) = mineFieldSize+ --rs = newRands r+ --xs = map (`rem` nx) (everyOther rs)+ --ys = map (`rem` ny) (everyOther (tail rs))+ (g1,g2) = split g+ ps = randomRs (1,nx) g1 `zip` randomRs (1,ny) g2+ xys = take ((n `min` (nx * ny)) `max` 0) $+ nub (ps \\ [(1,1),mineFieldSize])+ b = ((0,0),(nx+1,ny+1))+ in array b [(p, p `elem` xys) | p<-range b]++++--newRands r = randomInts ((r `max` 1) `min` 2147483562) (((r+123457) `max` 1) `min` 2147483398)+--everyOther (x:_:xs) = x:everyOther xs++initMoves = Moves (1,1) [(1,1)] [(1,2), (2,1), (2,2)]++moveTo :: Moves -> Coord -> Maybe Moves+moveTo (Moves _ visited border) xy | xy `elem` border =+ let visited' = xy:visited+ in Just (Moves xy visited' (union border (neighbours xy) \\ visited'))+moveTo (Moves _ visited border) xy | xy `elem` visited =+ Just (Moves xy visited border)+moveTo _ _ = Nothing+ +neighbours :: Coord -> [Coord]+neighbours (x,y) = + let (xm,ym) = mineFieldSize+ in [(xi,yi) | xi<-[x-1..x+1], xi>0 && xi<=xm, yi<-[y-1..y+1], yi>0 && yi<=ym]++data Symbol = SBlank | SNumber Int | SCurrent Int | SFree | SBomb | SBombX | SBombDone deriving (Eq, Ord, Show)+data MInput = Move Coord | Bomb Coord | Free Coord | Hint | New | SetSize Int | Noop deriving (Eq, Ord{-, Text-})+data MOutput = Repaint [(Coord, Symbol)] | Msg String | Status String deriving (Eq, Ord{-, Text-})+type Counters = (Int,Int) -- moves, hints+type Bombs = [Coord]+data State = Go StdGen MineCount MineField Moves Counters Bombs Bombs+ | Stop StdGen MineCount+ --deriving (Eq, Ord{-, Text-})++initMineCount :: MineCount+initMineCount = 26+newState :: StdGen -> MineCount -> State+newState g n = Go g1 n (newField g2 n) initMoves (0, 0) [] []+ where (g1,g2) = split g+doMove :: State -> MInput -> (State, [MOutput])+doMove s@(Go rs n mf ms c@(i,j) bs fs) (Move xy) =+ if xy `elem` bs then+ (s, [])+ else+ case moveTo ms xy of+ Nothing -> (s, [])+ Just ms' -> + let c' = (i+1,j) in+ if mf ! xy then+ let as = allBombs mf in+ (Stop rs n, [Msg "You just exploded!", stat c' bs fs, Repaint [paintBomb bs a | a<-as], Repaint [(xy,SBombX) | xy<-bs, xy `notElem` as]])+ else + if xy == mineFieldSize then+ (Stop rs n, [Msg "You honestly made it!", stat c' bs fs, Repaint (map (paint mf ms' bs) (changes ms ms'))])+ else+ (Go rs n mf ms' c' bs fs, [Msg (mineMsg mf xy), stat c' bs fs, Repaint (map (paint mf ms' bs) (changes ms ms'))])+doMove s@(Go rs n mf ms@(Moves _ vis _) c bs fs) (Bomb xy) =+ if xy `elem` vis then+ (s, [])+ else if xy `elem` bs then+ let bs' = bs \\ [xy] in (Go rs n mf ms c bs' fs, [stat c bs' fs, Repaint [(xy, SBlank)]])+ else+ let bs' = xy:bs+ fs' = fs \\ [xy]+ in (Go rs n mf ms c bs' fs', [stat c bs' fs', Repaint [(xy, SBomb)]])+doMove s@(Go rs n mf ms@(Moves _ vis _) c bs fs) (Free xy) =+ if xy `elem` vis then+ (s, [])+ else if xy `elem` fs then+ let fs' = fs \\ [xy] in (Go rs n mf ms c bs fs', [stat c bs fs', Repaint [(xy, SBlank)]])+ else+ let fs' = xy:fs+ bs' = bs \\ [xy]+ in (Go rs n mf ms c bs' fs', [stat c bs' fs', Repaint [(xy, SFree)]])+doMove (Go rs n _ _ _ _ _) New = doMove (Stop rs n) New+doMove (Stop rs n) New =+ let (s@(Go _ _ a _ _ _ _), os) = doMove (newState rs n) (Move (1,1))+ in (s, Repaint [((x,y), SBlank) | x<-[1..mineFieldSizeX], y<-[1..mineFieldSizeY]] : Repaint [((1,1), SCurrent (countBombs a (1,1)))] : stat (0,0) [] []:os)+doMove (Go rs _ mf ms c bs fs) (SetSize n) = (Go rs n mf ms c bs fs, [])+doMove (Go rs n mf ms@(Moves _ _ ps) (i,j) bs fs) Hint = + let m = case filter (\xy->not (mf ! xy)) ps of+ [] -> Msg "Impossible"+ xy:_ -> Repaint [(xy, SFree)]+ c' = (i,j+1)+ in (Go rs n mf ms c' bs fs, [stat c' bs fs, m])+doMove (Stop rs _) (SetSize n) = (Stop rs n, [])+doMove s _ = (s, [])++stat :: Counters -> Bombs -> Bombs -> MOutput+stat (i, j) bs fs = Status ("Moves: "++show i++" Hints: "++show j++" Safes: "++show (length fs)++" Mines: "++show (length bs))++mineMsg a xy =+ case countBombs a xy of+ 0 -> "No mines nearby."+ 1 -> "1 mine nearby."+ n -> shows n " mines nearby."++changes :: Moves -> Moves -> [Coord]+changes (Moves cur vis bor) (Moves cur' vis' bor') =+ let chg l l' = union l l' \\ intersect l l'+ in nub (chg [cur] [cur'] ++ chg vis vis' ++ chg bor bor')++paint :: MineField -> Moves -> Bombs -> Coord -> (Coord, Symbol)+paint a (Moves cur vis _) bs xy =+ (xy, + if xy == cur then+ SCurrent (countBombs a xy)+ else if xy `elem` vis then+ SNumber (countBombs a xy)+ else if xy `elem` bs then+ SBomb+ else+ SBlank)++countBombs a = length . filter id . map (a!) . neighbours++allBombs a = [(x,y) | x<-[1..mineFieldSizeX], y<-[1..mineFieldSizeY], a!(x,y)]++paintBomb bs xy =+ (xy,+ if xy `elem` bs then+ SBomb+ else+ SBombDone)++firstState :: StdGen -> (State, [MOutput])+firstState g =+ {-let r = truncate d+ in-} doMove (newState g initMineCount) New++stripR = filter f where f (Repaint []) = False+ f _ = True++doMoves :: State -> [MInput] -> [[MOutput]]+doMoves s [] = []+doMoves s (i:is) =+ let (s', os) = doMove s i+ in stripR os : doMoves s' is++play :: StdGen -> [MInput] -> [[MOutput]]+play d is =+ let (s, os) = firstState d+ in stripR os : doMoves s is+++-- Stream Processor version of play & doMoves (hallgren 930525):++--doMovesSP :: State -> SP MInput MOutput+doMovesSP s =+ getSP $ \i ->+ let (s', os) = doMove s i+ in putsSP (stripR os) $ doMovesSP s'++--playSP :: Double -> SP MInput MOutput+playSP d =+ let (s, os) = firstState d+ in putsSP (stripR os) $ doMovesSP s
+ Demos/mines/Pics.hs view
@@ -0,0 +1,200 @@+module Pics where+import AllFudgets(BitmapData(..),pP)++bm w h = BitmapData (pP w h) Nothing++cur = [cur_0,cur_1,cur_2,cur_3,cur_4,cur_5]+num = [num_0,num_1,num_2,num_3,num_4,num_5]++bomb = bm 32 32 bomb_bits+bomb_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x81, 0x01, 0x00, 0x80, 0xa1, 0x02, 0x00, 0x80,+ 0x21, 0x30, 0x00, 0x80, 0x05, 0x24, 0x00, 0x80, 0x39, 0x09, 0x00, 0x80,+ 0xa1, 0x00, 0x00, 0x80, 0x81, 0x00, 0x00, 0x80, 0x81, 0x00, 0x00, 0x80,+ 0x05, 0xc7, 0x07, 0x80, 0x39, 0xef, 0x1f, 0x80, 0x01, 0xdf, 0x3f, 0x80,+ 0x01, 0xde, 0x7f, 0x80, 0x01, 0xdc, 0xff, 0x80, 0x01, 0xe2, 0xff, 0x80,+ 0x01, 0xff, 0xff, 0x81, 0x01, 0xff, 0xff, 0x81, 0x01, 0xff, 0xff, 0x81,+ 0x01, 0xff, 0xff, 0x81, 0x01, 0xff, 0xff, 0x81, 0x01, 0xfe, 0xff, 0x80,+ 0x01, 0xfe, 0xff, 0x80, 0x01, 0xfc, 0x7f, 0x80, 0x01, 0xf8, 0x3f, 0x80,+ 0x01, 0xf0, 0x1f, 0x80, 0x01, 0xc0, 0x07, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]+bombdone = bm 32 32 bombdone_bits+bombdone_bits = [+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,+ 0xc0,0xc0,0x00,0x00,0xc0,0x50,0x01,0x00,0xc0,0x10,0x18,0x00,0xc0,0x02,0x12,+ 0x00,0xc0,0x9c,0x04,0x00,0xc0,0x50,0x00,0x00,0xc0,0x40,0x00,0x00,0xc0,0x40,+ 0x00,0x00,0xc0,0x82,0xe3,0x03,0xc0,0x9c,0xf7,0x0f,0xc0,0x80,0xef,0x1f,0xc0,+ 0x00,0xef,0x3f,0xc0,0x00,0xee,0x7f,0xc0,0x00,0x31,0x7e,0xc0,0x80,0x1f,0xfc,+ 0xc0,0x80,0x0f,0xf8,0xc0,0x80,0x07,0xf0,0xc0,0x80,0x07,0xf0,0xc0,0x80,0x07,+ 0xf0,0xc0,0x00,0x0f,0x78,0xc0,0x00,0x1f,0x7c,0xc0,0x00,0x3e,0x3e,0xc0,0x00,+ 0xfc,0x1f,0xc0,0x00,0xf8,0x0f,0xc0,0x00,0xe0,0x03,0xc0,0x00,0x00,0x00,0xc0,+ 0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff]+bombx = bm 32 32 bombx_bits+bombx_bits = [+ 0x00,0x00,0x00,0x80,0xfc,0xff,0xff,0x8f,0xf8,0xff,0xff,0x87,0xf1,0xff,0xff,+ 0xa3,0x23,0xff,0xff,0xb1,0x87,0xfe,0xff,0xb8,0x8f,0xe7,0x7f,0xbc,0x1d,0xed,+ 0x3f,0xbe,0x23,0xfa,0x1f,0xbf,0x2f,0xfc,0x8f,0xbf,0xbf,0xfc,0xc7,0xbf,0xbf,+ 0xff,0xe7,0xbf,0x7d,0x1c,0xfc,0xbf,0x63,0x08,0xf0,0xbf,0x7f,0x10,0xe0,0xbf,+ 0xff,0x10,0xc0,0xbf,0xff,0x11,0x80,0xbf,0xff,0x0e,0x80,0xbf,0x7f,0x00,0x00,+ 0xbf,0x7f,0x00,0x00,0xbf,0x7f,0x00,0x00,0xbf,0x7f,0x00,0x00,0xbf,0x7f,0x00,+ 0x00,0xbf,0xff,0x00,0x80,0xbf,0x9f,0x00,0x80,0xbf,0x8f,0x01,0xc0,0xbc,0xc7,+ 0x03,0xe0,0xb8,0xe3,0x07,0xf0,0xb1,0xf1,0x1f,0xfc,0xa3,0xf8,0xff,0xff,0x87,+ 0xfc,0xff,0xff,0x8f,0x00,0x00,0x00,0x80]+cur_0 = bm 32 32 cur_0_bits+cur_0_bits = [+ 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,+ 0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x0e,+ 0x00,0x80,0x01,0x11,0x00,0x80,0x01,0x11,0x00,0x80,0x01,0x11,0x00,0x80,0x01,+ 0x0e,0x00,0x80,0x01,0x04,0x00,0x80,0x01,0x04,0x00,0x80,0x01,0x04,0x00,0x80,+ 0x81,0x3f,0x00,0x80,0x01,0x04,0x00,0x80,0x01,0x04,0xe0,0x80,0x01,0x04,0x10,+ 0x81,0x01,0x04,0x10,0x81,0x01,0x04,0x90,0x81,0x01,0x04,0x50,0x81,0x01,0x04,+ 0x30,0x81,0x01,0x0a,0x10,0x81,0x01,0x11,0x10,0x81,0x01,0x11,0xe0,0x80,0x81,+ 0x20,0x00,0x80,0x41,0x40,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,+ 0x01,0x00,0x00,0x80,0xff,0xff,0xff,0xff]+cur_1 = bm 32 32 cur_1_bits+cur_1_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80,+ 0x01, 0x11, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80,+ 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80,+ 0x81, 0x3f, 0x00, 0x80, 0x01, 0x04, 0x40, 0x80, 0x01, 0x04, 0x60, 0x80,+ 0x01, 0x04, 0x50, 0x80, 0x01, 0x04, 0x40, 0x80, 0x01, 0x04, 0x40, 0x80,+ 0x01, 0x04, 0x40, 0x80, 0x01, 0x04, 0x40, 0x80, 0x01, 0x0a, 0x40, 0x80,+ 0x01, 0x11, 0x40, 0x80, 0x01, 0x11, 0xf0, 0x81, 0x81, 0x20, 0x00, 0x80,+ 0x41, 0x40, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]+cur_2 = bm 32 32 cur_2_bits+cur_2_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80,+ 0x01, 0x11, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80,+ 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80,+ 0x81, 0x3f, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0xe0, 0x80,+ 0x01, 0x04, 0x10, 0x81, 0x01, 0x04, 0x00, 0x81, 0x01, 0x04, 0x80, 0x80,+ 0x01, 0x04, 0x40, 0x80, 0x01, 0x04, 0x20, 0x80, 0x01, 0x0a, 0x10, 0x80,+ 0x01, 0x11, 0x10, 0x80, 0x01, 0x11, 0xf0, 0x81, 0x81, 0x20, 0x00, 0x80,+ 0x41, 0x40, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]+cur_3 = bm 32 32 cur_3_bits+cur_3_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80,+ 0x01, 0x11, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80,+ 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80,+ 0x81, 0x3f, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0xe0, 0x80,+ 0x01, 0x04, 0x10, 0x81, 0x01, 0x04, 0x00, 0x81, 0x01, 0x04, 0x00, 0x81,+ 0x01, 0x04, 0xc0, 0x80, 0x01, 0x04, 0x00, 0x81, 0x01, 0x0a, 0x00, 0x81,+ 0x01, 0x11, 0x10, 0x81, 0x01, 0x11, 0xe0, 0x80, 0x81, 0x20, 0x00, 0x80,+ 0x41, 0x40, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]+cur_4 = bm 32 32 cur_4_bits+cur_4_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80,+ 0x01, 0x11, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80,+ 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80,+ 0x81, 0x3f, 0x00, 0x80, 0x01, 0x04, 0x40, 0x80, 0x01, 0x04, 0x60, 0x80,+ 0x01, 0x04, 0x50, 0x80, 0x01, 0x04, 0x48, 0x80, 0x01, 0x04, 0xfc, 0x80,+ 0x01, 0x04, 0x40, 0x80, 0x01, 0x04, 0x40, 0x80, 0x01, 0x0a, 0x40, 0x80,+ 0x01, 0x11, 0x40, 0x80, 0x01, 0x11, 0xe0, 0x80, 0x81, 0x20, 0x00, 0x80,+ 0x41, 0x40, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]+cur_5 = bm 32 32 cur_5_bits+cur_5_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80,+ 0x01, 0x11, 0x00, 0x80, 0x01, 0x11, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x80,+ 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80,+ 0x81, 0x3f, 0x00, 0x80, 0x01, 0x04, 0x00, 0x80, 0x01, 0x04, 0xf0, 0x81,+ 0x01, 0x04, 0x10, 0x80, 0x01, 0x04, 0x10, 0x80, 0x01, 0x04, 0x20, 0x80,+ 0x01, 0x04, 0xc0, 0x80, 0x01, 0x04, 0x00, 0x81, 0x01, 0x0a, 0x00, 0x81,+ 0x01, 0x11, 0x10, 0x81, 0x01, 0x11, 0xe0, 0x80, 0x81, 0x20, 0x00, 0x80,+ 0x41, 0x40, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]+free = bm 32 32 free_bits+free_bits = [+ 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,+ 0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,+ 0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,+ 0x00,0x02,0x80,0x01,0x00,0x02,0x80,0x01,0x38,0x12,0x80,0x01,0x44,0x0a,0x80,+ 0x01,0x44,0x06,0x80,0x01,0x44,0x06,0x80,0x01,0x44,0x0a,0x80,0x01,0x44,0x12,+ 0x80,0x01,0x38,0x22,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,+ 0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,+ 0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,+ 0x01,0x00,0x00,0x80,0xff,0xff,0xff,0xff]+num_0 = bm 32 32 num_0_bits+num_0_bits = [+ 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x80,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,+ 0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,+ 0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x01,0x40,0x95,0xa9,+ 0x82,0x83,0xaa,0x55,0x41,0x44,0x95,0xa9,0x42,0x84,0xaa,0x55,0x41,0x46,0x95,+ 0xa9,0x42,0x85,0xaa,0x55,0xc1,0x44,0x95,0xa9,0x42,0x84,0xaa,0x55,0x41,0x44,+ 0x95,0xa9,0x82,0x83,0xaa,0x55,0x01,0x40,0x95,0xa9,0x02,0x80,0xaa,0x55,0x55,+ 0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,+ 0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,+ 0x01,0x00,0x00,0x80,0xff,0xff,0xff,0xff]+num_1 = bm 32 32 num_1_bits+num_1_bits = [+ 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x80,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,+ 0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,+ 0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x01,0x40,0x95,0xa9,+ 0x82,0xa0,0xaa,0x55,0xc1,0x40,0x95,0xa9,0xa2,0xa0,0xaa,0x55,0x81,0x40,0x95,+ 0xa9,0x82,0xa0,0xaa,0x55,0x81,0x40,0x95,0xa9,0x82,0xa0,0xaa,0x55,0x81,0x40,+ 0x95,0xa9,0xe2,0xa3,0xaa,0x55,0x01,0x40,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,+ 0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,+ 0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,+ 0x01,0x00,0x00,0x80,0xff,0xff,0xff,0xff]+num_2 = bm 32 32 num_2_bits+num_2_bits = [+ 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x80,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,+ 0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,+ 0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x01,0x40,0x95,0xa9,+ 0xc2,0xa1,0xaa,0x55,0x21,0x42,0x95,0xa9,0x02,0xa2,0xaa,0x55,0x01,0x42,0x95,+ 0xa9,0x02,0xa1,0xaa,0x55,0x81,0x40,0x95,0xa9,0x42,0xa0,0xaa,0x55,0x21,0x40,+ 0x95,0xa9,0xe2,0xa3,0xaa,0x55,0x01,0x40,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,+ 0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,+ 0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,+ 0x01,0x00,0x00,0x80,0xff,0xff,0xff,0xff]+num_3 = bm 32 32 num_3_bits+num_3_bits = [+ 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x80,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,+ 0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,+ 0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x01,0x40,0x95,0xa9,+ 0xc2,0xa1,0xaa,0x55,0x21,0x42,0x95,0xa9,0x02,0xa2,0xaa,0x55,0x01,0x42,0x95,+ 0xa9,0x82,0xa1,0xaa,0x55,0x01,0x42,0x95,0xa9,0x02,0xa2,0xaa,0x55,0x21,0x42,+ 0x95,0xa9,0xc2,0xa1,0xaa,0x55,0x01,0x40,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,+ 0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,+ 0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x95,0xa9,0xaa,0xaa,0xaa,+ 0x01,0x00,0x00,0x80,0xff,0xff,0xff,0xff]+num_4 = bm 32 32 num_4_bits+num_4_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x55, 0x55, 0x55, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa,+ 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x01, 0x40, 0x95, 0xa9, 0x82, 0xa1, 0xaa,+ 0x55, 0x41, 0x41, 0x95, 0xa9, 0x22, 0xa1, 0xaa, 0x55, 0x11, 0x41, 0x95,+ 0xa9, 0xf2, 0xa3, 0xaa, 0x55, 0x01, 0x41, 0x95, 0xa9, 0x02, 0xa1, 0xaa,+ 0x55, 0x01, 0x41, 0x95, 0xa9, 0x82, 0xa3, 0xaa, 0x55, 0x01, 0x40, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa,+ 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]+num_5 = bm 32 32 num_5_bits+num_5_bits = [+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0x55, 0x55, 0x55, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa,+ 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x01, 0x40, 0x95, 0xa9, 0xe2, 0xa3, 0xaa,+ 0x55, 0x21, 0x40, 0x95, 0xa9, 0x22, 0xa0, 0xaa, 0x55, 0x41, 0x40, 0x95,+ 0xa9, 0x82, 0xa1, 0xaa, 0x55, 0x01, 0x42, 0x95, 0xa9, 0x02, 0xa2, 0xaa,+ 0x55, 0x21, 0x42, 0x95, 0xa9, 0xc2, 0xa1, 0xaa, 0x55, 0x01, 0x40, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa,+ 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95,+ 0xa9, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x95, 0xa9, 0xaa, 0xaa, 0xaa,+ 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff]
+ Demos/mines/XMine.hs view
@@ -0,0 +1,60 @@+module Main where+--import Trace+--import Word+import Fudgets+import FUtil+import MineField+--import BitMaps+--import Time+import System.Random(newStdGen)+import Box++main = newStdGen >>= fudlogue . shellF "FXMines v1.2" . xmines++--getTimeDouble = randomRIO (0,2e9)+ ++--myFont = defaultFont+--separation = 5::Int++xmines d =+ let title = nullF -- untaggedListLF horizontalP [labelF "FXMines v1.2"]+ controls = untaggedListLF horizontalP [labelF "Mine count", inp initMineCount, bf "Hint" Hint, bf "Restart" New{-, bq "Quit"-}]+ msg1 = disp ""+ msg2 = disp ""+ panel = untaggedListLF verticalP [ignoreI title, -- 0+ ignoreI controls, -- 1+ msg1 >=^< (\(Status s)->s), -- 2+ msg2 >=^< (\(Msg s)->s), -- 3+ boxes' >=^< (\(Repaint l)->l)] >=^< directMsg -- 4+ where directMsg m@(Repaint l) = (4, m)+ directMsg m@(Msg s) = (3, m)+ directMsg m@(Status s) = (2, m)+ but s = buttonF s+ bf s f = (\_ -> f) >^=< but s+ bq s = quitF >==< but s+ disp s = displayF+ inp n = (\x->case x of { InputChange n -> SetSize n; _ -> Noop} ) >^=< ignoreI (intWF 8 n)+ (xn, yn) = mineFieldSize+ boxes = mapstateSP action Move >^^=< vBoxF (actionF >+< boxes1) >=^< Right+ where+ action _ (Left (Fun f) ) = (f,[])+ action f (Right (Move p)) = (f,[f p])+ action f (Right m ) = (f,[m])++ actionF =+ radioGroupF' (setPlacer (spacerP centerS horizontalP) .+ setLabelInside True)+ [(Fun Move,"Move"),(Fun Free,"ok"),(Fun Bomb,"Bomb")]+ (Fun Move)++ boxes1 :: F [(Coord, Symbol)] MInput+ boxes1 = readAllBitmaps $ \ ps ->+ (\(a,f)->f a) >^=< listLF (matrixP xn) [((x,y), boxF ps) | x<-[1..xn], y<-[1..yn]] >=^^< concatSP+ boxes' = --allcacheF+ boxes+ in loopF ({-debugF show show-} panel >==< absF (playSP d))++data Fun = Fun (Coord->MInput)+instance Eq Fun where+ Fun f1 == Fun f2 = f1 (0,0) == f2 (0,0)
+ Demos/paint/GraphF.hs view
@@ -0,0 +1,84 @@+module GraphF(graphF,PaintCommand(..),ToolFunc(..)) where+import AllFudgets+--import Word()++data PaintCommand+ = ChangeTool ToolFunc+ | ChangeColor ColorName++type ToolFunc = Point->Point->DrawCommand++graphK size func bgcol gc gcinv =+ let same = graphK size func bgcol gc gcinv+ newf f = graphK size f bgcol gc gcinv+ resize s = graphK s func bgcol gc gcinv+ newgc = graphK size func bgcol+ in getK $ \msg ->+ case msg of+ High (ChangeTool func) -> newf func+ High (ChangeColor color) -> changeColorK bgcol color newgc+ Low (LEvt (LayoutSize newsize)) -> resize newsize+ Low (XEvt (Expose _ 0)) -> same -- !!!+ Low (XEvt (ButtonEvent _ p _ _ Pressed (Button _))) ->+ rubberBandK size func bgcol gc gcinv p p+ _ -> same++rubberBandK s f bgcol gc gcinv p0 p1 =+ let cont p = rubberBandK s f bgcol gc gcinv p0 p+ in let same = cont p1+ draw gc p0 p1 = Low (wDraw gc (f p0 p1))+ in let toggle = draw gcinv+ in putK (toggle p0 p1) $+ getK $ \msg ->+ case msg of+ Low (XEvt (MotionNotify _ p _ _)) -> putK (toggle p0 p1) (cont p)+ Low (XEvt (ButtonEvent _ p _ _ Released _)) ->+ putsK [toggle p0 p1, draw gc p0 p] (graphK s f bgcol gc gcinv)+ _ -> same++idleGraphK size bgcol gc gcinv =+ let same = idleGraphK size bgcol gc gcinv+ resize size' = idleGraphK size' bgcol gc gcinv + in getK $ \msg ->+ case msg of+ High (ChangeTool func) -> graphK size func bgcol gc gcinv+ Low (LEvt (LayoutSize size')) -> resize size'+ _ -> same++changeColorK bgcol fg k =+ let gcattr fgcol = [GCForeground fgcol, GCLineWidth 3]+ invattrs bg fg = if bg==fg+ then invertColorGCattrs (Pixel 0) (Pixel 170) -- hmm+ else invertColorGCattrs bg fg+ in allocNamedColorPixel defaultColormap fg $ \fgcol ->+ wCreateGC rootGC (gcattr fgcol) $ \gc ->+ wCreateGC gc (invattrs bgcol fgcol) $ \gcinv ->+ k gc gcinv++graphF =+ let evmask =[ExposureMask{-,ButtonReleaseMask-}]+ in let wattrs = [CWBackingStore WhenMapped,+ CWEventMask evmask,+ CWBitGravity NorthWestGravity+ ]+ in let startcmds = map XCmd + [ ChangeWindowAttributes wattrs,+ --ConfigureWindow [CWBorderWidth 0],+ GrabButton True (Button 1) []+ [ButtonPressMask,+ PointerMotionMask,+ ButtonReleaseMask]+ {-,+ GrabButton True (Button 1) []+ [ButtonReleaseMask],+ GrabButton True (Button 3) []+ [ButtonReleaseMask]+ -}+ ]+ size = Point 300 300+ in windowF startcmds $+ setFontCursor 130 $+ changeGetBackPixel "white" $ \bgcol ->+ changeColorK bgcol "black" $ \gc gcinv ->+ putK (Low (layoutRequestCmd (plainLayout size False False))) $+ idleGraphK size bgcol gc gcinv
+ Demos/paint/Paint.hs view
@@ -0,0 +1,63 @@+module Main where+import Fudgets+import GraphF++main = fudlogue $ shellF "FudPaint" mainF++mainF = hBoxF (graphF >==< vBoxF toolscolorsF)++toolscolorsF =+ noStretchF True True $ spacerF centerS $ vBoxF $+ stripEither >^=< (toolsF >+< colorsF)++toolsF =+ "Tools" `labAboveF`+ ((ChangeTool. tool)>^=< radioGroupF' pm (map (pairwith pict) tools) LineTool)+ where pm = setLabelInside True++colorsF =+ "Colors" `labAboveF`+ (ChangeColor >^=< radioGroupF' pm (map col colors) "Black")+ where col c = (c,stackD [fgD c (g (cpict BlockTool)),+ g (cpict RectTool)])+ pm = setLabelInside True . setPlacer (matrixP' 3 Horizontal 0)++tools = [LineTool, RectTool, BlockTool, OvalTool, FilledOvalTool]++colors = [ "Black", "Grey", "White",+ "Blue", "Blue3", "Blue4",+ "Green", "Green3", "Green4",+ "Yellow","Orange", "Brown",+ "Red", "Red3", "Red4" ]++data Tool = LineTool | RectTool | BlockTool | OvalTool | FilledOvalTool+ deriving (Eq)++tool LineTool = drawline+tool RectTool = drawrect+tool BlockTool = fillrect+tool OvalTool = drawoval+tool FilledOvalTool = filloval++pict = pict' (Point 30 15)+cpict = pict' (Point 15 15)+pict' s t = FixD (s+1) [tool t 0 (s-1)]++{-+pict LineTool = "Line"+pict RectTool = "Rect"+pict BlockTool = "Block"+pict OvalTool = "Oval"+pict FilledOvalTool = "Blob"+-}++drawline p0 p1 = DrawLine (Line p0 p1)+drawrect p0 p1 = DrawRectangle (rect' p0 p1)+fillrect p0 p1 = FillRectangle (rect' p0 p1)+drawoval p0 p1 = DrawArc (rect' p0 p1) 0 (64*360)+filloval p0 p1 = FillArc (rect' p0 p1) 0 (64*360)++rect' p1 p2 =+ let p0 = pmin p1 p2+ p = pmax p1 p2+ in Rect p0 (padd (psub p p0) (Point 1 1))
+ Examples/FancyHello.hs view
@@ -0,0 +1,26 @@+-- Fancy version of the "Hello, world!" program+import Fudgets++main = fudlogue (shellF "Hello" helloF)++helloF = labelF (fancyTextD greeting)++fancyTextD text =+ stackD [bgD,+ spacedD (hvMarginS (5+dist) 5) shadowTxtD,+ spacedD (hvMarginS 5 (5+dist)) fgTxtD]+ where+ shadowTxtD = fgD shadow txtD+ fgTxtD = fgD color txtD+ txtD = spacedD centerS $ fontD font (g text)+ bgD = vboxD' 0 [fgD sky fillD,fgD ground fillD]+ fillD = g (filler False False 10)++-- Everything can be changed with command line switches:+color = argKey "color" "red"+shadow = argKey "shadow" "black"+sky = argKey "sky" "skyblue"+ground = argKey "ground" "blue"+greeting = argKey "greeting" "Hello, world!"+dist = diag (argReadKey "dist" 2)+font = argKey "font" "-*-helvetica-bold-r-*-*-24-*-*-*-*-*-iso8859-1"
+ Examples/StopWatch.hs view
@@ -0,0 +1,23 @@+module Main where+-- A simple stop watch with a run/stop button and a reset button.+import Fudgets++main = fudlogue (shellF "Stop Watch" stopWatchF)++stopWatchF = + timeDispF >==< (counterSP 0 >^^=< idRightF (timerF >=^< timeprep))+ >==< (runF >+< resetF)+ -- >+<quitButtonF++timeprep True = Just (100,100)+timeprep False = Nothing++runF = toggleButtonF "Run"+resetF = buttonF "Reset"++timeDispF = intDispF -- to be improved++counterSP no = getSP $ \msg -> let out n = putSP n $ counterSP n + in case msg of+ Left _ -> out (no+1)+ Right _ -> out 0
+ Examples/texteditor.hs view
@@ -0,0 +1,6 @@+import Fudgets+import ContribFudgets(textFileShellF)++main = fudlogue $ textFileShellF "Text Editor" edF++edF = spacer1F (minSizeS (Point 500 400)) (scrollF inputEditorF)
+ README.md view
@@ -0,0 +1,71 @@++# ¤ Fudgets ¤++[Fudgets](https://www.altocumulus.org/Fudgets/)+is primarily a Graphical User Interface Toolkit implemented in Haskell+on top of its own binding to the+[Xlib library](https://tronche.com/gui/x/xlib/) of the+[X Windows system](https://www.x.org/).+Fudgets also makes it easy to create client/server applications that+communicate via the Internet.+[The Hello world program](https://www.altocumulus.org/Fudgets/Intro/ex1.html)+fits on a single line:++```haskell+main = fudlogue (shellF "Hello" (labelF "Hello world!"))+```++The key abstraction is+[*the fudget*](https://www.altocumulus.org/Fudgets/Intro/concept.html).+A fudget is a *stream processor* with+high-level and low-level streams. The high level streams are used for+communication between fudgets within a program.+The low level streams are for communication with the I/O system.++> ++Fudgets are combined using various combinators for parallel composition,+serial composition and loops.++> ++Fudgets was originally implemented in Lazy ML in the early 1990s,+then converted to Haskell. It was thus designed before monadic IO was+introduced in Haskell and early versions did not make use of Haskell's+type classes at all.++## Documentation++- [Your first 8 Fudgets program](https://www.altocumulus.org/Fudgets/Intro/).+ Gentle Introduction.+- [Fudgets User's Guide](https://www.altocumulus.org/Fudgets/userguide.html).+ Naming conventions and some other practical things.+- [Fudget Library Reference Manual](https://www.altocumulus.org/Fudgets/Manual/). (Haddock did not exist back when Fudgets were created.)+- [The FPCA-93 paper about Fudgets](https://www.altocumulus.org/Fudgets/fpca93-abstract.html),+ the first publication describing Fudgets.+- See the [Fudgets home page](https://www.altocumulus.org/Fudgets/) for more info.++## Installing Fudgets from Hackage++### On Linux systems++- `sudo apt install libxext-dev` (installs Xlib etc on Debian-based+ distributions, the command will be different on other Linux distributions.)+- `cabal install fudgets`++### On macOS++- Install [XQuartz](https://www.xquartz.org/).+- `brew install gcc` (need the version of `cpp` included with gcc, since there+ are some issues with cpp from clang.+ Note: `fudgets.cabal` refers to `cpp-11`, you might need to change this+ if you install a different version of gcc.)++- If you are using ghc>=8.10.3: unfortunately it seems that the+ `-pgmP` option no longer works, so you need to+ change a line in `$PREFIX/lib/ghc-*/lib/settings` instead:++ ``` ,("Haskell CPP command", "gcc-11")```++- `cabal install fudgets`+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ fudgets.cabal view
@@ -0,0 +1,539 @@+Name: fudgets+-- The version number also appears in hsrc/utils/FudVersion.hs+Version: 0.18.3+Cabal-Version: >=1.10+Synopsis: The Fudgets Library+Homepage: https://www.altocumulus.org/Fudgets/+Category: GUI, Network, Concurrency+ -- Graphics?, User Interfaces?++Description: <https://www.altocumulus.org/Fudgets/ Fudgets> is a Graphical+ User Interface Toolkit built in Haskell on top of the X11+ Windows system in the early 1990s. There is an+ <https://www.altocumulus.org/Fudgets/fpca93-abstract.html FPCA-93 paper>+ about it. Fudgets also makes it easy to create+ client/server applications that communicate via the Internet.+ .+ This package includes the Fudgets library and a few small+ examples and demo applications.++Author: Thomas Hallgren and Magnus Carlsson+Maintainer: Thomas Hallgren+Build-Type: Simple+License: OtherLicense+License-File: COPYRIGHT+Tested-With: GHC==7.4.1, GHC==7.6.3, GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.3, GHC==8.8.2, GHC==8.10.2, GHC==8.10.7, GHC==9.0.2, GHC==9.2.2++Extra-Source-Files: README.md+ hsrc/exists.h+ hsrc/defaults/defaults.h+ hsrc/ghc-dialogue/asyncinput.h+ hsrc/ghc-dialogue/ccalls.h+ hsrc/ghc-dialogue/cfuns.h+ hsrc/ghc-dialogue/cfundefs.h+ hsrc/ghc-dialogue/cimports.h+ hsrc/ghc-dialogue/csizes.h+ hsrc/ghc-dialogue/newstructfuns.h+ hsrc/ghc-dialogue/structs.h+ xlib/socketlib/defs.h++Flag developer+ Description: Enable options useful for developers of this library+ Manual: True+ Default: False++Flag old-time+ Description: Use the old-time package+ Default: True++Library+ --Exposed: False+ Exposed-modules: AllFudgets Fudgets ContribFudgets+ TreeBrowser HyperGraphicsF2 SuperMenuF ConnectF TypedSockets+ ReactiveF ReactionM DialogueIO DoRequest+ IOUtil+ --NonStdTrace+ HbcUtils+ -- GhcFudgets++ Build-Depends: base>=4 && <5, process, directory>=1.2.3,+ --packedstring,+ containers, array, time,+ unix++ if flag(old-time)+ Build-Depends: old-time++ Hs-source-dirs: Contrib hsrc+ hsrc/utils hsrc/sp hsrc/types hsrc/xtypes hsrc/combinators hsrc/containers+ hsrc/drawing hsrc/filters hsrc/fudgets hsrc/defaults hsrc/internals+ hsrc/kernelutils hsrc/layout hsrc/infix hsrc/lowlevel hsrc/io hsrc/debug+ hsrc/ghc-dialogue hsrc/ghc+ -- The only module used from hbc_library is FudUTF8+ hsrc/hbc_library++ Default-language: Haskell98+ Default-extensions: ForeignFunctionInterface Rank2Types+ ExistentialQuantification+ MultiParamTypeClasses FunctionalDependencies+ FlexibleInstances FlexibleContexts TypeSynonymInstances++--if impl(ghc>=8.6) && impl(ghc<8.8)+-- Default-extensions: NoMonadFailDesugaring++ Include-dirs: hsrc hsrc/ghc-dialogue hsrc/defaults++ if os(darwin)+ Extra-lib-dirs: /opt/X11/lib + Include-dirs: /opt/X11/include+ -- Run 'brew install gcc', then you should have gcc-11 and cpp-11, or+ -- possibly another version, in which case you need to adapt the line below:+ if impl(ghc<8.10.3)+ -- Use the -pgmP in ghc<8.10.3+ ghc-options: -pgmP cpp-11 -optP -traditional+ --else+ -- Unfortunately -pgmP doesn't work in ghc>=8.10.3, so you need to+ -- change a line in $PREFIX/lib/ghc-*/lib/settings insead:+ -- ,("Haskell CPP command", "gcc-11")++ Extra-Libraries: X11 Xext++ ghc-options: -fno-warn-tabs+ + if flag(developer)+ ghc-options: -fwarn-unused-imports+ ghc-prof-options: -fprof-auto++ if impl(ghc>=8.6)+ ghc-options: -haddock++ c-sources: hsrc/ghc-dialogue/cfuns.c xlib/fdzero.c xlib/socketlib/inet.c+ cc-options: "-DVERSION=\"SOCKET Version 1.3\"" -DHAS_H_ERRNO++ -- Sigh. Why can't Cabal fill this in?+ -- ghc --make has no problem finding all the reqired modules.+ Other-Modules:+ AlignP+ Alignment+-- Ap+ AppStorage+ AsyncInput+ AsyncTransmitter+ AutoLayout+ AutoPlacer+ AuxShellF+ AuxTypes+ BellF+ BgF+ BitmapDrawing+ BitmapF+ Border3dF+ BranchF+ BubbleF+ ButtonBorderF+ ButtonF+ ButtonGroupF+ CSizes+ CString16+ CmdLineEnv+ Color+ Combinators+ Command+ CompF+ CompFfun+ CompOps+ CompSP+ CompiledGraphics+ CompletionStringF+ CondLayout+ Cont+ ContDynF+ Containers+ ContinuationIO+ Convgc+ Cursor+ DButtonF+ DDisplayF+ DFudIO+ DLValue+ DRadioF+ DShellF+ DStringF+ DToggleButtonF+ Debug+ DefaultParams+ Defaults+ DialogF+ DialogueSpIO+ Direction+ Display+ Dlayout+ DoXCommand+ DoXRequest+ DoubleClickF+ DragF+ DrawCompiledGraphics+ DrawCompiledGraphics1+ DrawInPixmap+ DrawInWindow+ DrawTypes+ Drawcmd+ Drawing+ DrawingModules+ DrawingOps+ DrawingUtils+ DynListF+ DynListLF+ DynRadioGroupF+ DynSpacerF+ Dynforkmerge+ Edit+ Editfield+ Editor+ Edtypes+ EitherUtils+ EncodeEvent+ EndButtonsF+ Event+ EventMask+ Expose+ FDefaults+ FRequest+ FilePaths+ FilePickF+ FilePickPopupF+ FileShellF+ Filters+ FixedDrawing+ FlexibleDrawing+ FocusMgr+ Font+ FontProperty+ FreeGroupF+ FudIO+ FudUTF8+ FudUtilities+ FudVersion+ Fudget+ FudgetIO+ GCAttrs+ GCtx+ Gc+ GcWarningF+ Geometry+ GetModificationTime+ GetTime+ GetVisual+ GetWindowProperty+ Graphic+ Graphic2Pixmap+ GraphicsF+ GreyBgF+ GuiElems+ HandleF+ HaskellIO+-- HbcLibrary+ HbcWord+ HelpBubbleF+ HorizontalAlignP+ HyperGraphicsF+ IdempotSP+ Image+ InOut+ InfixOps+ InputEditorF+ InputF+ InputMsg+ InputSP+ IntMemo+ InternAtom+ IoF+ IsRequest+ KernelUtils+ KeyGfx+-- LA+ LabelF+ Layout+ LayoutDir+ LayoutDoNow+ LayoutF+ LayoutHints+ LayoutOps+ LayoutRequest+ LayoutSP+ Layoutspec+ LinearSplitP+ List2+ ListF+ ListRequest+ LoadFont+ Loop+ LoopCompF+ LoopLow+ Loops+ Loopthrough+ LowLevel+ MGOps+ MapstateK+ MapstateMsg+ Maptrace+ Marshall+ MatrixP+ MeasuredGraphics+ MenuBarF+ MenuButtonF+ MenuF+ MenuPopupF+ Message+ MeterF+ MoreF+ MoreFileF+ MyForeign+ NameLayout+ NewCache+ NullF+ OldLayoutOps+ OnOffDispF+ OpenSocket+ PQueue+ P_IO_data+ PackedString+ ParF+ ParK+ ParSP+ ParagraphP+ Path+ PathTree+ Pixmap+ PixmapGen+ Placer+ Placers+ Placers2+ PopupF+ PopupGroupF+ PopupMenuF+ Popupmsg+ PosPopupShellF+ Process+ ProdF+ PushButtonF+ QueryPointer+ QueryTree+ Queue+ QuitButtonF+ QuitF+ QuitK+ RadioF+ ReadFileF+ Rects+ ResourceIds+ RootWindowF+ Route+ SP+ SPmonad+ SPstateMonad+ ScrollF+ SelectionF+ SerCompF+ ShapeGroupMgr+ ShapeK+ ShapedButtonsF+ Shells+ ShowCommandF+ ShowFailure+ ShowFun+ SimpleF+ Sizing+ SizingF+ SmileyF+ SocketServer+ Socketio+ Sockets+ SpEither+ SpIO+ Spacer+ Spacers+ Spinterp+ SplitF+ Spops+ SpyF+ Srequest+ StateMonads+ StdIoUtil+ StreamProc+ StreamProcIO+ StringEdit+ StringF+ StringUtils+ StructFuns+ Table+ TableP+ Tables+ Tables2+ TagEvents+ TerminalF+ TextExtents+ TextF+ TimerF+ TitleShellF+ ToggleButtonF+ ToggleGroupF+ TransCoord+ Transceivers+ Tree234+ TreeF+ TryLayout+ Types+ UndoStack+ UnsafeGetDLValue+ UnsafePerformIO+ UserLayoutF+ Utils+ Visual+ WindowF+ WriteFile+ XCallTypes+ XDraw+ XStuff+ XTypesModules+ Xcommand+ Xlib+ Xrequest+ Xtypes++Executable Graph+ hs-source-dirs: Demos/graph+ main-is: Graph.hs+ Other-modules: Compat Diff Eval Exp ExpF Lex Ops Parser Parsop PlotF Root+ Show Simp UserCoords ZoomF+ build-depends: base, fudgets+ Default-language: Haskell98++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable fudgetclock+ hs-source-dirs: Demos/clock+ main-is: fudgetclock.hs+ Other-modules: ClockF+ Default-language: Haskell98+ build-depends: base, fudgets+ if flag(old-time)+ Build-Depends: old-time+ else+ Build-Depends: time++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable StopWatch+ hs-source-dirs: Examples+ main-is: StopWatch.hs+ Default-language: Haskell98+ build-depends: base, fudgets++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable texteditor+ hs-source-dirs: Examples+ main-is: texteditor.hs+ Default-language: Haskell98+ build-depends: base, fudgets++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable FancyHello+ hs-source-dirs: Examples+ main-is: FancyHello.hs+ Default-language: Haskell98+ build-depends: base, fudgets++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable SpaceInvaders2+ hs-source-dirs: Demos/SpaceInvaders+ main-is: SpaceInvaders2.hs+ Other-modules: BitmapOps GUI InvaderTypes MainF Pics Pics1 ReadPic ScoreF WorldF Metrics+ Default-language: Haskell98+ build-depends: base, fudgets, random+--, split>=0.2++ ghc-options: -fno-warn-tabs+--if impl(ghc>=8.6)+-- Default-extensions: NoMonadFailDesugaring+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable Explore+ hs-source-dirs: Demos/Mandelbrot Demos/graph+ main-is: Explore.hs+ Other-modules: Mandelbrot UserCoords ZoomF+ Default-language: Haskell98+ ghc-options: -threaded+ build-depends: base, fudgets, array, parallel++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts -with-rtsopts=-N++Executable FudPaint+ hs-source-dirs: Demos/paint+ main-is: Paint.hs+ Other-modules: GraphF+ Default-language: Haskell98+ build-depends: base, fudgets++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable Life+ hs-source-dirs: Demos/life+ main-is: Main.hs+ other-modules: Generate Life Panel Timer Utils2+ Default-language: Haskell98+ build-depends: base, fudgets++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable Tiles+ hs-source-dirs: Demos/Tiles+ main-is: Main.hs+ Other-modules: BoardF ChoiceF DesignF DrawingF MyUtils RadioDrawF Tiles+ ToggleDrawGroupF ToolsF+ Default-language: Haskell98+ build-depends: base, fudgets++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable XMine+ hs-source-dirs: Demos/mines+ main-is: XMine.hs+ Other-modules: Box FUtil MineField Pics+ Default-language: Haskell98+ build-depends: base, fudgets, array, random++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts++Executable doRequest+ main-is: hsrc/doRequest.hs+ Default-language: Haskell98+ build-depends: base, fudgets++ ghc-options: -fno-warn-tabs+ if impl(ghc>=7.0)+ ghc-options: -rtsopts
+ hsrc/AllFudgets.hs view
@@ -0,0 +1,33 @@+-- | This module exposes everything, but there is very little documentation+-- here. See the+-- <http://www.altocumulus.org/Fudgets/Manual/ Fudget Library Reference Manual>+-- instead.+module AllFudgets + (module Combinators, module Containers,module Debug,module DrawingModules,+ module Filters,module GuiElems,module InfixOps,module KernelUtils,+ module Layout,module LowLevel,module Types,module XTypesModules,+ module FudUtilities,module StreamProc,module InOut,module DefaultParams) where+import GuiElems+import Combinators+import InfixOps+import Layout+import Containers+import Filters+import DrawingModules+import KernelUtils+import StreamProc+import InOut+import LowLevel+import XTypesModules+import Types+import FudUtilities+import Debug+import DefaultParams++{-+#ifdef __NHC_HASKELL__+-- nhc bug workaround+blaha1=Pixel 1+blaha2=Width 1+#endif+-}
+ hsrc/Fudgets.hs view
@@ -0,0 +1,259 @@+{-# LANGUAGE CPP #-}+#include "exists.h"+-- | Programmers' index. There is very little documentation here. See the+-- <http://www.altocumulus.org/Fudgets/Manual/ Fudget Library Reference Manual>+-- instead.+module Fudgets(+ -- * GUI+ buttonF, border3dF, buttonBorderF, pushButtonF,+ BMevents(..),+ popupMenuF, Click(..),+ radioGroupF, radioGroupF', intF, passwdF, stringF,+ intInputF, stringInputF, passwdInputF,+ intInputF', stringInputF', passwdInputF',+ toggleButtonF,+ -- ** Popups+ inputPopupOptF, inputPopupF,+ passwdPopupOptF, passwdPopupF, stringPopupOptF, stringPopupF,+ confirmPopupF, ConfirmMsg(..), oldConfirmPopupF, oldMessagePopupF,+ messagePopupF, intDispF, displayF, labelF,+ -- ** Text editor+ EditStop(..), editF,+ EditEvt(..), EditCmd(..), editorF, editorF', selectall, loadEditor,+ newline, EDirection(..), inputEditorF, inputEditorF', EditorF,+ EditStopFn(..), EditStopChoice(..), IsSelect(..),setEditorCursorPos,+ -- ** List and text+ oldFilePickF, PickListRequest(..),+ textF, textF',-- textF'',+ TextRequest(..), TextF, HasInitText(..), HasSizing(..),Sizing(..),+ ListRequest(..),+ replaceAll, replaceAllFrom, deleteItems, insertItems, appendItems,+ changeItems, replaceItems, highlightItems, pickItem, applyListRequest, + smallPickListF, labRightOfF, labLeftOfF, labBelowF, labAboveF,+ tieLabelF, menuF, PopupMenu(..), menuPopupF,+ pickListF, moreShellF,pickListF', moreShellF',+ moreFileShellF, moreFileF, moreF, moreF',+ terminalF, cmdTerminalF, TerminalCmd(..),+ -- ** Graphics+ hyperGraphicsF, hyperGraphicsF',GraphicsF,setAdjustSize,+ -- * Fudgets and combinators+ contDynF,+ Fudget(..), F, --F(..),+ listF,+ untaggedListF, loopCompF, loopCompSP, loopF, loopLeftF, loopRightF, loopOnlyF,+ loopThroughRightF, loopCompThroughLeftF, loopCompThroughRightF,+ loopThroughBothF,+ --Message,+ delayF, getF, putF, putsF, startupF, appendStartF, ++ nullF, parF, prodF, absF, bypassF, concatMapF, idF, idLeftF,+ idRightF, mapF, mapstateF, serCompLeftToRightF, serCompRightToLeftF, stubF,+ throughF, toBothF, (>*<), (>+<), (>=^<), (>=^^<),+ (>#+<), (>#==<), (>==<), (>^=<), (>^^=<),+ prepostMapHigh,++ quitIdF, quitF,++ DynFMsg(..), dynF, dynListF, DynMsg(..), --Either(..),+ FudgetIO(..),+ --Fa(..),Direction, TCommand(..),TEvent(..),++ {- FCommand(..), FEvent(..), K(..), KCommand(..), KEvent(..),+ TCommand(..), TEvent(..), -}+ -- ** Input+ InF(..), InputMsg(..), inputDoneSP, inputLeaveDoneSP,+ inputListSP, inputPairSP, inputThroughF, inputPairF, inputListF, inputChange,+ inputListLF, inputPairLF, -- obsolete+ stripInputSP,+ inputButtonKey, inputLeaveKey, inputMsg, mapInp, stripInputMsg,+ inputDone, inputLeaveDone,+ tstInp,++ -- * Layout+ Orientation(..),+ alignF, marginHVAlignF, layoutModifierF, noStretchF,+ marginF, sepF,+ autoP, flipP, permuteP, revP, idP,+ Alignment(..), aBottom, aCenter, aLeft, aRight, aTop,+ -- barP, rightBelowP,+ dynListLF, LayoutDir(..),+ listLF, nullLF, holeF,+ --rbLayoutF,+ untaggedListLF, LayoutRequest,+ Placer, center, center', fixedh, fixedv, flipPoint,+ flipRect, flipReq,++ NameLayout, LName(..),hvAlignNL, marginHVAlignNL, hBoxNL, hBoxNL',+ nullNL, leafNL, spaceNL, placeNL, + listNF, modNL, nameF, nameLayoutF, sepNL, marginNL, vBoxNL, vBoxNL',++ hBoxF, matrixF, placerF, spacerF, spacer1F, revHBoxF, revVBoxF, spacerP,+ tableF, vBoxF, horizontalP, horizontalP', matrixP, matrixP',+ verticalP, verticalP',paragraphP,paragraphP',paragraphP'',+ dynPlacerF, dynSpacerF, -- There are pitfalls with using these...++ Distance(..), Spacer, bottomS, centerS, compS, flipS,+ hAlignS, sizeS, maxSizeS, minSizeS, hCenterS, hMarginS, marginHVAlignS,+ hvAlignS, hvMarginS, idS, leftS, marginS, sepS, noStretchS,+ rightS, topS, vAlignS, vCenterS, vMarginS, tableP, tableP', bubbleF,+ bubblePopupF, bubbleRootPopupF, shellF, PotRequest(..), PotState(..),+ containerGroupF, hPotF, vPotF, popupShellF, popupShellF', PopupMsg(..),+ posPopupShellF, hScrollF, scrollF, scrollShellF, vScrollF,+ ESelCmd(..), ESelEvt(..), SelCmd(..), SelEvt(..), eselectionF,+ selectionF, allcacheF,+ {-+ bitmapdatacacheF, bitmapfilecacheF,+ colorcacheF, fontcacheF, fontcursorcacheF, fstructcacheF, gCcacheF,+ -}+ doubleClickF, Time(..),+ -- * Stream processors+ -- ** Combining stream processors+ (-+-),(-*-),(-==-),+ compEitherSP, idLeftSP, idRightSP, postMapSP, preMapSP,+ prepostMapSP, serCompSP, loopLeftSP, loopSP, loopOnlySP, loopThroughRightSP,+ loopThroughBothSP,+ parSP, seqSP,+ -- ** Stream processor primitives+ SP,nullSP,putSP,putsSP,getSP,+ StreamProcIO(..),runSP, walkSP, pullSP,++ {-SPm(..), bindSPm, getSPm, monadSP, nullSPm, putsSPm, thenSPm, toSPm, unitSPm,-}++ -- ** Convenient stream processors+ idSP, filterSP, filterJustSP, filterLeftSP, filterRightSP, mapFilterSP,+ splitSP, toBothSP,+ concatSP, concSP,+ mapSP, concatMapSP, concmapSP,+ concatMapAccumlSP, mapstateSP, mapAccumlSP,+ zipSP,+ -- ** Stream processor behaviour+ Cont(..),+ appendStartSP, chopSP, delaySP, feedSP,+ splitAtElemSP, startupSP, stepSP,+ cmdContSP, conts, getLeftSP, getRightSP, waitForSP, waitForF, dropSP, contMap,+ -- * System (stdio, files, network, subprocesses)+ -- ** Dialogue IO+ hIOF,+ hIOSuccF, hIOerrF, haskellIOF,+ inputLinesSP, linesSP,+ -- ** Stdio+ outputF, stderrF, stdinF,+ stdioF, stdoutF,+ -- ** Subprocesses+ subProcessF,+ -- ** Files and directories+ appStorageF,+ readDirF, readFileF, writeFileF,+ -- ** Sockets+ Host(..), LSocket(..), Peer(..), Port(..), Socket(..),+ openLSocketF,+ openSocketF, receiverF, transceiverF, transmitterF, asyncTransmitterF,+ asyncTransceiverF,+ -- ** Timer+ Tick(..), timerF,+ --dropF,+ -- ** Running a fudget+ fudlogue, fudlogue', Fudlogue,+ -- * Command line, environment and defaults+ argFlag, argKey, argReadKey, argKeyList, args, progName,+ bgColor, buttonFont, defaultFont, defaultSize,+ defaultPosition, defaultSep, edgeWidth, fgColor, labelFont, look3d,+ menuFont, options, paperColor, shadowColor, shineColor,+ -- * Utilities for the Either type+ filterLeft, filterRight, isLeft, isRight, mapEither,+ fromLeft, fromRight, plookup, splitEitherList, stripEither, stripLeft,+ -- mapfilter, isM, stripMaybe, stripMaybeDef,+ -- use Maybe.mapMaybe,isJust,fromJust,fromMaybe!+ stripRight, swapEither,+ -- * Geometry+ (=.>),+ Line(..), Point(..), Rect(..), Size(..), Move(..), confine, diag, freedom,+ growrect, inRect, lL, line2rect, moveline, moverect, origin, pMax,+ pMin, pP, padd, plim, pmax, pmin, posrect, psub, rR, rect2line,+ rectMiddle,+ rmax, rsub, scale, scalePoint, sizerect,+ --xcoord, ycoord, rectpos, rectsize,+ -- * Utilities+ aboth, anth, gmap, -- afst, asnd, dropto, + issubset, lhead, loop, lsplit, ltail, mapPair, number, oo, pair,+ pairwith, part, remove, replace, swap, unionmap, module FudVersion,++ -- * Xlib types+ XCommand, XEvent, Path(..),+ Button(..), ColorName(..), FontName(..), KeySym(..), FontStruct, RGB(..),+ WindowAttributes, + ModState(..), Modifiers(..), + -- * Graphics and drawings+ CoordMode(..),Shape(..),+ DrawCommand(..),fillCircle,drawCircle,+ Graphic(..),+ Drawing(..),atomicD,labelD,up,boxD,hboxD,hboxD',vboxD,vboxD',tableD,tableD',+ hboxcD,hboxcD',vboxlD,vboxlD',matrixD,matrixD',+ attribD,softAttribD,hardAttribD,fontD,fgD,stackD,spacedD,placedD,+ blankD,filledRectD,rectD,+ DPath(..),+#ifdef USE_EXIST_Q+ Gfx,+#endif+ g,+ FixedDrawing(..),FixedColorDrawing(..),gctx2gc,+ FlexibleDrawing(..),flex,flex',+ filler,hFiller,vFiller,frame,frame',ellipse,ellipse',arc,arc',+ filledEllipse,filledEllipse',filledarc,filledarc',+ lpar,rpar,lbrack,rbrack,lbrace,rbrace,+ triangleUp,triangleDown,filledTriangleUp,filledTriangleDown,+ BitmapFile(..),+ ColorGen(..),FontGen(..),FontSpec,ColorSpec,--Name(..),--ColorFallback(..),+#ifdef USE_EXIST_Q+ colorSpec,fontSpec,+#endif+ GCtx,rootGCtx,wCreateGCtx,createGCtx,gcFgA,gcBgA,gcFontA,+ GCAttributes(..),GCFillStyle(..),GCCapStyle(..),GCLineStyle(..),GCFunction(..),+ Width(..),++ -- * Customisation+ Customiser(..), PF(..), standard,++ HasClickToType(..), HasVisible(..), HasFontSpec(..), setFont,+ HasKeys(..), HasWinAttr(..), --HasTitle(..),+ HasBorderWidth(..), HasBgColorSpec(..), HasFgColorSpec(..), HasMargin(..),+ setBgColor,setFgColor,+ HasAlign(..),+ {- HasAllowedChar(..), HasShowString(..), -}+ setAllowedChar, setShowString, setCursorPos,+ HasCache(..),+ setDeleteQuit,setDeleteWindowAction,DeleteWindowAction(..),--HasDeleteQuit(..),+ HasInitSize(..),+ HasInitDisp(..),+ --setInitDisp, getInitDisp,+ setSpacer,+ HasStretchable(..),+ HasLabelInside(..),setPlacer,++ ShellF, shellF', setInitPos,+ unmappedSimpleShellF, unmappedSimpleShellF',+ ButtonF, buttonF', buttonF'', setLabel,+ DisplayF, displayF',-- displayF'',+ labelF', --labelF'',+ StringF, stringF', stringF'', setInitString, setInitStringSize,+ passwdF', passwdF'',+ intF', intF'',+ intDispF', --intDispF'',+ -- * Miscellaneous+ gcWarningF,bellF,+ --D_IOError,+ -- * Time+#ifdef VERSION_old_time+ getTime,getLocalTime,+#endif+#ifdef VERSION_time+ getCurrentTime,getZonedTime,+#endif+ -- * Debugging+ spyF,teeF, ctrace,showCommandF) where++import AllFudgets -- hiding (Cont,PCont,Fa)+import FudVersion++-- I hate this file /TH+-- I still hate this file /TH
+ hsrc/combinators/BranchF.hs view
@@ -0,0 +1,70 @@+module BranchF(branchF,branchFSP) where+import Direction+import Fudget+--import Path(Path(..))+import Route+import SP+--import Message(Message(..))++branchF :: (F (Path, a) b) -> (F (Path, a) b) -> F (Path, a) b+branchF (F f1) (F f2) = F{-ff-} (branchFSP f1 f2)++branchFSP :: (FSP (Path, a) b) -> (FSP (Path, a) b) -> FSP (Path, a) b+branchFSP f1 f2 =+ case f1 of+ PutSP (Low tcmd) f1' -> PutSP (compTurnLeft tcmd) (branchFSP f1' f2)+ PutSP msg f1' -> PutSP msg (branchFSP f1' f2)+ GetSP xf1 -> branchF1 xf1 f2+ NullSP -> restF2 f2++--and branchF1:: (FEvent *a->F *a *b) -> F *c *d -> F (Either *a *c) (Either *b *d)+branchF1 xf1 f2 =+ case f2 of+ PutSP (Low tcmd) f2' -> PutSP (compTurnRight tcmd) (branchF1 xf1 f2')+ PutSP msg f2' -> PutSP msg (branchF1 xf1 f2')+ GetSP xf2 -> GetSP (branchF12 xf1 xf2)+ NullSP -> GetSP (restF1x xf1)++--and branchF2:: F *a *b -> (FEvent *c->F *c *d) -> F (Either *a *c) (Either *b *d)+branchF2 f1 xf2 =+ case f1 of+ PutSP (Low tcmd) f1' -> PutSP (compTurnLeft tcmd) (branchF2 f1' xf2)+ PutSP msg f1' -> PutSP msg (branchF2 f1' xf2)+ GetSP xf1 -> GetSP (branchF12 xf1 xf2)+ NullSP -> GetSP (restF2x xf2)++--and branchF12:: (FEvent *a->F *a *b) -> (FEvent *c->F *c *d) -> FEvent (Either *a *c) -> F (Either *a *c) (Either *b *d)+branchF12 xf1 xf2 msg =+ case msg of+ High (L : path', x) -> branchF2 (xf1 (High (path', x))) xf2+ High (R : path', y) -> branchF1 xf1 (xf2 (High (path', y)))+ Low (L : path', x) -> branchF2 (xf1 (Low (path', x))) xf2+ Low (R : path', y) -> branchF1 xf1 (xf2 (Low (path', y)))+ _ -> GetSP (branchF12 xf1 xf2)++restF2 f2 =+ case f2 of+ PutSP (Low tcmd) f2' -> PutSP (compTurnRight tcmd) (restF2 f2')+ PutSP msg f2' -> PutSP msg (restF2 f2')+ GetSP xf2 -> GetSP (restF2x xf2)+ NullSP -> NullSP++restF2x xf2 msg =+ case msg of+ High (R : path', y) -> restF2 (xf2 (High (path', y)))+ Low (R : path', ev) -> restF2 (xf2 (Low (path', ev)))+ _ -> GetSP (restF2x xf2)++restF1 f1 =+ case f1 of+ PutSP (Low tcmd) f1' -> PutSP (compTurnLeft tcmd) (restF1 f1')+ PutSP msg f1' -> PutSP msg (restF1 f1')+ GetSP xf1 -> GetSP (restF1x xf1)+ NullSP -> NullSP++restF1x xf1 msg =+ case msg of+ High (L : path', x) -> restF1 (xf1 (High (path', x)))+ Low (L : path', ev) -> restF1 (xf1 (Low (path', ev)))+ _ -> GetSP (restF1x xf1)+
+ hsrc/combinators/Combinators.hs view
@@ -0,0 +1,19 @@+module Combinators (-- * Combinators+ module BranchF,module CompF,module ParF,module CompFfun,module DynListF,module ListF,module LoopLow,module Loops,module LoopCompF,module NullF,module ProdF,module Route,module SerCompF,module StateMonads,module TreeF,module InputF,module ContDynF) where+import BranchF+import CompF+import ParF+import CompFfun+import DynListF+import ListF+import LoopLow+import Loops+import LoopCompF+import NullF+import ProdF+import Route+import SerCompF+import StateMonads+import TreeF+import InputF+import ContDynF
+ hsrc/combinators/CompF.hs view
@@ -0,0 +1,72 @@+module CompF(compF) where+import Fudget+--import Message(Message(..))+import Route+import SP+import Direction+import LayoutHints++--import Maptrace(ctrace) -- debugging++compF (F f1) (F f2) = layoutHintF parHint (F{-ff-} (compF' f1 f2))++compF' :: FSP a b -> FSP c d -> FSP (Either a c) (Either b d)+compF' f1 f2 =+ case f1 of+ PutSP (High x) f1' -> PutSP (High (Left x)) (compF' f1' f2)+ PutSP (Low tcmd) f1' -> PutSP (compTurnLeft tcmd) (compF' f1' f2)+ GetSP xf1 -> compF1 xf1 f2+ NullSP -> restF2 f2++compF1 :: (FEvent a -> FSP a b) -> FSP c d -> FSP (Either a c) (Either b d)+compF1 xf1 f2 =+ case f2 of+ PutSP (High y) f2' -> PutSP (High (Right y)) (compF1 xf1 f2')+ PutSP (Low tcmd) f2' -> PutSP (compTurnRight tcmd) (compF1 xf1 f2')+ GetSP xf2 -> GetSP (compF12 xf1 xf2)+ NullSP -> GetSP (restF1x xf1)++compF2 :: FSP a b -> (FEvent c -> FSP c d) -> FSP (Either a c) (Either b d)+compF2 f1 xf2 =+ case f1 of+ PutSP (High x) f1' -> PutSP (High (Left x)) (compF2 f1' xf2)+ PutSP (Low tcmd) f1' -> PutSP (compTurnLeft tcmd) (compF2 f1' xf2)+ GetSP xf1 -> GetSP (compF12 xf1 xf2)+ NullSP -> GetSP (restF2x xf2)++compF12 :: (FEvent a -> FSP a b) -> (FEvent c -> FSP c d) -> (FEvent (Either a c)) -> FSP (Either a c) (Either b d)+compF12 xf1 xf2 msg =+ case msg of+ High (Left x) -> compF2 (xf1 (High x)) xf2+ High (Right y) -> compF1 xf1 (xf2 (High y))+ Low (tag, ev) -> case tag of+ L : tag' -> compF2 (xf1 (Low (tag', ev))) xf2+ R : tag' -> compF1 xf1 (xf2 (Low (tag', ev)))+ _ -> {-ctrace "drop" (tag,ev) $-} GetSP (compF12 xf1 xf2)++restF2 f2 =+ case f2 of+ PutSP (High y) f2' -> PutSP (High (Right y)) (restF2 f2')+ PutSP (Low tcmd) f2' -> PutSP (compTurnRight tcmd) (restF2 f2')+ GetSP xf2 -> GetSP (restF2x xf2)+ NullSP -> NullSP++restF2x xf2 msg =+ case msg of+ High (Right y) -> restF2 (xf2 (High y))+ Low (R : tag, ev) -> restF2 (xf2 (Low (tag, ev)))+ _ -> GetSP (restF2x xf2)++restF1 f1 =+ case f1 of+ PutSP (High y) f1' -> PutSP (High (Left y)) (restF1 f1')+ PutSP (Low tcmd) f1' -> PutSP (compTurnLeft tcmd) (restF1 f1')+ GetSP xf1 -> GetSP (restF1x xf1)+ NullSP -> NullSP++restF1x xf1 msg =+ case msg of+ High (Left x) -> restF1 (xf1 (High x))+ Low (L : tag, ev) -> restF1 (xf1 (Low (tag, ev)))+ _ -> GetSP (restF1x xf1)+
+ hsrc/combinators/CompFfun.hs view
@@ -0,0 +1,61 @@+module CompFfun where+import CompSP+import Fudget+import Message+--import Path(Path(..))+--import SP++postProcessHigh postsp (F sp) = F{-ff-} (postProcessHigh' postsp sp)+postProcessLow postsp (F sp) = F{-ff-} (postProcessLow' postsp sp)+preProcessHigh (F sp) presp = F{-ff-} (preProcessHigh' sp presp)+preProcessLow (F sp) presp = F{-ff-} (preProcessLow' sp presp)+preMapHigh (F sp) pre = F{-ff-} (preMapHigh' sp pre)+postMapHigh post (F sp) = F{-ff-} (postMapHigh' post sp)+preMapLow (F sp) pre = F{-ff-} (preMapLow' sp pre)+postMapLow post (F sp) = F{-ff-} (postMapLow' post sp)++postProcessHighK postsp (K sp) = K{-kk-} (postProcessHigh' postsp sp)+postProcessLowK postsp (K sp) = K{-kk-} (postProcessLow' postsp sp)+preProcessHighK (K sp) presp = K{-kk-} (preProcessHigh' sp presp)+preProcessLowK (K sp) presp = K{-kk-} (preProcessLow' sp presp)+preMapHighK (K sp) pre = K{-kk-} (preMapHigh' sp pre)+postMapHighK post (K sp) = K{-kk-} (postMapHigh' post sp)+preMapLowK (K sp) pre = K{-kk-} (preMapLow' sp pre)+postMapLowK post (K sp) = K{-kk-} (postMapLow' post sp)++postProcessHigh' :: (SP a b) -> (Fa c d e a) -> Fa c d e b+postProcessHigh' p f = serCompSP (idLowSP p) f++postProcessLow' :: (SP a b) -> (Fa c a d e) -> Fa c b d e+postProcessLow' p f = serCompSP (idHighSP p) f++preProcessHigh' :: (Fa a b c d) -> (SP e c) -> Fa a b e d+preProcessHigh' f p = serCompSP f (idLowSP p)++preProcessLow' :: (Fa a b c d) -> (SP e a) -> Fa e b c d+preProcessLow' f p = serCompSP f (idHighSP p)++preMapHigh' :: (Fa a b c d) -> (e -> c) -> Fa a b e d+preMapHigh' f pre = preMapSP f (aHigh pre)++preMapLow' :: (Fa a b c d) -> (e -> a) -> Fa e b c d+preMapLow' f pre = preMapSP f (aLow pre)++postMapHigh' :: (a -> b) -> (Fa c d e a) -> Fa c d e b+postMapHigh' post f = postMapSP (aHigh post) f++postMapLow' :: (a -> b) -> (Fa c a d e) -> Fa c b d e+postMapLow' post f = postMapSP (aLow post) f++prepostMapHigh' :: (a -> b) -> (c -> d) -> (Fa e f b c) -> Fa e f a d+prepostMapHigh' pre post f = prepostMapSP (aHigh pre) (aHigh post) f+++prepostMapHigh pre post (F sp) = F{-ff-} (prepostMapHigh' pre post sp)+prepostMapHighK pre post (K sp) = K{-kk-} (prepostMapHigh' pre post sp)++prepostMapLow' :: (a -> b) -> (c -> d) -> (Fa b c e f) -> Fa a d e f+prepostMapLow' pre post f = prepostMapSP (aLow pre) (aLow post) f++prepostMapLow pre post (F sp) = F (prepostMapLow' pre post sp)+prepostMapLowK pre post (K sp) = K (prepostMapLow' pre post sp)
+ hsrc/combinators/ContDynF.hs view
@@ -0,0 +1,27 @@+module ContDynF where++import Fudget+--import Xtypes+import Command+import FRequest+--import LayoutRequest(LayoutRequest)+--import Geometry+--import Message+import Spops(getSP,putSP,walkSP,pullSP)+import Path(here)+--import Direction+import Cont+--import Dynforkmerge+--import NullF(getMessageF,putMessageF)+--import LayoutDir++contDynF :: F a b -> Cont (F a d) b+contDynF (F sp) = fContWrap (contDynFSP sp)++contDynFSP :: FSP a b -> Cont (FSP a d) b+contDynFSP f c = cdf (pullSP f)+ where cdf (outf,f') = out f' outf + out f' [] = getSP $ \msg -> cdf (walkSP f' msg)+ out f' (x:xs) = case x of+ High msg -> putSP (Low (here,XCmd DestroyWindow)) $ c msg+ Low cmd -> putSP (Low cmd) $ out f' xs
+ hsrc/combinators/DynListF.hs view
@@ -0,0 +1,40 @@+module DynListF(dynF, DynFMsg(..), dynListF) where+import Command+import FRequest+--import Xtypes+import CompOps((>^=<),(>=^^<))+import CompSP+import Dynforkmerge+import Fudget+--import Message(Message(..))+import NullF+import Spops+import Direction+import Path+import LayoutRequest++type DynFMsg a b = DynMsg a (F a b)++dynListF :: F (Int, DynFMsg a b) (Int, b)+dynListF =+ let prep (High (t, DynMsg m)) = [High (t, DynMsg (High m))]+ prep (High (t, DynDestroy)) = + map tag [XCmd DestroyWindow,LCmd LayoutDestroy] + ++ [High (t, DynDestroy)] + where tag m = Low (turn (Dno t) here, m)+ prep (High (t, DynCreate (F f))) = [High (t, DynCreate f)]+ prep (Low ([], ev)) = []+ prep (Low (tag, ev)) =+ case path tag of+ (Dno i, tag') -> [High (i, DynMsg (Low (tag', ev)))]+ _ -> [] -- wrong address!+ post (High (t, High m)) = High (t, m)+ post (High (i, Low (tag, cmd))) = Low (turn (Dno i) tag, cmd)+ post (Low c) = Low c+ in F{-ff-} $ serCompSP (postMapSP post (idLowSP dynforkmerge)) (concmapSP prep)++dynF :: (F a b) -> F (Either (F a b) a) b+dynF f0 =+ let prep (Left f) = [(0, DynDestroy), (0, DynCreate f)]+ prep (Right m) = [(0, DynMsg m)]+ in (snd >^=< startupF [(0, DynCreate f0)] dynListF) >=^^< concmapSP prep
+ hsrc/combinators/InputF.hs view
@@ -0,0 +1,29 @@+module InputF(module InputF) where+import Fudget+import InputMsg+import CompOps+import ListF(listF)+import Placer(placerF)+import LayoutF(orientP)+import EitherUtils(stripEither)+import Spops+import InputSP+import AuxTypes() -- synonym KeySym, for hbc+import SpEither(splitSP)+import SerCompF(mapF,toBothF)++type InF a b = F a (InputMsg b)++inputPairLF orient f1 f2 = placerF (orientP orient) $ inputPairF f1 f2+inputListLF placer tfs = placerF placer $ inputListF tfs++inputPairF :: InF a1 b1 -> InF a2 b2 -> InF (a1,a2) (b1,b2)+inputPairF f1 f2 = inputPairSP >^^=< (f1>+<f2) >=^^< splitSP++inputListF :: (Eq a) => [(a, InF b c)] -> InF [(a, b)] [(a, c)] +inputListF tfs =+ inputListSP (map fst tfs) >^^=< listF [(t,f)|(t,f)<-tfs] >=^^< concatSP++inputThroughF :: InF a a -> InF a a+inputThroughF f = stripEither>^=<(f>+<mapF InputChange)>==<toBothF+
+ hsrc/combinators/ListF.hs view
@@ -0,0 +1,74 @@+module ListF(listF,untaggedListF) where+import CompF+import CompSP(prepostMapSP)+import CompSP(preMapSP)+import CompOps((>^=<),(>=^^<))+import Direction+import Fudget+--import ListMap(lookupWithDefault)+--import Message(Message(..))+--import NullF+--import Path(Path(..))+import Spops+import TreeF+import Utils(number,pair)+import HbcUtils(apSnd,lookupWithDefault)+import LayoutHints++untaggedListF :: [F a b] -> F a b+untaggedListF fs = snd >^=< listF tfs >=^^< concatMapSP broadcast+ where+ tfs = number 0 fs+ ns = map fst tfs+ broadcast x = map (`pair` x) ns++listF :: {-Prelude.-}Eq a => [(a, F b c)] -> F (a, b) (a, c)+listF = layoutHintF listHint . F{-ff-} . listF'++listF' :: Eq a => [(a, F b c)] -> FSP (a, b) (a, c)+listF' [(tag, F w)] =+ let prepinp (High (t, a)) =+ if t == tag then High a else error "Unknown tag in listF"+ prepinp (Low tev) = Low tev+ prepout (High b) = High (tag, b)+ prepout (Low cmd) = Low cmd+ in prepostMapSP prepinp prepout w+listF' [(ltag, lw), (rtag, rw)] =+ let prepinp (High (tag, a)) =+ if tag == ltag then+ High (Left a)+ else+ if tag == rtag then+ High (Right a)+ else+ error "Unknown tag in listF"+ prepinp (Low tev) = Low tev+ prepout (High (Left b)) = High (ltag, b)+ prepout (High (Right b)) = High (rtag, b)+ prepout (Low cmd) = Low cmd+ F lwrw = compF lw rw+ in prepostMapSP prepinp prepout lwrw+listF' [] = nullSP+listF' wtab =+ let tree = balancedTree wtab+ paths = pathtab tree+ prepinp (High (tag, a)) =+ let path' = lookupWithDefault paths (error "Unknown tag in listF") tag+ in High (path', a)+ prepinp (Low tev) = Low tev+ in preMapSP (treeF' tree) prepinp++pathtab (Leaf (t, _)) = [(t, [])]+pathtab (Branch l r) =+ map (apSnd (L :)) (pathtab l) ++ map (apSnd (R :)) (pathtab r)++balancedTree xs =+ case xs of+ [x] -> Leaf x+ _ -> let (l, r) = split2 xs+ in Branch (balancedTree l) (balancedTree r)++split2 l =+ let sp = length l `quot` 2+ in (take sp l, drop sp l)+
+ hsrc/combinators/LoopCompF.hs view
@@ -0,0 +1,30 @@+module LoopCompF(loopCompF,loopCompSP,loopThroughBothF,loopThroughBothSP) where+import Fudget +import CompFfun(prepostMapHigh)+import CompF(compF)+import CompSP(compSP,prepostMapSP)+import Loop(loopLeftSP)+import Loops(loopLeftF)++-- loopComp = symmetric version of loopThroughRight++loopCompF :: F (Either (Either r2l inl) (Either l2r inr))+ (Either (Either l2r outl) (Either r2l outr)) ->+ F (Either inl inr) (Either outl outr)+loopCompF = loopLeftF . prepostMapHigh pre post++loopThroughBothF fud1 fud2 = loopCompF (fud1 `compF` fud2)+loopThroughBothSP sp1 sp2 = loopCompSP (sp1 `compSP` sp2)++loopCompSP = loopLeftSP . prepostMapSP pre post++post (Left (Left x)) = Left (Left x)+post (Left (Right x)) = Right (Left x)+post (Right (Left x)) = Left (Right x)+post (Right (Right x)) = Right (Right x)+-- post = either (either (Left.Left) (Right.Left)) (either (Left.Right) (Right.Right))++pre (Right (Left x)) = Left (Right x)+pre (Right (Right x)) = Right (Right x)+pre (Left (Left x)) = Right (Left x)+pre (Left (Right x)) = Left (Left x)
+ hsrc/combinators/LoopLow.hs view
@@ -0,0 +1,46 @@+module LoopLow(loopLow,loopThroughLowSP,loopThroughLowF) where+--import Command(Command(..))+import CompSP+--import Event(Event(..))+import Fudget+import Loop+--import Message(Message(..))+--import Path(Path(..))+--import SP+import Loopthrough(loopThroughRightSP)++loopLow :: (SP TCommand (FCommand a)) -> (SP (FEvent a) TEvent) -> (F b c) -> F b c+loopLow ch eh (F f) =+ let prep (Left msg) = Low (High msg)+ prep (Right (High msg)) = High msg+ prep (Right (Low msg)) = Low (Low msg)+ post (High msg) = Right (High msg)+ post (Low (High msg)) = Left msg+ post (Low (Low msg)) = Right (Low msg)+ in F{-ff-} $+ loopLeftSP+ (prepostMapSP prep post + (idHighSP ch `serCompSP` f `serCompSP` idHighSP eh))++loopThroughLowSP :: SP (Either c e) (Either c e) -> + SP (Message e a) (Message c b) ->+ SP (Message e a) (Message c b)++loopThroughLowSP ctrl f =+ loopThroughRightSP (prepostMapSP prep post (idHighSP ctrl)) f+ where+ prep msg = case msg of+ Right (High a) -> High (Left a)+ Left (High a) -> High (Right a)+ Right (Low e) -> Low (Right e)+ Left (Low c) -> Low (Left c)++ post msg = case msg of+ High (Left msg) -> Left (High msg)+ High (Right msg) -> Right (High msg)+ Low (Left c) -> Right (Low c)+ Low (Right e) -> Left (Low e)++loopThroughLowF+ :: SP (Either TCommand TEvent) (Either TCommand TEvent) -> F i o -> F i o+loopThroughLowF ctrlSP (F fudSP) = F $ loopThroughLowSP ctrlSP fudSP
+ hsrc/combinators/Loops.hs view
@@ -0,0 +1,76 @@+module Loops(loopF, loopThroughRightF, loopCompThroughRightF, loopCompThroughLeftF, loopRightF, loopLeftF, loopOnlyF) where+import Maptrace(ctrace) -- debugging -- syntax error if you put this is last in the import list. TH 960428+--import Command(Command(..))+import CompFfun(prepostMapHigh)+--import CompSP(prepostMapSP)+import CompOps+--import Event(Event(..))+import Fudget+import Loop+--import Message(Message(..))+--import Path(Path(..))+--import SP+import SpEither(toBothSP,mapFilterSP)+import EitherUtils(stripEither, swapEither)+import LayoutHints+import Route+import Direction+import Loopthrough+import CompSP+++loopLeftF :: (F (Either a b) (Either a c)) -> F b c+loopLeftF (F sp) =+ let post (Low x) = Right (Low x)+ post (High (Right x)) = Right (High x)+ post (High (Left x)) = Left x+ pre (Right (Low x)) = Low x+ pre (Right (High x)) = High (Right x)+ pre (Left xs) = High (Left xs)+ in {-layoutHintF loopHint-} (F{-ff-} $ loopLeftSP (prepostMapSP pre post sp))++loopRightF :: (F (Either a b) (Either c b)) -> F a c+loopRightF f = loopLeftF (prepostMapHigh swapEither swapEither f)++loopThroughRightF :: F (Either a b) (Either c d) -> F c a -> F b d+loopThroughRightF (F m) (F s) = + --loopThroughRightSP (prepostMapSP pre post (idRightSP m)) s where+ layoutHintF loopHint $+ F{-ff-} $+ loopThroughRightSP+ (post `postMapSP` (idRightSP m) `serCompSP` mapFilterSP pre) s where++ post (Left (Low c)) = Right (compTurnLeft c)+ post (Right (Left c)) = Right (compTurnRight c)+ post (Right (Right e)) = Left (Low e)+ post (Left (High (Left m))) = Left (High m)+ post (Left (High (Right m))) = Right (High m)++ pre (Right (Low (p,e))) =+ case p of+ L:p -> Just $ Left (Low (p,e))+ R:p -> Just $ Right (Right (p,e))+ _ -> ctrace "drop" (p,e) $ Nothing --error "Dno in loopThroughRightF"+ pre (Left (Low c)) = Just $ Right (Left c)+ pre (Right (High m)) = Just $ Left (High (Right m))+ pre (Left (High m)) = Just $ Left (High (Left m))++loopCompThroughRightF :: (F (Either (Either a b) c) (Either (Either c d) a)) -> F b d+loopCompThroughRightF w =+ let post (Left (Left x)) = Left (Right x)+ post (Left (Right x)) = Right x+ post (Right x) = Left (Left (Left x))+ pre (Left x) = x+ pre (Right x) = Left (Right x)+ in loopLeftF (prepostMapHigh pre post w)+++loopCompThroughLeftF :: (F (Either a (Either b c)) (Either b (Either a d))) -> F c d+loopCompThroughLeftF f =+ loopCompThroughRightF (prepostMapHigh swapEither swapEither f)++loopOnlyF :: F a a -> F a b+loopOnlyF f = loopLeftF (prepostMapHigh stripEither Left f)++loopF :: F a a -> F a a+loopF f = loopLeftF (toBothSP>^^=<f>=^<stripEither)
+ hsrc/combinators/NullF.hs view
@@ -0,0 +1,87 @@+module NullF(module NullF, Cont(..),K,F,StreamProcIO(..),FudgetIO(..)) where+import Utils(pair)+import Fudget+import Message(aLow,stripHigh) --Message(..),+import Path(here)+import Spops+import Cont(dropSP,kContWrap,fContWrap,waitForK,waitForFu)+import StreamProcIO+import FudgetIO++--{- -}+instance StreamProcIO F where+ put = putF+ get = getF -- Discards low level input! Leave undefined?+ end = nullF++instance StreamProcIO K where+ put = putHigh+ get = getHigh+ end = nullK++instance FudgetIO F where+ waitForMsg = waitForFu+ putMsg = putMessageFu+ --nullMsg = nullF+ --getMsg = getMessageFu+++instance FudgetIO K where+ putMsg = putK+ waitForMsg = waitForK+ --nullMsg = nullK+ --getMsg = getK++---}++----++nullK = K{-kk-} nullSP+nullF = F{-ff-} nullSP++--putK :: KCommand ho -> K hi ho -> K hi ho+putK o (K sp) = kk (putSP o sp)++putF = putMessageF . High++putsF = puts :: ([b] -> F a b -> F a b)+--putsF his f = foldr putF f his+putsK = putMsgs :: ([KCommand b] -> K a b -> K a b)+--putsK msgs k = foldr putK k msgs++putMessageF msg (F sp) = F{-ff-} (putSP msg sp)+putMessageFu = putMessageF . aLow (pair here)++putMessagesF hos (F sp) = F{-ff-} (putsSP hos sp)+putMessagesFu = putMsgs :: ([KCommand b] -> F a b -> F a b)+--putMessagesFu msgs f = foldr putMessageFu f msgs++--appendStartK :: [KCommand b] -> K a b -> K a b+appendStartK kcmds (K sp) = kk (appendStartSP kcmds sp)++--appendStartMessageF :: [FCommand b] -> F a b -> F a b+appendStartMessageF fcmds (F sp) = F{-ff-} (appendStartSP fcmds sp)++--appendStartF :: [b] -> F a b -> F a b+appendStartF = appendStartMessageF . map High++getK = kContWrap getSP -- :: (Cont (K a b) (KEvent a))++getMessageF = fContWrap getSP -- :: (Cont (F a b) (FEvent a))+getMessageFu = fContWrap (getSP . (. aLow snd)) :: (Cont (F a b) (KEvent a))++--getF :: Cont (F a b) a+getF = fContWrap (dropSP stripHigh)++--startupK :: ([KEvent a] -> K a b -> K a b)+startupK kevs (K sp) = kk (startupSP kevs sp)+--startupMessageF :: ([FEvent a] -> F a b -> F a b)+startupMessageF fevs (F sp) = F{-ff-} (startupSP fevs sp)++--startupMessageFu = startupMessageF . map (aLow (pair here)) -- error prone++--startupF :: [a] -> F a b -> F a b+startupF = startupMessageF . map High++--delayF :: (F a b -> F a b)+delayF (F sp) = F{-ff-} (delaySP sp)
+ hsrc/combinators/ParF.hs view
@@ -0,0 +1,10 @@+module ParF(parF) where+--import Fudget+import EitherUtils(stripEither)+import CompF(compF)+--import SerCompF(serCompF)+import CompFfun(postMapHigh,preProcessHigh)+import SpEither(toBothSP)++-- Quick (i.e. slow) implementation+parF f1 f2 = stripEither `postMapHigh` compF f1 f2 `preProcessHigh` toBothSP
+ hsrc/combinators/ProdF.hs view
@@ -0,0 +1,8 @@+module ProdF where+import CompOps((>+<), (>=^^<))+import Fudget+import SpEither(splitSP)++prodF :: (F a b) -> (F c d) -> F (a, c) (Either b d)+prodF leftw rightw = (leftw >+< rightw) >=^^< splitSP+
+ hsrc/combinators/Route.hs view
@@ -0,0 +1,13 @@+module Route(compTurnRight, compTurnLeft, compPath) where+import Direction+import Message(Message(..))+import Path({-Path(..),-}path, turn)++compPath (tag, ev) wrongaddr c =+ case path tag of+ (L, tag') -> c $ Left (Low (tag', ev))+ (R, tag') -> c $ Right (Low (tag', ev))+ _ -> wrongaddr++compTurnLeft (tag, cmd) = Low (turn L tag, cmd)+compTurnRight (tag, cmd) = Low (turn R tag, cmd)
+ hsrc/combinators/SerCompF.hs view
@@ -0,0 +1,87 @@+module SerCompF(stubF, bypassF, throughF, toBothF,+ idF, concatMapF, mapF, mapstateF, absF, idLeftF,+ idRightF, serCompLeftToRightF, serCompRightToLeftF,+ serCompF) where+--import Command(Command(..))+import CompF+import CompFfun(postMapHigh)+import CompSP+--import Direction+--import Event(Event(..))+import Fudget+import Loop+--import Message(Message(..))+import NullF+--import Path(Path(..))+import Route+import Spops+import EitherUtils(stripEither)+import LayoutHints++serCompF (F f1) (F f2) = layoutHintF serHint (F{-ff-} $ serCompF' f1 f2)++serCompF' :: FSP a b -> FSP c a -> FSP c b+serCompF' f1 f2 =+ let post (Left (High x)) = High x+ post (Left (Low tcmd)) = compTurnLeft tcmd+ post (Right tcmd) = compTurnRight tcmd+ mid (Left ltev) = Left ltev+ mid (Right (Low tcmd)) = Right tcmd+ mid (Right (High x)) = Left (High x)+ pre (High x) = [Right (High x)]+ pre (Low ([], _)) = []+ pre (Low tev) = compPath tev [] (:[])+ in serCompSP (postMapSP post+ (serCompSP (idRightSP f1)+ (postMapSP mid (idLeftSP f2))))+ (concmapSP pre)++serCompRightToLeftF :: (F (Either a b) (Either c a)) -> F b c+serCompRightToLeftF (F sp) =+ let post (Low x) = Right (Low x)+ post (High (Left x)) = Right (High x)+ post (High (Right x)) = Left x+ pre (Right (Low x)) = Low x+ pre (Right (High x)) = High (Right x)+ pre (Left xs) = High (Left xs)+ in F{-ff-} $ loopLeftSP (prepostMapSP pre post sp)++serCompLeftToRightF :: (F (Either a b) (Either b c)) -> F a c+serCompLeftToRightF (F sp) =+ let post (Low x) = Right (Low x)+ post (High (Right x)) = Right (High x)+ post (High (Left x)) = Left x+ pre (Right (Low x)) = Low x+ pre (Right (High x)) = High (Left x)+ pre (Left xs) = High (Right xs)+ in F{-ff-} $ loopLeftSP (prepostMapSP pre post sp)++idRightF :: (F a b) -> F (Either a c) (Either b c)+--and idRightF w = w:+:idF+idRightF w = compF w idF++idLeftF w = compF idF w++absF :: (SP a b) -> F a b+absF sp =+ let pre (High x) = [x]+ pre (Low y) = []+ in F{-ff-} $ serCompSP (postMapSP High sp) (concmapSP pre)++concatMapF = absF . concatMapSP+mapF = absF . mapSP+mapstateF f x = absF (mapstateSP f x)++idF = mapF id++toBothF = concatMapF (\x -> [Left x, Right x])++throughF w = serCompF (idRightF w) toBothF++--and throughF w = idRightF w:==:toBothF+bypassF :: (F a a) -> F a a+bypassF f = postMapHigh stripEither (throughF f)++stubF :: F a b -> F c d+stubF f = serCompF (serCompF nullF f) nullF+
+ hsrc/combinators/StateMonads.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE CPP #-}+module StateMonads where+import Control.Applicative+import Control.Monad(ap)+import Fudget(K) --,KEvent+import FudgetIO+import StreamProcIO+import EitherUtils(Cont(..))+import NullF(getK)++--------------------------------------------------------------------------------++-- | The continuation monad+#ifdef __HBC__+newtype Mk k r = Mk (Cont k r)+unMk (Mk mk) = mk+#else+newtype Mk k r = Mk {unMk::Cont k r}+#endif+-- | Continuation monad with unit result+type Mkc k = Mk k ()++instance Functor (Mk k) where+ fmap f (Mk m) = Mk (\k -> m (k.f))++instance Applicative (Mk k) where+ pure = return+ (<*>) = ap+ +instance Monad (Mk k) where+ return r = Mk ($ r)+ Mk m1 >>= xm2 = Mk (m1 . flip (unMk . xm2))++--------------------------------------------------------------------------------++-- | Continuation monad with state (just an instance of the continuation monad)+type Ms k s r = Mk (s -> k) r+type Msc k s = Ms k s ()++loadMs :: Ms k s s+storeMs :: s -> Msc k s+modMs :: (s -> s) -> Msc k s+fieldMs :: (s -> f) -> Ms k s f++loadMs = Mk (\ k s -> k s s)+storeMs s = Mk (\ k _ -> k () s)+modMs f = Mk (\ k s -> k () (f s))+fieldMs r = Mk (\ k s -> k (r s) s)++nopMs :: Msc k s+nopMs = return ()++--------------------------------------------------------------------------------++toMkc :: (k -> k) -> Mkc k+toMkc k = Mk (\f -> k (f ()))++toMs :: Cont k r -> Ms k s r+toMs f = Mk (bmk f)+bmk f = (f .) . flip++toMsc :: (k -> k) -> Msc k r+toMsc k = Mk (\f -> k . f ())++--------------------------------------------------------------------------------+-- | Fudget Kernel Monad with State (just an instance...)+type Ks i o s ans = Ms (K i o) s ans+--type Ksc i o s = Ks i o s ()++{-+putsKs :: [KCommand a] -> Ksc b a c+putKs :: KCommand a -> Ksc b a c+getKs :: Ks a b c (KEvent a)+nullKs :: Ks i o s ()+loadKs :: Ks i o s s+storeKs :: s -> Ks i o s ()+-}+putHighsMs c = toMsc (puts c)+putHighMs c = toMsc (put c)+putLowsMs c = toMsc (putLows c)+putLowMs c = toMsc (putLow c)+getKs = toMs getK+++-- Some synonyms, kept mostly for backwards compatibility+nullKs = nopMs+storeKs = storeMs+loadKs = loadMs+unitKs x = return x+bindKs m1 xm2 = m1>>=xm2+thenKs m1 m2 = m1>>m2+mapKs f = fmap f++-- Running a kernel monad++--stateMonadK :: s -> Ks i o s ans -> (ans -> K i o) -> K i o+stateMonadK s0 (Mk ks) k = ks (\ans state->k ans) s0++--stateK :: a -> (Ksc b c a) -> (K b c) -> K b c+stateK s (Mk ksc) k = ksc (const (const k)) s
+ hsrc/combinators/TreeF.hs view
@@ -0,0 +1,19 @@+module TreeF where+import BranchF+import CompFfun(prepostMapHigh')+import Utils(pair)+import Fudget++data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving (Eq, Ord)++treeF :: Tree (a, F b c) -> F (Path, b) (a, c)+treeF = F{-ff-} . treeF'++treeF' :: Tree (a, F b c) -> FSP (Path, b) (a, c)+treeF' (Leaf (t, f)) = leafF t f+treeF' (Branch l r) = branchFSP (treeF' l) (treeF' r)++leafF t (F sp) =+ let pre ([], x) = x+ pre _ = error "unknown path in treeF"+ in prepostMapHigh' pre (pair t) sp
+ hsrc/containers/BubbleF.hs view
@@ -0,0 +1,86 @@+module BubbleF(bubbleF, bubblePopupF, bubbleRootPopupF) where+--import Alignment(Alignment(..))+import Command+import XDraw+import CompOps((>=^<), (>^=<))+import Dlayout(groupF)+import Event+import Fudget(F)+--import FudgetIO+import FRequest+import NullF()+import Gc+import Geometry(origin,pP,Point(..),psub,padd)+import LayoutRequest(LayoutResponse(..))+import Message(Message(..))+import PopupGroupF+--import Popupmsg+import Spacer(sepF)+import ShapeK+import MapstateK+import EitherUtils(stripEither)+import Xtypes++default(Int) -- mostly for Hugs++bubblePopupF f =+ popupGroupF (bubbleOffset, wattrs, bubbleShapeK) (bubbleF f)++bubbleRootPopupF f =+ rootPopupF (bubbleOffset, rwattrs, bubbleShapeK) (bubbleF f)++bubbleF :: (F a b) -> F a b+bubbleF f =+ let startcmds = [XCmd $ ChangeWindowAttributes wattrs]+ in stripEither >^=<+ groupF startcmds bubbleShapeK (sepF sep f) >=^< Right++wattrs = [CWEventMask [ExposureMask]]+rwattrs = CWOverrideRedirect True:wattrs++bubbleShapeK =+ wCreateGC rootGC [GCLineWidth 2] $+ shapeK fillBubble . bubbleK++bubbleK gc =+ let bubbleT state@size msg =+ case msg of+ Low (LEvt (LayoutSize size')) -> (size', [])+ Low (XEvt (Expose _ 0)) ->+ (state, if size == origin+ then []+ else [Low $ wDraw gc (drawBubble (size-1))])+ _ -> (state, [])+ in mapstateK bubbleT origin++drawBubble size = DrawLines CoordModeOrigin (bubblePoints size)+fillBubble size = [FillPolygon Convex CoordModeOrigin (bubblePoints size)]++c = 4+ah = 12+ax = 12+aw = 6+atx = 6+bubbleBorder = ah + c+sep = pP (2 * c) (2 * c + bubbleBorder)+bubbleOffset (Point _ h) = Point atx (h - c)++bubblePoints size =+ let Point w h = psub size (pP 0 (2 * bubbleBorder))+ in map (padd (pP 0 bubbleBorder))+ [pP c 0,+ pP (w - c) 0,+ pP w c,+ pP w (h - c),+ pP (w - c) h,+ pP (ax + aw) h,+ pP atx (h + ah),+ pP ax h,+ pP c h,+ pP 0 (h - c),+ pP 0 c,+ pP c 0]++--drawlines (p1 : p2 : ps) = DrawLine (Line p1 p2) : drawlines (p2 : ps)+--drawlines _ = []+
+ hsrc/containers/Containers.hs view
@@ -0,0 +1,21 @@+module Containers ( -- * Containers+ module BubbleF,module Dlayout,module DragF,module PopupF,module PopupGroupF,module PosPopupShellF,module ScrollF,module SelectionF,module DShellF,module Shells,module RootWindowF) where+import BubbleF+import Dlayout+import DragF+import PopupF+import PopupGroupF+import PosPopupShellF+import ScrollF+import SelectionF+import DShellF+import Shells+import RootWindowF++{-+import Fudget+import Geometry(Rect,Size(..),Point)+import Popupmsg(PopupMsg)+import Xtypes(Button,ModState(..),Modifiers,WindowAttributes,KeySym(..),ColorName(..),FontName(..))+import FDefaults+-}
+ hsrc/containers/DShellF.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE CPP #-}+module DShellF(ShellF,shellF, shellF', shellKF, shellKF',+ setDeleteWindowAction,+ getDeleteWindowActionMaybe', -- for use in titleShellF+ DeleteWindowAction(..),setDeleteQuit,+ HasClickToType(..),setInitPos,setFocusMgr,+ HasVisible(..)) where++import FDefaults+import Dlayout(sF)+import AutoLayout(autoLayoutF',nowait)+import QuitK+import Fudget+import EitherUtils+import CompOps+import Geometry(Point(..))+import Command+import Xcommand+import Xtypes+import Defaults(defaultSep,defaultPosition)+import CmdLineEnv(argFlag)+import FocusMgr(focusMgr)+--import Placer+--import Spacers+import Spacer(marginF)+--import LayoutRequest+import Sizing(Sizing(..))+import NullF+import ParK+--import Maptrace(ctrace) -- debugging+#include "defaults.h"++newtype ShellF = Pars [Pars]+data Pars+ = WinAttr [WindowAttributes]+ | DeleteWindowAction (Maybe DeleteWindowAction)+ | ClickToType Bool+ | FocusMgr Bool -- mainly for internal use+ | Visible Bool+ | Margin Int+ | Sizing Sizing+ | InitPos (Maybe Point)++data DeleteWindowAction = DeleteQuit | DeleteUnmap deriving (Eq,Show)++parameter(InitPos)+parameter(FocusMgr)++parameter_instance(WinAttr,ShellF)++parameter(DeleteWindowAction)+getDeleteWindowActionMaybe' pm =+ getDeleteWindowActionMaybe (pm (Pars []))++-- Backwards compatibility:+setDeleteQuit b = setDeleteWindowAction (if b then Just DeleteQuit else Nothing)++parameter_class(ClickToType,Bool)+parameter_instance(ClickToType,ShellF)+++parameter_class(Visible,Bool)+parameter_instance(Visible,ShellF)++parameter_instance(Margin,ShellF)+parameter_instance(Sizing,ShellF)++shellF = shellF' standard+shellF' pmod s f = stripEither >^=< shellKF' pmod k f >=^< Right where+ k = xcommandK (StoreName s) nullK++shellKF = shellKF' standard++shellKF' :: (Customiser ShellF)->K a b -> F c d -> F (Either a c) (Either b d)+shellKF' pmod k f = genShellF siz clicktt focusmgr vis pos sep [] kernel f+ where+ ps = pmod (Pars [WinAttr [],DeleteWindowAction (Just DeleteQuit),+ ClickToType ctt, FocusMgr defFocusMgr,+ InitPos defaultPosition, -- hmm+ Visible True,Margin defaultSep,Sizing Dynamic])+ -- !! Change default Sizing?+ d_action = getDeleteWindowAction ps+ clicktt = getClickToType ps+ focusmgr = getFocusMgr ps+ sep = getMargin ps+ vis = getVisible ps+ wa = getWinAttr ps+ siz = getSizing ps+ pos = getInitPos ps+ kernel = xcommandK (ChangeWindowAttributes wa) $+ maybe (wmDeleteWindowK (const k)) -- see (*) in QuitK.hs+ (\ a -> quitK (action a) `parK` k)+ d_action++ action DeleteQuit = exitK+ action DeleteUnmap = unmapWindowK++genShellF sizing ctt focusmgr map pos sep cmds k f = + sF (not map) pos cmds k (filter (sepf f)) where+ filter = if focusmgr+ then focusMgr sizing ctt+ else autoLayoutF' nowait sizing -- usually sits inside a groupF in focusMgr+ sepf = if sep == 0 then id else marginF sep++ctt = argFlag "ctt" True+defFocusMgr = argFlag "focusmgr" True
+ hsrc/containers/Dlayout.hs view
@@ -0,0 +1,142 @@+module Dlayout(invisibleGroupF,+ simpleGroupF, unmappedGroupF, groupF, groupF',+ sgroupF, swindowF,+ windowF,sF) where+--import Alignment(Alignment(..))+import Command+import CompFfun(prepostMapHigh)+--import CompOps((>=^^<), (>^=<),(>..=<))+import Defaults(bgColor)+import CmdLineEnv(resourceName)+import Event+import Fudget+import FRequest+import Geometry(Point(..), Rect(..), origin, pmax)+import GreyBgF(changeBg)+import LayoutRequest+import LoopLow+--import Message(Message(..))+import NullF+import Spops+--import SpEither(mapFilterSP)+import AutoLayout(autoLayoutF',nowait)+import Sizing(Sizing(..))+import EitherUtils(stripEither)+--import Utils(oo)+import WindowF+import Xtypes+--import Placer(placerF,spacerF)+--import Spacers+--import AutoPlacer(autoP)+import ParSP+--import CompSP+import Path(turn,here)+import Direction(Direction(..))++addEventMask addmask =+ let addem [] = []+ addem (CWEventMask mask : wattrs) =+ CWEventMask (addmask ++ mask) : wattrs+ addem (wattr : wattrs) = wattr : addem wattrs+ in addem++shell :: Bool -> (F a b) -> F a b+shell nomap f =+ let eventmask = [StructureNotifyMask,KeyPressMask,KeyReleaseMask,FocusChangeMask]++ prep ss@(osize,sizeq, Just ltag) (Low (tag, XEvt (ConfigureNotify (Rect _ nsize) _)))+ | tag == kernelTag = case sizeq of + (size:sizeq') | size == nsize -> ((nsize,sizeq',Just ltag),[])+ _ -> if nsize == osize then (ss,[]) else+ ((nsize,sizeq,Just ltag),[(ltag,LEvt $ LayoutPlace (Rect origin nsize))])+ prep s (Low (t,e@(XEvt (FocusIn {})))) | t == kernelTag = (s,[(focusMgrTag, e)])+ prep s (Low (t,e@(XEvt (FocusOut {})))) | t == kernelTag = (s,[(focusMgrTag, e)])+ prep s (Low (t,e@(XEvt (KeyEvent {})))) | t == kernelTag = (s,[(focusMgrTag, e)])+ prep s (Low msg) = (s, [msg])+ prep (osize,sizeq, _) (High (tag, nsize)) = + ((osize,sizeq++ (if null sizeq || last sizeq /= nsize then [nsize] else []), Just tag),+ [(tag, LEvt $ LayoutPlace (Rect origin nsize))])++ focusMgrTag = turn R $ turn L here -- hardwired assumption+ minSize = Point 1 1++ post nomap' (tag, LCmd lreq) = case lreq of+ LayoutRequest (Layout {minsize=size}) ->+ (True,+ High (tag, size) :+ toKernel ([XCmd $ resizeWindow (pmax minSize size)] +++ (if nomap' then [] else [XCmd $ MapRaised])))+ -- we should actually wait with MapRaised until f reports OK somehow...+ _ -> (nomap',[]) {- filter all other layout msgs -}+ post nomap' (tag, XCmd (ChangeWindowAttributes wattrs)) | tag == kernelTag =+ (nomap',+ [Low (tag, XCmd $ ChangeWindowAttributes (addEventMask eventmask wattrs))])+ post nomap' (_,XCmd MeButtonMachine) = (nomap', [])+ post nomap' cmd@(tag, XCmd (ChangeWindowAttributes wattrs)) = (nomap',[Low cmd])+ post nomap' cmd = (nomap', [Low cmd])+ startcmds = toKernel [XCmd $ ChangeWindowAttributes [CWEventMask []],+ XCmd $ SetWMHints True]+ in loopLow (mapstateSP' post nomap)+ (mapstateSP prep ((Point 10 10),[], Nothing)) {- 10 10 from windowKF... -}+ (myAppendStartF startcmds f)++mapstateSP' f s0 =+ getSP (\x ->+ case f s0 x of+ (s, y) -> putsSP y (mapstateSP' f s))+{-+-- causes a space leak with nhc13 and ghc-7.6+mapstateSP' f s0 =+ getSP (\x ->+ let (s, y) = f s0 x+ in putsSP y (mapstateSP' f s))+-}+-- myAppendStart will let f speak all its initial msgs, not just the first one.+myAppendStartF cmds (F f) = {-F-}ff $ parSP f (putsSP cmds nullSP)++windowF :: [FRequest] -> (K a b) -> F a b+windowF cmds = swindowF cmds Nothing++swindowF cmd oplace k = + prepostMapHigh Left stripEither (group0F sizing False cmd oplace k Nothing)+ where sizing = if oplace==Nothing then Static else Dynamic++sF nomap pos lc k f =+ let r = Nothing -- temporary+ p =+ case r of+ Just (Rect p _) -> Just p+ Nothing -> pos+ lc' =+ case p of+ Just p' -> XCmd (SetNormalHints p') : XCmd (moveWindow p') : lc+ Nothing -> lc+ in shell nomap+ (windowKF (XReq . flip CreateRootWindow resourceName) True nomap lc' r (bgK k) f)++group0F sizing nomap cmds r k mf =+ case mf of+ Nothing -> w nullF+ Just f -> w $ autoLayoutF' nowait sizing f+ where w = windowKF (XReq . CreateMyWindow) False nomap cmds r k ++sgroupF sizing cmds r k = group0F sizing False cmds r k . Just+groupF' sizing cmds = sgroupF sizing cmds Nothing+groupF = groupF' Dynamic++unmappedGroupF sizing cmds k = group0F sizing True cmds Nothing k . Just+++simple sf sizing startcmds k w =+ prepostMapHigh Right stripEither (sf sizing startcmds k w)++bgK = changeBg bgColor++--sGF :: (K a b) -> [WindowAttributes] -> (F a b) -> F a b+sGF sizing k wattrs =+ simple groupF' sizing [XCmd $ ChangeWindowAttributes wattrs] k++simpleGroupF = sGF Dynamic (bgK nullK)+invisibleGroupF sizing cmds = + sGF sizing (bgK (putsK (map Low cmds) nullK))+
+ hsrc/containers/DragF.hs view
@@ -0,0 +1,250 @@+module DragF(containerGroupF,hPotF,hPotF',vPotF,vPotF',PotRequest(..),PotState(..)) where+import Command+import CompOps((>=^<), (>^=<))+import CompFfun(prepostMapHigh)+import Cursor+import Dlayout(groupF,groupF')+import Sizing(Sizing(..))+import Event+--import Color+import Fudget+--import FudgetIO+import FRequest+import NullF+import Geometry+import GreyBgF+import Border3dF(border3dF)+import LayoutRequest(LayoutResponse(..))+import LayoutF(holeF')+import Spacers(hvMarginS)+import DynSpacerF(dynSpacerF)+import Spacer(noStretchF)+import Alignment+import Loops(loopCompThroughRightF,loopLeftF)+--import Message(Message(..))+import EitherUtils(stripEither)+import Data.Maybe(fromMaybe)+import CmdLineEnv(argReadKey)+import Xtypes+--import Maptrace(ctrace)++data PotRequest = ResizePot Int Int -- frame size, total size+ | MovePot Int -- new position+ | PotMkVisible Int Int (Maybe Alignment) -- pos, length, alignm+ | PotInput (ModState, KeySym) -- remote control++type PotState = (Int,Int,Int) -- position, frame size, total size++knobS knob@(Rect kp ks) box@(Rect bp bs) =+ --ctrace "knobS" (knob,box) $+ hvMarginS (kp+margin) (bs+margin-kp-ks)++knobK box knob pabs =+ let cont knob' pabs' = knobK box knob' pabs'+ newbox box' knob' = knobK box' knob' pabs+ same = cont knob pabs+ output knob = putK (High (Right knob))+ repos knob box = putK (High (Left (knobS knob box)))+ in getK $ \msg ->+ case msg of+ Low (XEvt (MotionNotify {rootPos=pabs',state=mods})) ->+ let knob' = moverect knob (psub pabs' pabs)+ knob'' = confine box knob'+ pabs'' = padd pabs' (rsub knob'' knob')+ in repos knob'' box $+ (if Shift `elem` mods then id else output knob'') $+ cont knob'' pabs''+ Low (XEvt (ButtonEvent {rootPos=pabs',type'=Pressed})) -> cont knob pabs'+ Low (XEvt (ButtonEvent {type'=Released})) -> output knob $ same+ High (newknob, box') ->+ let knob' = confine box' newknob+ msgs = (if knob'/=knob || box'/=box+ then repos knob' box'+ else id) .+ (if knob'/=knob -- was: knob/=newknob+ then output knob'+ else id)+ in msgs $+ newbox box' knob'+ _ -> same++-- New version, using new more general containterGroupF+-- containterGroupF should be replaced.+containerGroupF knob box cursorshape buttons modifiers fudget =+ loopLeftF $+ prepostMapHigh pre post $+ dynSpacerF $+ groupF initcmds+ (setFontCursor cursorshape (knobK box knob origin))+ fudget+ where attrs = [CWEventMask []]+ initcmds = map XCmd + [ChangeWindowAttributes attrs,+ GrabButton False buttons modifiers+ [PointerMotionMask, ButtonReleaseMask]]+ --MapRaised]+ pre = id+ post = either (either Left (Right. Left)) (Right. Right)++knobF cursor box knob =+ (stripEither >^=< containerGroupF knob box cursor (Button 1) [] vF ) >=^<+ Left+ where vF = raisedF (holeF' s)+ s = rectsize knob++staticBorder3dF down fud = border3dF down 2 fud >=^< Right+raisedF = staticBorder3dF False+loweredF = staticBorder3dF True++--topleft = diag 2+--margin = diag 6+topleft = diag 0+margin = diag (argReadKey "potmargin" 0)++absknobpos size (pos, frame, tot) =+ if tot == 0+ then (0, max 1 size)+ else ((pos * size + tot `div` 2) `quot` tot, max 1 (frame * size `quot` tot))++newkpos :: PotState -> (Int,Int) -> PotState+newkpos (_, frame, tot) (pos, size) = (pos * tot `quot` size, frame, tot)++knobup d (pos, frame, tot) = (0 `max` (pos - d), frame, tot)+knobdown d (pos, frame, tot) = ((tot - frame) `min` (pos + d), frame, tot)+pageup knob@(_, frame, _) = knobup frame knob+pagedown knob@(_, frame, _) = knobdown frame knob++stepup len knob = knobup (stepsize len knob) knob+stepdown len knob = knobdown (stepsize len knob) knob+stepsize size (_,_,tot) = (tot+size-1) `quot` size++knobhome (_, frame, tot) = (0, frame, tot)+knobend (_, frame, tot) = (tot - frame, frame, tot)++resizePot (pos,_,_) frame tot = (pos,frame,tot) -- !! should adjust pos if necessary+movePot (_,frame,tot) pos = (pos,frame,tot) -- !! should keep pos within boundaries++--and adjkpos (pos,frame,tot) frame' tot' = (min (tot'-frame') (pos*tot'/tot),frame',tot')++keyAction mods s len =+ case s of+ s | s == "space" || s == "Next" -> Just (shift knobend pagedown)+ s | s `elem` pageupKeys -> Just (shift knobhome pageup)+ s | s == "Home" -> Just knobhome+ s | s == "End" -> Just knobend+ s | s == "Down" || s == "Right" -> Just (stepdown len)+ s | s == "Up" || s == "Left" -> Just (stepup len)+ _ -> Nothing+ where+ shift = if Shift `elem` mods then const else const id+ pageupKeys = ["Delete","BackSpace","Prior"]++mkVisible (pos,frame,tot) first last optAlign =+ case optAlign of+ Just a -> Just (max 0 (min (tot-frame) pos'),frame,tot)+ where pos' = first+truncate (a*fromIntegral (last-first-frame))+ _ ->+ if first<pos || last-first>frame+ then Just (first,frame,tot)+ else if last>pos+frame+ then Just (last-frame,frame,tot)+ else Nothing++potF hori par ort vect shape grav acceptFocus optsize =+ loopCompThroughRightF potGroupF+ where+ potGroupF =+ noStretchF (not hori) hori $+ loweredF $ + groupF' Static startcmds + (darkGreyBgK potK0)+ (knobF shape box0 (knob length0 kpos0))+ where wattrs = [CWEventMask eventmask]+ alwayseventmask = [ButtonPressMask,Button2MotionMask]+ focuseventmask = [EnterWindowMask, LeaveWindowMask, KeyPressMask]+ eventmask = alwayseventmask ++ + if acceptFocus then focuseventmask else []+ startcmds = [--XCmd $ LayoutMsg (Layout wsize (not hori) hori),+ XCmd $ ChangeWindowAttributes wattrs]+ wsize = fromMaybe (vect 50 11) optsize+ boxsize0 = psub wsize margin+ length0 = par boxsize0+ boxwidth = ort boxsize0+ knob length' kpos' =+ let (pos, size) = absknobpos length' kpos'+ in Rect (padd topleft (vect pos 0)) (vect size boxwidth)+ box0 = Rect topleft boxsize0+ potK0 = potK1 --allocNamedColorPixel defaultColormap "white" potK1+ potK1 = potK kpos0 length0 where+ potK kpos len =+ let cont kpos' = potK kpos' len+ newlen kpos' len' = potK kpos' len'+ same = cont kpos+ report kpos' = --ctrace "report" kpos' $+ High (Right kpos')+ changeknob len' kpos' =+ High (Left (knob len' kpos',+ Rect topleft (vect len' boxwidth)))+ moveknob kpos' = --ctrace "moveknob" kpos' $+ putsK [changeknob len kpos'{-,report kpos'-}] $+ -- Rely on the knob to report the new position,+ -- after it has been confined to the box. This+ -- is a fix for button2Action that result in+ -- positions outside the box...+ same -- cont kpos'+ keyInput mods key = maybe same act (keyAction mods key len)+ where act action = moveknob (action kpos)++ button2Action p = newkpos kpos (par p, len)++ buttonAction (Button 2) mods p = button2Action p+ buttonAction b mods p =+ case (par p < par (rectpos (knob len kpos)),+ Shift `elem` mods || Control `elem` mods) of+ (True, False) -> pageup kpos+ (True, True ) -> knobhome kpos+ (False,False) -> pagedown kpos+ (False,True ) -> knobend kpos++ in getK $ \msg ->+ case msg of+ Low (XEvt (ButtonEvent {button=b,pos=p,state=mods,type'=Pressed})) ->+ moveknob (buttonAction b mods p)+ Low (XEvt (MotionNotify {pos=p,state=mods})) | Button2 `elem` mods ->+ moveknob (button2Action p)+ Low (LEvt (LayoutSize size')) ->+ let len' = par size' - par margin+ in if len'/=len+ then putsK [changeknob len' kpos] (newlen kpos len')+ else same+ Low (XEvt (KeyEvent _ _ _ mods Pressed _ key _)) ->+ keyInput mods key+ Low (XEvt (FocusIn {detail=d})) | d /= NotifyInferior -> + lightGreyBgK same+ Low (XEvt (FocusOut {detail=d})) | d /= NotifyInferior -> + darkGreyBgK same+ High (Right (PotInput (mods,key))) -> keyInput mods key+ High (Right (ResizePot frame tot)) ->+ let kpos' = resizePot kpos frame tot+ in putK (changeknob len kpos') (cont kpos')+ High (Right (MovePot pos)) ->+ let kpos' = movePot kpos pos+ in putK (changeknob len kpos') (cont kpos')+ High (Right (PotMkVisible pos size optAlign)) ->+ case mkVisible kpos pos (pos+size) optAlign of+ Just kpos' -> moveknob kpos'+ Nothing -> same+ High (Left newknob) ->+ --ctrace "newknob" newknob $ + let kpos' = newkpos kpos (par (rsub newknob box0), len)+ in if kpos'==kpos -- False+ then same+ else putK (report kpos') (cont kpos')+ _ -> same+ kpos0 = (0,1,1)++vPotF' = potF False ycoord xcoord (\x -> \y -> Point y x) 116 NorthEastGravity+hPotF' = potF True xcoord ycoord Point 108 SouthWestGravity++vPotF = vPotF' True Nothing+hPotF = hPotF' True Nothing
+ hsrc/containers/FreeGroupF.hs view
@@ -0,0 +1,56 @@+module FreeGroupF(freeGroupF) where+--import Fudget+import EitherUtils+import Path(here)+import LayoutRequest+import Geometry+--import Command+--import Event+--import Xtypes++import Dlayout(groupF)+import UserLayoutF(userLayoutF)+import Spops+--import SpEither(mapFilterSP)+import NullF(nullK)+import SerCompF(absF)+import LoopCompF(loopCompF)+import CompOps+import Defaults(bgColor)+import GreyBgF(changeBg)++freeGroupF f =+ loopCompF (absF placeSP0>+<innerF)+ where+ innerF = userLayoutF $+ stripEither >^=< groupF [] (bgK nullK) f >=^< Right++ placeSP0 = placeSP False here (rR 0 0 0 0) {- dummy initial path & place -}++ placeSP placed path place =+ let same = placeSP placed path place+ in + getSP $ \ msg ->+ case msg of+ Left (path',layoutmsg) ->+ case layoutmsg of+ LayoutRequest req ->+ let place' = sizerect place (minsize req)+ in putSP (Right layoutmsg) $ placeSP False path' place'+ LayoutMakeVisible _ _ -> putSP (Right layoutmsg) same+ LayoutScrollStep _ -> putSP (Right layoutmsg) same+ _ -> same -- ignore other msgs for now+ Right (Right pos) ->+ let place' = posrect place pos+ in putSP (Left (path,place')) $+ placeSP True path place'+ Right (Left newtotsize) ->+ let place' = sizerect place newtotsize+ in ifSP (not placed || place'/=place)+ (putSP (Left (path,place'))) $+ -- ^^ dangerous optimization?+ placeSP True path place'++ifSP b th = if b then th else id++bgK = changeBg bgColor
+ hsrc/containers/PopupF.hs view
@@ -0,0 +1,53 @@+module PopupF(popupShellF,popupShellF') where+import Command+import DShellF+import FDefaults+import Fudget+import FRequest+import Xcommand+import Geometry(Point(..), pP)+--import LayoutRequest(LayoutRequest)+import Loops(loopCompThroughRightF)+--import Message(Message(..))+--import Spops+import MapstateK+import Xtypes+--import NullF(putsK)+import CompSP+import Path(here)++popupShellF = popupShellF' standard++popupShellF' :: Customiser ShellF -> String -> Maybe Point -> F a b -> F a (a,b)+popupShellF' pm title optpos (F f) =+ let pos = case optpos of+ Just pos -> pos+ Nothing -> pP 300 300+ params = pm . setVisible False . setDeleteQuit False+ in loopCompThroughRightF (shellKF' params (popupK title pos) + (F{-ff-} $ prepostMapSP pre post (idRightSP f)))++pre (Low m) = Left (Low m)+pre (High (Left a)) = Left (High a)+pre (High (Right a)) = Right a+post (Right a) = Low (here,a)+post (Left (Low m)) = Low m+post (Left (High a)) = High a++popupK title pos =+ let kf s@(mapped,trig) msg =+ case msg of+ High (Right trig') -> ((True,trig'), + [High (Left (Left trig')),lowfromf (GrabEvents True)] +++ if not mapped then [Low $ XCmd MapRaised] else [])+ High (Left x) -> ((False,trig),+ (if mapped then unmapcmds else []) ++ + [lowfromf UngrabEvents,High (Right (trig, x))])+ Low _ -> (s, [])+ lowfromf = High . Left . Right . XCmd+ unmapcmds = [Low $ XCmd UnmapWindow,Low $ XCmd Flush]+ startcmds =+ [StoreName title, SetNormalHints pos, moveWindow pos,+ ChangeWindowAttributes [CWSaveUnder True]]+ in xcommandsK startcmds $+ mapstateK kf (False,error "premature output from fudget inside popupShellF")
+ hsrc/containers/PopupGroupF.hs view
@@ -0,0 +1,66 @@+module PopupGroupF(popupGroupF,rootPopupF) where+import Command+import CompOps((>=^^<), (>^^=<))+--import Direction+import Dlayout(unmappedGroupF)+import Sizing(Sizing(..))+import Shells(unmappedShellF)+--import Event+import Fudget+import FRequest+import Geometry(psub,pP)+import LayoutRequest+import LoopLow+--import Message(Message(..))+import ParK+--import Path(Path(..))+import Popupmsg+--import Spops+import MapstateK+import SpEither(filterRightSP)+--import SerCompF(concatMapF)+import Spops+--import Xtypes++popupGroupF = popupF (unmappedGroupF Dynamic)+rootPopupF = popupF unmappedShellF++popupF grF (offset, wattrs, k) f =+ let post (tag, cmd) =+ case cmd of+ LCmd req ->+ case req of+-- Layout size fh' fv -> [High (tag, LEvt $ LayoutPlace (Rect origin size))]+ LayoutRequest (Layout {minsize=size}) ->+ [High (tag, LEvt $ LayoutSize size)]+ -- treated specially in windowKF.+ _ -> []+ cmd' -> [Low (tag, cmd')]+ pre ev =+ case ev of+ High ev' -> [ev']+ Low (_, LEvt (LayoutPlace _)) -> [] -- shouldn't happen?+ Low tev -> [tev]+ distr (Popup p x) = [Right x, Left (Left (Just p))]+ distr Popdown = [Left (Left Nothing)]+ startcmds = [XCmd $ ChangeWindowAttributes wattrs]+ in (filterRightSP >^^=<+ loopLow (concmapSP post)+ (concmapSP pre)+ (grF startcmds (compK (placeK offset) k) f)) >=^^<+ concatMapSP distr++placeK offset = mapstateK sizeT (False,pP 0 0)+ where+ sizeT s@(mapped,size) msg =+ case msg of+ High (Just p) ->+ ((True,size),+ [Low $ XCmd (moveWindow (psub p (offset size)))] +++ if not mapped then [Low $ XCmd MapRaised] else [])+ High Nothing ->+ ((False,size),if mapped then [Low $ XCmd UnmapWindow] else [])+ Low (LEvt (LayoutSize size')) ->+ ((mapped,size'), [])+ _ -> (s, [])+
+ hsrc/containers/PosPopupShellF.hs view
@@ -0,0 +1,45 @@+module PosPopupShellF(posPopupShellF) where+import Command+import Shells(unmappedShellF)+--import Event(Event(..))+import Fudget+import FRequest+import Geometry(origin, pP, psub)+--import LayoutRequest(LayoutRequest)+import Loops(loopCompThroughRightF)+--import Message(Message(..))+import NullF+--import Path(Path(..))+import QueryPointer+--import SP+--import Xtypes++posPopupShellF title wattrs f =+ loopCompThroughRightF (unmappedShellF startcmds popupK f)+ where+ startcmds =+ [XCmd $ StoreName title,+ XCmd $ SetNormalHints origin,+ XCmd $ ChangeWindowAttributes wattrs]++popupK = kf (error "premature output from fudget inside posPopupShellF")+ where+ pickPos p cont =+ case p of+ Just pos -> cont pos+ Nothing -> queryPointerK (\(_, r, _, _) -> cont (psub r (pP 5 5)))++ kf s@(mapped,trig) =+ getK $ \msg ->+ case msg of+ High (Right (trig', optpos)) ->+ pickPos optpos $ \pos ->+ putsK ([Low $ XCmd $ moveWindow pos,+ High (Left trig')] +++ if not mapped then [Low $ XCmd MapRaised] else []) $+ kf (True,trig')+ High (Left y) ->+ putsK ((if mapped then [Low $ XCmd UnmapWindow] else []) +++ [High (Right (trig, y))]) $+ kf (False,trig)+ _ -> kf s
+ hsrc/containers/RootWindowF.hs view
@@ -0,0 +1,50 @@+module RootWindowF where+import Command+--import Event+--import Font(FontStruct)+--import Fudget+--import Message(Message(..))+import Geometry(Rect(..),origin,pP)+--import Path+import WindowF(kernelF)+--import NullF(putK)+--import Xrequest(xrequestF)+import Xcommand(xcommandK)+import QueryTree+import UserLayoutF(userLayoutF)+import CompOps+import SerCompF(absF)+import Loops(loopThroughRightF)+import Spops(mapSP)+import AutoLayout(autoLayoutF)+--import CmdLineEnv(argReadKey)+--import NullF(nullF)+import WindowF(kernelTag)++{-+rootWindowF k =+ defaultRootWindowF $ \ root ->+ kernelF (putK (Low (ReparentToMe kernelTag root)) k) >*< nullF+-}+ +rootWindowF k =+ defaultRootWindowF $ \ root ->+ kernelF (xcommandK (SelectWindow root) k)+ +rootGroupF k f =+ k' >+< f'+ where+ k' = kernelF (+ defaultRootWindowK $ \ root ->+ xcommandK (ReparentToMe kernelTag root) k)+ f' = loopThroughRightF (absF ctrlSP) (userLayoutF (autoLayoutF f))+ ctrlSP = mapSP ctrl+ ctrl msg =+ case msg of+ Left (Left (path,req)) -> Left (Left (path,screenrect))+ Left (Right x) -> Right x+ Right x -> Left (Right x)+ + screenrect = Rect origin (pP 1152 900)+ -- !!! no Read instance...+ --screenrect = Rect origin (argReadKey "screensize" (pP 1152 900)) -- !!!
+ hsrc/containers/ScrollF.hs view
@@ -0,0 +1,181 @@+module ScrollF(scrollShellF,+ scrollF,oldScrollF,+ vScrollF,oldVscrollF,+ hScrollF,oldHscrollF,+ grabScrollKeys) where+import Fudget+import EitherUtils+import CmdLineEnv(argFlag)+import Utils(remove)+import LayoutRequest+import Geometry+import Command+import FRequest+import Event+import Xtypes++import FreeGroupF+import Dlayout(groupF)+import DShellF(shellF)+import Spops+import NullF(nullF)+import Cont(waitForSP)+import SpEither(mapFilterSP)+import DragF(hPotF',vPotF',PotRequest(..))+import Placer(tableF,hBoxF,vBoxF)+import SerCompF(absF)+import Loops(loopThroughRightF)+import CompOps+--import Maptrace(ctrace)++scrollShellF name initlimits = shellF name . oldScrollF True initlimits++grabScrollKeys = argFlag "grabscrollkeys" False+ -- True is not good if there are two or more scrollFs in the same shell window.++-- Std versions with arbirarily chosen limits...+scrollF = oldScrollF grabScrollKeys (pP 50 30,pP 550 700)+vScrollF = oldVscrollF grabScrollKeys (pP 50 30,pP 550 700)+hScrollF = oldHscrollF grabScrollKeys (pP 50 10,pP 550 700)++scroll foc = (const,plainAdjLayout,tableF 2,vPotF' foc Nothing >+< hPotF' foc Nothing)+vscroll foc = (const,wAdjLayout,hBoxF,vPotF' foc Nothing >+< nullF)+hscroll foc = (const,hAdjLayout,vBoxF,nullF>+<hPotF' foc Nothing)++oldScrollF grabKeys = gScrollF (scroll (not grabKeys)) grabKeys+oldVscrollF grabKeys = gScrollF (vscroll (not grabKeys)) grabKeys+oldHscrollF grabKeys = gScrollF (hscroll (not grabKeys)) grabKeys++gScrollF (outCoupling,inCoupling,placer,scrollbarsF) grabKeys initlimits fud =+ loopThroughRightF (placer mainF) (absF (initSP ctrlSP))+ where+ mainF =+ post>^=<+ (groupF start visibleK (freeGroupF fud)>+<scrollbarsF)+ >=^<pre+ where+ post = swapRight.mapEither assocLeft id -- (KV+(T+a))+S -> ((KV+T)+S)+a+ pre = mapEither assocRight id.swapRight -- converse++ start = map XCmd $+ transinit+++ [ChangeWindowAttributes [CWBackPixmap parentRelative],+ ConfigureWindow [CWBorderWidth 1]]++ transinit =+ if grabKeys+ then [TranslateEvent tobutton [KeyPressMask]]+ else []++ --tobutton k@(KeyEvent t p1 p2 s Pressed _ ks _) | (s, ks) `elem` keys =+ tobutton e@(KeyEvent {state=s,type'=Pressed,keySym=ks})+ | (s, ks) `elem` keys =+ Just e+ -- Mouse Wheel support:+ tobutton e@(ButtonEvent {button=Button 4,type'=Pressed}) = Just e+ tobutton e@(ButtonEvent {button=Button 5,type'=Pressed}) = Just e+ tobutton _ = Nothing++ keys = map ((,) []) keys' ++ map ((,) [Shift]) keys'+ where keys' = ["Prior","Next","Home","End"]++ -- visibleK reports the current visible size and grabbed keys+ visibleK = K{-kk-} $ mapFilterSP visible+ where+ visible (Low (LEvt (LayoutSize vissize))) = Just (High (Right vissize))+ visible (Low (XEvt (KeyEvent{state=mods,type'=Pressed,keySym=key}))) =+ Just (High (Left (mods,key)))+ visible (Low (XEvt (ButtonEvent{button=Button 4,type'=Pressed,state=mods}))) =+ Just (High (Left (mods,"Prior")))+ visible (Low (XEvt (ButtonEvent{button=Button 5,type'=Pressed,state=mods}))) =+ Just (High (Left (mods,"Next")))+ visible (High vissize) =+ Just (Low (layoutRequestCmd (plainLayout vissize False False)))+ visible _ = Nothing++ initSP cont =+ waitForSP initreq $ \ req ->+ let vissize = limit initlimits rtotsize+ rtotsize = minsize req+ adj = inCoupling req+ in putSP (Left (Left vissize)) $+ cont vissize rtotsize adj+ where initreq (Left (Right (LayoutRequest req))) = Just req+ initreq _ = Nothing++ -- ctrlSP :: SP ((KV+T)+S) ((V+T)+S)+ -- cltrSP implements the scrolling+ -- Input : KV = grabbed keys or visible size (from visibleK)+ -- : T = total size (from freeGroupF)+ -- : S = scroll bar positions+ -- Output: V = requested visible size (to visibleK)+ -- S = scroll bar adjustments on size changes+ -- T = position adjustments on scroll bar changes,+ -- notification of current visible size+ ctrlSP visible total adj =+ concatMapAccumlSP ctrlT (visible, total, pP 0 0,adj) -- limits??+ where+ ctrlT s@(visible, total, pos, adj) msg =+ case msg of+ Left (Left (Left key)) -> (s,potKeyInput key)+ Left (Left (Right visible')) -> adjustVisible visible' adj+ Left (Right req) ->+ case req of+ LayoutRequest req -> adjustVisible visible adj'+ where adj' = inCoupling req+ LayoutMakeVisible rect align ->+ (s, mkvisible rect align)+ --LayoutScrollStep step -> ...+ _ -> (s, [])+ Right (Left (y,_,_)) -> vmove pos (-y)+ Right (Right (x,_,_)) -> hmove pos (-x)+ where+ potKeyInput key@(mods,k) =+ if Shift `elem` mods+ then [Right (Right (PotInput (remove Shift mods,k)))]+ else [Right (Left (PotInput key))]+ adjustVisible visible' adj' =+ ((visible', total', pos, adj'),+ Left (Right (Left total')):+ adjustPots visible' total')+ where total' = adj' visible'+ adjustPots (Point visw vish) size@(Point totw toth) =+ [Right (Right (ResizePot visw totw)),+ Right (Left (ResizePot vish toth))]+ mkvisible r@(Rect (Point x y) (Point w h)) (halign,valign) =+ --ctrace "mkvisible" r $+ [Right (Right (PotMkVisible x w halign)),+ Right (Left (PotMkVisible y h valign))]+ vmove pos@(Point x _) y =+ --ctrace "vmove" (pos,pos') $+ ((visible,total,pos',adj),[Left (Right (Right pos'))])+ where pos' = Point x y+ hmove pos@(Point _ y) x =+ --ctrace "hmove" (pos,pos')+ ((visible,total,pos',adj),[Left (Right (Right pos'))])+ where pos' = Point x y+++limit (min', max') size = pmax min' (pmin max' size)+++type SizeCoupling = Size -> Size -> Size+-- my size other size my new size++stdCoupling = pmax+vCoupling (Point tw th) (Point vw vh) = Point vw (max th vh)+hCoupling (Point tw th) (Point vw vh) = Point (max tw vw) vh++plainAdjLayout (Layout {minsize=total'}) = stdCoupling total'+wAdjLayout (Layout {wAdj=wa}) = s (flip vCoupling) (wa . xcoord)+hAdjLayout (Layout {hAdj=ha}) = s (flip hCoupling) (ha . ycoord)++s f g x = f x (g x)++-- assocLeft :: a+(b+c) -> (a+b)+c+-- assocRight :: (a+b)+c -> a+(b+c)+assocLeft = either (Left. Left) (either (Left. Right) Right)+assocRight = either (either Left (Right. Left)) (Right. Right)++--swapRight :: (a+b)+c -> (a+c)+b+swapRight = either (either (Left. Left) Right) (Left. Right)
+ hsrc/containers/SelectionF.hs view
@@ -0,0 +1,109 @@+module SelectionF where +import FudUTF8(decodeUTF8,encodeUTF8)+import Command+import CompOps((>=^<), (>^=<))+import Cont(conts,cmdContK')+import Shells(unmappedShellF)+import Event+import Fudget+import FRequest+import Xcommand+import GetWindowProperty+import InternAtom+--import Message(Message(..))+import NullF+import LayoutF(nullLF)+import Spops(putSP,getSP)+import Loops(loopThroughRightF)+import EitherUtils(stripEither)+import SerCompF(absF)+import Xtypes++{- +Supports cut/paste of UTF-8 encoded Unicode Strings.+Cut/paste of Unicode strings between two fudgets program works.+Cut/paste between a fudget program and xterm -u8 from XFree86 4.0 works.+/TH 2000-04-02+-}++data SelCmd a = Sel a | ClearSel | PasteSel deriving (Eq, Ord)+data SelEvt a = LostSel | SelNotify a deriving (Eq, Ord)++data ESelCmd a = OwnSel | SelCmd (SelCmd a) deriving (Eq, Ord)+data ESelEvt a = WantSel | SelEvt (SelEvt a) deriving (Eq, Ord)++eselectionF :: F (ESelCmd String) (ESelEvt String)+eselectionF =+ (stripEither >^=< unmappedShellF [] selK nullLF) >=^<+ Left where+ selK =+ conts (flip internAtomK True) + ["PRIMARY", "STRING", "NONE", "ATOM"] $ + \ [primaryA, stringA, noneA, atomA] ->+ conts (flip internAtomK False) ["FUDGETS_UTF8","UTF8_STRING"] $+ \ [fudgetsA, utf8A] -> let+ sevt = High. SelEvt+ l =+ getK $ \ev ->+ case ev of+ High esc -> case esc of+ SelCmd sc -> case sc of+ Sel t -> l -- select t+ ClearSel -> deselect+ PasteSel -> paste_utf8string -- try UTF-8 first...+ OwnSel -> select+ Low (XEvt ev) -> case ev of+ SelectionClear s | s == primaryA -> putK (sevt LostSel) l+ SelectionRequest t w s -> selectionrequest t w s+ SelectionNotify t s -> selectionnotify s+ _ -> l+ Low _ -> l+ selectionrequest time w sel@(Selection s t p) =+ if t `notElem` [stringA,utf8A]+ then notify time w (Selection s noneA p) l+ else+ let p' = if p == noneA then t else p+ wait (High (SelCmd (Sel t))) = Just t+ wait _ = Nothing+ in cmdContK' (High WantSel) wait $ \rawtext ->+ let text = if t==utf8A+ then encodeUTF8 rawtext+ else rawtext in+ xcommandK (ChangeProperty w p' t 8 propModeReplace text) $+ notify time w (Selection s t p') l+ notify t w sel = xcommandK (SendEvent w False [] (SelectionNotify t sel))+ paste_string = paste' stringA+ paste_utf8string = paste' utf8A+ paste' typ =+ xcommandK (ConvertSelection (Selection primaryA typ fudgetsA)) l+ paste_failed = putK (sevt (SelNotify "")) l+ selectionnotify sel@(Selection s t p) =+ if p==noneA+ then if t==utf8A -- UTF8_STRING wasn't supported, try STRING+ then paste_string+ else paste_failed+ else if t `notElem` [stringA,utf8A]+ then paste_failed+ else getWindowPropertyK 0 p True t $ + \(typ, format, nitems, after,seltext) ->+ let s' = if t==utf8A then decodeUTF8 seltext else seltext in+ putK (sevt (SelNotify s')) l+ select = select' True+ deselect = select' False+ -- should check that setselectionowner succeeded.+ select' b = xcommandK (SetSelectionOwner b primaryA) l+ in l++selectionF :: F (SelCmd String) (SelEvt String)+selectionF = loopThroughRightF (absF (selSP "")) (eselectionF) where+ selSP text = + let same = selSP text + toesel = Left+ toout = Right in+ getSP $ \msg -> case msg of+ Right ocmd -> case ocmd of+ Sel t -> putSP (toesel OwnSel) $ selSP t+ _ -> putSP (toesel (SelCmd ocmd)) same+ Left esevt -> case esevt of+ WantSel -> putSP (toesel (SelCmd (Sel text))) same+ SelEvt se -> putSP (toout se) same
+ hsrc/containers/Shells.hs view
@@ -0,0 +1,42 @@+module Shells where++import FDefaults+import Fudget+import FRequest+import Xcommand+import DShellF+import EitherUtils+--import NullF+import CompOps+import Command+import FudgetIO+import Event+import Spops(concatMapSP)+import MapstateK++unmappedShellF cmds = unmappedShellF' standard cmds++unmappedShellF' pm cmds k =+ shellKF' (pm. setVisible False. setMargin 0)+ (putLows cmds k)+ +unmappedSimpleShellF = unmappedSimpleShellF' standard++unmappedSimpleShellF' :: Customiser ShellF -> String -> F i o -> F i o+unmappedSimpleShellF' pm name f = + stripEither >^=< shellKF' params k f >=^^< mapraiseSP where+ params = setVisible False . pm+ startcmds = [StoreName name]+ mapraiseSP = concatMapSP ( \msg -> [Right msg, Left True])+ k = xcommandsK startcmds mapWindowK++mapWindowK = mapstateK k1 False+ where+ k1 False (High True) = (True, [Low $ XCmd $ MapRaised])+ k1 True (High False) = (False, [Low $ XCmd $ UnmapWindow])+ k1 _ (Low (XEvt (UnmapNotify _))) = (False, [])+ k1 _ (Low (XEvt (MapNotify _))) = (True, [])+ k1 mapped _ = (mapped, [])++-- Retained for backwards compatibility:+simpleShellF name wattrs = shellF' (setWinAttr wattrs) name
+ hsrc/debug/Debug.hs view
@@ -0,0 +1,5 @@+module Debug (-- * Debug+ module Maptrace,module ShowCommandF,module SpyF) where+import Maptrace+import ShowCommandF+import SpyF
+ hsrc/debug/Maptrace.hs view
@@ -0,0 +1,10 @@+module Maptrace(maptrace,ctrace) where+import Debug.Trace(trace)+import CmdLineEnv(argFlag)++maptrace s = map (\x -> if x == x then trace s x else error "?")++ctrace flag =+ if argFlag flag False+ then \e -> trace (flag++": "++show e)+ else const id
+ hsrc/debug/ShowCommandF.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE CPP #-}+module ShowCommandF(showCommandF) where+import CompOps((>.=<), (>=.<))+import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import LayoutRequest(LayoutRequest)+--import Message(Message)+import Path(showPath)+import Debug.Trace(trace)+import Xtypes+import Command+import Event+--import ResourceIds+import Sockets+import CmdLineEnv(argFlag)+--import DialogueIO hiding (IOError)++showCommandF :: String -> (F a b) -> F a b+showCommandF s f = const (if not (argFlag s False) then f else+ let showit show' d (t, c) =+ trace (s ++ " " ++ d ++ ": " ++ showPath t ++ ": " ++ show' c+#ifdef __NHC__+ ++ "\n"+#endif+ )+ (t, c)+ in (showit show "out" >.=< f) >=.< showit show "in") x++{-+showEv e = case e of+ IOResponse (XResponse x) -> "IOResponse (XResponse ..."++show x++")"+ _ -> show e+-}++-- Hack: The following is to avoid show methods from hlib++x = [show (m :: Display),+ show (m :: Command),+ show (m :: Event),+ show (m :: WindowId),+ show (m :: Descriptor)]++m = error "module ShowCommandF"
+ hsrc/debug/ShowFailure.hs view
@@ -0,0 +1,6 @@+module ShowFailure where++import qualified DialogueIO++showFailure :: DialogueIO.IOError -> String+showFailure = show
+ hsrc/debug/SpyF.hs view
@@ -0,0 +1,22 @@+module SpyF where+import Fudget+import CompOps+import IoF(ioF)+import StdIoUtil(echoStderrK)+--import EitherUtils+import NullF(getK,putK{-,F,K-})+--import FudgetIO+--import ContinuationIO(stderr)++spyF f = teeF show "OUT: " >==< f >==< teeF show "IN: "++teeF show prefix = ioF teeK+ where+ teeK =+ getK $ \msg ->+ case msg of+ Low _ -> teeK+ High msg -> echoStderrK (prefix++show msg) $+ putK (High msg) $+ teeK+
+ hsrc/defaults/DefaultParams.hs view
@@ -0,0 +1,8 @@+module DefaultParams(-- * Default parameters+ module FDefaults) where+import FDefaults++{-+import Fudget+import Xtypes(ColorName(..),FontName(..),KeySym(..),ModState(..),Modifiers,WindowAttributes)+-}
+ hsrc/defaults/FDefaults.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE CPP #-}+module FDefaults(module FDefaults,module Alignment,fromMaybe) where++import Fudget+import CompOps+import Xtypes+import Alignment(Alignment(..))+--import Geometry(pmax)+import Data.Maybe(fromMaybe)+import Sizing(Sizing)+import GCAttrs --(ColorSpec,colorSpec)+#include "defaults.h"++type Customiser a = a -> a+cust :: (a->a) -> Customiser a -- to obtain better type signatures+cust = id++type PF p a b = F (Either (Customiser p) a) b+type PK p a b = K (Either (Customiser p) a) b++getpar pp = fromMaybe (error "getpar:: missing default") . getparMaybe pp++getparMaybe pp [] = Nothing+getparMaybe pp (p:ps) =+ case pp p of+ Just a -> Just a+ Nothing -> getparMaybe pp ps++noPF :: PF p a b -> F a b+noPF f = f >=^< Right++standard :: Customiser a+standard = id++parameter_class(FontSpec,FontSpec)+setFont f = setFontSpec (fontSpec f)++--parameter_class(Title,String)+parameter_class(Keys,[(ModState,KeySym)])+parameter_class(WinAttr,[WindowAttributes])+parameter_class(BorderWidth,Int)++parameter_class(BgColorSpec,ColorSpec)+parameter_class(FgColorSpec,ColorSpec)+-- eta expanded because of the stupid monomorphism restriction+setBgColor c = setBgColorSpec . colorSpec $ c+setFgColor c = setFgColorSpec . colorSpec $ c+--getBgColor c = getBgColorSpec $ c+--getFgColor c = getFgColorSpec $ c++parameter_class(Margin,Int)+parameter_class(Align,Alignment)+parameter_class1(InitSize)+parameter_class1(InitDisp)+parameter_class(Stretchable,(Bool,Bool))+parameter_class(InitText,[String])+parameter_class(Sizing,Sizing)
+ hsrc/defaults/defaults.h view
@@ -0,0 +1,33 @@+{-+HBC uses "cpp -C -traditional" which causes all the /**/ to be left behind+when the macro definitions are processed. That is why the definitions+are inside a comment.++#define parameter_class(name,type) parameter_class_gen(name,name,type)++#define parameter_class_gen(classname,par,type) \+class Has/**/classname xxx where {\+ set/**/par :: (type) -> Customiser xxx; \+ get/**/par :: xxx -> (type); \+ get/**/par/**/Maybe :: xxx -> Maybe (type); \+ get/**/par = fromMaybe (error "get par: missing default") . get/**/par/**/Maybe }++#define parameter_class1(par) class Has/**/par xxx where {\+ set/**/par :: a -> Customiser (xxx a); \+ get/**/par/**/Maybe :: xxx a -> Maybe a; \+ get/**/par :: xxx a -> a; \+ get/**/par = fromMaybe (error "get par: missing default") . get/**/par/**/Maybe }++#define parameter_instance1(par,type) parameter_instance(par,type a)++#define parameter_instance(par,type) instance Has/**/par (type) where {\+ set/**/par p (Pars ps) = Pars (par p:ps); \+ get/**/par/**/Maybe (Pars ps) = getparMaybe (\x->case x of par p -> Just p; _-> Nothing) ps }++/* non-overloaded parameters: */+#define parameter(par) \+set/**/par p = cust (\ (Pars ps) -> Pars (par p:ps)); \+get/**/par (Pars ps) = getpar (\x->case x of par p -> Just p; _-> Nothing) ps; \+get/**/par/**/Maybe (Pars ps) = getparMaybe (\x->case x of par p -> Just p; _-> Nothing) ps+ +-}
+ hsrc/doRequest.hs view
@@ -0,0 +1,17 @@+import Control.Monad(forever)+import System.IO+import DoRequest++main =+ do state <- initXCall+ forever (print' =<< doRequest state =<< readLn')++print' x = do --hPutStr stderr "OR: "+ --hPrint stderr x+ print x+ hFlush stdout++readLn' = do r <- readLn+ --hPutStr stderr "IR: "+ --hPrint stderr r+ return r
+ hsrc/drawing/BitmapDrawing.hs view
@@ -0,0 +1,35 @@+module BitmapDrawing where+import Graphic+import MeasuredGraphics(MeasuredGraphics(..))+import GCtx(GCtx(..))+--import Command+import Event(BitmapReturn(..))+import DrawTypes+import Geometry(Rect(..),origin)+import Xtypes+--import FudgetIO+import NullF() -- instances, for hbc+import LayoutRequest(refpLayout,plainLayout)+import Gc+import StdIoUtil(echoStderrK)+import Pixmap(readBitmapFile)+import Data.Maybe(maybeToList)+--import ContinuationIO(stderr)++data BitmapFile = BitmapFile String++instance Graphic BitmapFile where+ measureGraphicK (BitmapFile filename) (GC gc _) k =+ readBitmapFile filename $ \ bmret ->+ case bmret of+ BitmapReturn size optrefp pixmap ->+ wCreateGC gc [GCGraphicsExposures False] $ \ gc' ->+ k (LeafM ll (drawit gc'))+ where r = Rect origin size+ ll = refpLayout size True True (maybeToList optrefp)+ drawit gc (Rect p _) = [(gc,[CopyPlane (Pixmap pixmap) r p 0])]+ _ ->+ echoStderrK ("Failed to load bitmap "++filename) $+ k (LeafM ll drawit)+ where ll = plainLayout 20 False False+ drawit r = [(gc,[FillRectangle r])]
+ hsrc/drawing/Color.hs view
@@ -0,0 +1,71 @@+module Color(tryAllocColor,tryAllocColorF,+ allocColor,allocColorF,+ allocColorPixel,allocColorPixelF,+ tryAllocNamedColor,tryAllocNamedColorF,+ allocNamedColor,allocNamedColorF,+ allocNamedColorPixel,allocNamedColorPixelF,+ allocNamedColorDef,+ allocNamedColorDefPixel,+ queryColor,queryColorF+ ) where+import Command+import Event+--import Fudget+import Xrequest+import Xtypes+import Cont+--import NullF(F,K)+import StdIoUtil(echoStderrK)+--import ContinuationIO(stderr)++genTryAlloc cmd xr =+ let expected (ColorAllocated color) = Just color+ expected _ = Nothing+ in xr cmd expected++genTryAllocColor xr cmap rgb = genTryAlloc (AllocColor cmap rgb) xr+genTryAllocNamedColor xr cmap cname = genTryAlloc (AllocNamedColor cmap cname) xr++tryAllocColor x = genTryAllocColor xrequest x+tryAllocColorF = genTryAllocColor xrequestF++tryAllocNamedColor x = genTryAllocNamedColor xrequest x+tryAllocNamedColorF = genTryAllocNamedColor xrequestF++--allocNamedColorDef :: ColormapId -> ColorName -> ColorName -> Cont (K a b) Color+allocNamedColorDef cmap cname fallback = + tryGet (tryAllocNamedColor cmap cname)+ (echoStderrK+ ("Warning, cannot allocate background color \""++cname+++ -- backround ??+ "\", using \""++fallback++"\" instead.") .+ allocNamedColor cmap fallback)++--allocNamedColorDefPixel :: ColormapId -> ColorName -> ColorName -> Cont (K a b) Pixel+allocNamedColorDefPixel cmap cname fallback = allocNamedColorDef cmap cname fallback+ . (.colorPixel)++safe req cmap c = tryM (req cmap c) (error ("Cannot allocate color: "++show c))++pixel :: (a->b->Cont c Color) -> a->b->Cont c Pixel+pixel req cmap c = req cmap c . (.colorPixel)++allocNamedColor x = safe tryAllocNamedColor x+allocNamedColorF = safe tryAllocNamedColorF++allocNamedColorPixel x = pixel allocNamedColor x+allocNamedColorPixelF = pixel allocNamedColorF++allocColor x = safe tryAllocColor x+allocColorF = safe tryAllocColorF++allocColorPixel x = pixel allocColor x+allocColorPixelF = pixel allocColorF++querycolor xr cmap pixel =+ let expected (ColorQueried c) = Just c+ expected _ = Nothing+ in xr (QueryColor cmap pixel) expected++queryColorF = querycolor xrequestF+queryColor x = querycolor xrequest x
+ hsrc/drawing/Convgc.hs view
@@ -0,0 +1,32 @@+module Convgc(convGCattrsK) where+import Color+--import Font(FontStruct)+--import Fudget+import LoadFont+--import Spops+import Xtypes+import EitherUtils() -- synonym Cont, for hbc++convGCattrsK attrs = gcattrsK attrs []++gcattrsK [] outattrs dr = dr (reverse outattrs)+gcattrsK (attr : attrs) outattrs dr =+ let cp attr' = gcattrsK attrs (attr' : outattrs) dr+ in case attr of+ GCForeground colname ->+ allocNamedColorPixel defaultColormap colname $ \fg ->+ gcattrsK attrs (GCForeground fg : outattrs) dr+ GCBackground colname ->+ allocNamedColorPixel defaultColormap colname $ \fg ->+ gcattrsK attrs (GCBackground fg : outattrs) dr+ GCFont fname ->+ loadFont fname $ \font ->+ gcattrsK attrs (GCFont font : outattrs) dr+ GCFunction f -> cp (GCFunction f)+ GCLineWidth w -> cp (GCLineWidth w)+ GCLineStyle s -> cp (GCLineStyle s)+ GCCapStyle s -> cp (GCCapStyle s)+ GCJoinStyle s -> cp (GCJoinStyle s)+ GCSubwindowMode m -> cp (GCSubwindowMode m)+ GCGraphicsExposures b -> cp (GCGraphicsExposures b)+
+ hsrc/drawing/Cursor.hs view
@@ -0,0 +1,22 @@+module Cursor where+import Command+import Event+import Fudget+import Xrequest+import Xcommand+import Xtypes++createFontCursor shape =+ let cmd = CreateFontCursor shape+ expected (CursorCreated cursor) = Just cursor+ expected _ = Nothing+ in xrequestK cmd expected++setFontCursor :: Int -> K a b -> K a b+setFontCursor shape process =+ createFontCursor shape $ \ cursor ->+ xcommandK (ChangeWindowAttributes [CWCursor cursor]) $+ process++defineCursor cursor = xcommandK (ChangeWindowAttributes [CWCursor cursor])+undefineCusror = xcommandK (ChangeWindowAttributes [CWCursor cursorNone])
+ hsrc/drawing/Drawing.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE DeriveFunctor #-}+module Drawing(Drawing(..),labelD,placedD,atomicD,DPath(..),up,GCSpec) where+import Graphic+import MeasuredGraphics(MeasuredGraphics(..),DPath(..),up)+--import FudgetIO+import NullF() -- instances, for hbc+import GCtx(GCSpec(..),wCreateGCtx)+import Placers2(overlayP)+import LayoutRequest+--import EitherUtils(Cont(..))+import GCAttrs(ColorSpec,FontSpec)+import Xtypes(GCAttributes)+--import Geometry() -- Show instances++data Drawing lbl leaf+ = AtomicD leaf+ | LabelD lbl (Drawing lbl leaf)+ | AttribD GCSpec (Drawing lbl leaf)+ | SpacedD Spacer (Drawing lbl leaf)+ | PlacedD Placer (Drawing lbl leaf)+ | ComposedD Int [Drawing lbl leaf] -- ^ Int=how many visible components+ | CreateHardAttribD GCtx [GCAttributes ColorSpec FontSpec] (GCtx -> + Drawing lbl leaf)+ deriving (Show,Functor)++labelD = LabelD+placedD = PlacedD+atomicD = AtomicD++instance Graphic leaf => Graphic (Drawing annot leaf) where+ measureGraphicK = drawK+ measureGraphicListK = drawListK overlayP -- or autoP ??+++drawK d gctx{-@(GC gc fs)-} k =+ case d of+ AtomicD x -> measureGraphicK x gctx k+ LabelD _ d -> drawK d gctx (k . MarkM gctx)+ AttribD gcspec d ->+ wCreateGCtx' gctx gcspec $ \ gctx' ->+ drawK d gctx' (k . MarkM gctx')+ SpacedD spacer d ->+ drawK d gctx $ \ g ->+ k (SpacedM spacer g)+ PlacedD placer d ->+ drawK d gctx $ \ g ->+ k (PlacedM placer g)+ ComposedD n ds ->+ -- take the n visible components, remaining parts are invisible.+ drawsK gctx (take n ds) $ \ gs ->+ k (ComposedM gs)+ CreateHardAttribD templ attrs d ->+ wCreateGCtx templ attrs $ \tx ->+ drawK (d tx) gctx k+{-+ where+ replaceFontK fs gcattrs k = font gcattrs (k fs) (\fid -> queryFont fid k)+ font [] kdef _ = kdef+ font (GCFont fid:gcattrs) _ kfont = kfont fid+ font (_:gcattrs) kdef kfont = font gcattrs kdef kfont+-}++drawListK placer ds gctx k =+ drawsK gctx ds $ \ gs ->+ k (PlacedM placer $ ComposedM gs)++drawsK gctx [] k = k []+drawsK gctx (d:ds) k =+ drawK d gctx $ \ g ->+ drawsK gctx ds $ \ gs ->+ k (g:gs)++wCreateGCtx' gctx gcspec k =+ case gcspec of+ HardGC gctx' -> k gctx'+ SoftGC gcattrs -> wCreateGCtx gctx gcattrs k
+ hsrc/drawing/DrawingModules.hs view
@@ -0,0 +1,42 @@+module DrawingModules(-- * Drawing+ -- ** Colors+ module Color,+ -- ** Cursors+ module Cursor,+ -- ** Fonts+ module Font,module LoadFont,+ -- ** Graphics Contexts+ module Gc,module Convgc,module GCAttrs,module GCtx,+ -- ** class Graphic+ module Graphic,+ -- ** Atomic Drawings+ module FixedDrawing,module FlexibleDrawing,+ module BitmapDrawing,module Pixmap,module PixmapGen,+ -- ** Composed drawings+ module Drawing,module DrawingUtils,module DrawingOps,+ module Graphic2Pixmap,+ -- ** Misc+ module TransCoord,+ module MeasuredGraphics, module CompiledGraphics+) where+import Color+import Convgc+import Cursor+import Font+import Gc+import LoadFont+import Pixmap+import TransCoord+import DrawingUtils+import FixedDrawing+import FlexibleDrawing+import BitmapDrawing+import PixmapGen+import GCAttrs+import GCtx+import Graphic+import Drawing+import DrawingOps+import Graphic2Pixmap+import MeasuredGraphics+import CompiledGraphics
+ hsrc/drawing/DrawingOps.hs view
@@ -0,0 +1,226 @@+module DrawingOps where+import Drawing(Drawing(..),DPath(..),up)+import Utils(number)++drawingPart drawing path =+ case maybeDrawingPart drawing path of+ Just part -> part+ Nothing -> error ("bad path in drawingPart "++show path)++maybeDrawingPart drawing path =+ case (path::DPath) of+ [] -> Just drawing+ p:ps -> part drawing+ where+ part0 d = if p==0+ then maybeDrawingPart d ps+ else Nothing+ part drawing =+ case drawing of+ AtomicD _ -> Nothing+ LabelD _ d -> part0 d+ AttribD gcattrs d -> part0 d+ SpacedD spacer d -> part0 d+ PlacedD placer d -> part0 d+ ComposedD _ ds ->+ if 1<=p && p<=length ds+ then maybeDrawingPart (ds !! (p-1)) ps+ else Nothing++drawingAnnotPart = drawingAnnotPart' (const True)++drawingAnnotPart' p drawing path =+ case path of+ [] -> []+ _ -> case maybeDrawingPart drawing path of+ Just (LabelD a _) | p a -> path+ _ -> drawingAnnotPart' p drawing (up path)++isVisibleDrawingPart drawing path =+ case (path::DPath) of+ [] -> True+ p:ps -> visible drawing+ where+ visible0 d = p==0 && isVisibleDrawingPart d ps -- ??+ visible drawing =+ case drawing of+ AtomicD _ -> True -- ??+ LabelD _ d -> visible0 d+ AttribD gcattrs d -> visible0 d+ SpacedD spacer d -> visible0 d+ PlacedD placer d -> visible0 d+ ComposedD n ds ->+ 1<=p && p<=n && isVisibleDrawingPart (ds !! (p-1)) ps++visibleAncestor drawing path =+ case path::DPath of+ [] -> path+ p:ps ->+ case drawing of+ AtomicD _ -> path+ LabelD _ d -> skip d+ AttribD gcattrs d -> skip d+ SpacedD spacer d -> skip d+ PlacedD placer d -> skip d+ ComposedD n ds ->+ if 1<=p && p<=n+ then p:visibleAncestor (ds!!(p-1)) ps+ else []+ where skip d = 0:visibleAncestor d ps++replacePart drawing path new = updatePart drawing path (const new)++updatePart drawing path new =+ case (path::DPath) of+ [] -> new drawing+ p:ps -> repl drawing+ where+ err = error "bad path in updatePart"+ repl0 d = if p==0 then updatePart d ps new else err+ repl drawing =+ case drawing of+ AtomicD _ -> err+ AttribD gcattrs d -> AttribD gcattrs (repl0 d)+ LabelD label d -> LabelD label (repl0 d)+ SpacedD spacer d -> SpacedD spacer (repl0 d)+ PlacedD placer d -> PlacedD placer (repl0 d)+ ComposedD n ds ->+ let (pre,d:post) = splitAt (p-1) ds+ in ComposedD n (pre++updatePart d ps new:post)++mapLabelDrawing f = ma+ where+ ma d =+ case d of+ AtomicD x -> AtomicD x+ AttribD gcattrs d -> AttribD gcattrs (ma d)+ LabelD label d -> LabelD (f label) (ma d)+ SpacedD spacer d -> SpacedD spacer (ma d)+ PlacedD placer d -> PlacedD placer (ma d)+ ComposedD n ds -> ComposedD n (map ma ds)++mapLeafDrawing f = ma+ where+ ma d =+ case d of+ AtomicD x -> AtomicD (f x)+ AttribD gcattrs d -> AttribD gcattrs (ma d)+ LabelD label d -> LabelD label (ma d)+ SpacedD spacer d -> SpacedD spacer (ma d)+ PlacedD placer d -> PlacedD placer (ma d)+ ComposedD n ds -> ComposedD n (map ma ds)++{-+drawingArity drawing =+ case drawing of+ AtomicD _ -> 0+ LabelD _ d -> drawingArity d+ AttribD _ d -> drawingArity d+ SpacedD _ d -> drawingArity d+ PlacedD _ d -> drawingArity d+ ComposedD _ ds -> length ds+-}++annotChildren = annotChildren' (const True)++annotChildren' :: (a -> Bool) -> (Drawing a d) -> [(DPath, Drawing a d)] +annotChildren' p drawing =+ case drawing of+ LabelD _ d -> ac0 d+ d -> ac d+ where + ac0 d0 = [(0:p,d)| (p,d)<-ac d0]+ ac d =+ case d of+ AtomicD _ -> []+ LabelD a d' -> if p a then [([],d)] else ac0 d'+ AttribD _ d -> ac0 d+ SpacedD _ d -> ac0 d+ PlacedD _ d -> ac0 d+ ComposedD _ ds -> [(i:p,d) | (i,cs) <- number 1 (map ac ds), (p,d)<-cs]++{-+drawingAnnots :: Drawing a d -> [(DPath,a)] +drawingAnnots drawing = da drawing+ where + da d =+ case d of+ AtomicD _ -> []+ LabelD a d' -> ([],a):da d'+ AttribD _ d -> da d+ SpacedD _ d -> da d+ PlacedD _ d -> da d+ ComposedD _ ds -> [(i:p,d) | (i,cs) <- number 1 (map da ds), (p,d)<-cs]+-}++drawingAnnots drawing = extractParts drawing sel+ where sel (LabelD a d) = Just a+ sel _ = Nothing++extractParts :: Drawing lbl leaf -> (Drawing lbl leaf -> Maybe a) -> [(DPath,a)]+extractParts drawing sel = extr drawing+ where+ extr0 d = [(0:p,d') | (p,d') <- extr d]+ extr d =+ (case sel d of+ Just x -> (([],x):)+ _ -> id) $+ case d of+ AtomicD _ -> []+ LabelD a d' -> extr0 d'+ AttribD _ d -> extr0 d+ SpacedD _ d -> extr0 d+ PlacedD _ d -> extr0 d+ ComposedD _ ds -> [(i:p,d) | (i,cs) <- number 1 (map extr ds), (p,d)<-cs]++deletePart drawing [] = drawing -- !! error report?+deletePart drawing path =+ updatePart drawing (init path) (deleteElem (last path))+ where+ deleteElem i = di+ where di d =+ case d of+ ComposedD n ds ->+ case splitAt (i-1) ds of+ (ds1,_:ds2) -> ComposedD n' (ds1++ds2)+ _ -> d -- !! error report?+ where n' = if i<=n+ then n-1+ else n+ _ -> d -- !! error report?+{-+ AtomicD x -> d -- !! error report?+ AttribD gcattrs d -> AttribD gcattrs (di d)+ LabelD label d -> LabelD label (di d)+ SpacedD spacer d -> SpacedD spacer (di d)+ PlacedD placer d -> PlacedD placer (di d)+-}++groupParts pos0 len0 drawing =+ case drawing of+ ComposedD n ds -> ComposedD n1 (ds1++ComposedD n2 ds2:ds3)+ where+ (ds1,ds2a) = splitAt (pos0-1) ds+ (ds2,ds3) = splitAt len0 ds2a+ pos = length ds1+ len = length ds2+ -- keep the same parts visible+ (n1,n2) = if n<=pos then (n,0)+ else if n<=pos+len+ then (pos+1,n-pos)+ else (n-len+1,len)++ungroupParts pos drawing =+ case drawing of+ ComposedD n1 ds ->+ case splitAt (pos-1) ds of+ (ds1,ComposedD n2 ds2:ds3) -> ComposedD n (ds1++ds2++ds3)+ where+ -- Can't preserve visibility when some of ds3 was visible+ -- but some of ds2 was hidden+ n = if n1<=pos then n1+ else if n1==pos+1+ then pos+n2+ else n1-1+length ds2 -- all of ds2 becomes visible!!+ _ -> drawing -- hmm!!+ _ -> drawing -- hmm!!
+ hsrc/drawing/DrawingUtils.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE CPP #-}+module DrawingUtils where+import Xtypes+import Drawing+import Graphic+import FixedDrawing+import FlexibleDrawing(blank')+import GCAttrs+import GCtx+import Placers+import MatrixP(matrixP,matrixP')+import Spacers+import Placers2+import TableP(tableP,tableP')+import Geometry+import DrawTypes(DrawCommand(..))+import Alignment(aLeft,aCenter,aTop)+import LayoutDir(LayoutDir(..))+--import EitherUtils(Cont(..))+--import Fudget(K)++#include "exists.h"++boxVisibleD = ComposedD+boxD ds = ComposedD (length ds) ds+stackD = PlacedD overlayP . boxD+vertD = PlacedD verticalP+vertD' = PlacedD . verticalP'+horizD = PlacedD horizontalP+horizD' = PlacedD . horizontalP'+vboxD = vertD . boxD+hboxD = horizD . boxD+vboxD' sep = vertD' sep . boxD+hboxD' sep = horizD' sep . boxD++vertlD = PlacedD verticalLeftP+vertlD' = PlacedD . verticalLeftP'+vboxlD = vertlD . boxD+vboxlD' sep = vertlD' sep . boxD+horizcD = PlacedD horizontalCenterP+horizcD' = PlacedD . horizontalCenterP'+hboxcD = horizcD . boxD+hboxcD' sep = horizcD' sep . boxD++tableD n = PlacedD (tableP n) . boxD+tableD' sep n = PlacedD (tableP' n Horizontal sep) . boxD++matrixD n = PlacedD (matrixP n) . boxD+matrixD' sep n = PlacedD (matrixP' n Horizontal sep) . boxD++westD = spacedD $ hvAlignS aLeft aCenter+northwestD = spacedD $ hvAlignS aLeft aTop++padD = spacedD.marginS++fontD fn = softAttribD [GCFont (fontSpec fn)]++--fgnD :: ColorName -> Drawing lbl leaf -> Drawing lbl leaf+--fgnD = fgD.Name++--fontnD :: FontName -> Drawing lbl leaf -> Drawing lbl leaf+--fontnD = fontD.Name++fgD color = softAttribD [GCForeground (colorSpec color)]+bgD color = softAttribD [GCBackground (colorSpec color)]+fatD = softAttribD [GCLineWidth 5,GCCapStyle CapRound]+--attribD = belowAnnotD.AttribD --hmm+attribD = AttribD +softAttribD = attribD.SoftGC+hardAttribD = attribD.HardGC+--spacedD = belowAnnotD.SpacedD --hmm+spacedD = SpacedD++--belowAnnotD f (LabelD a d) = LabelD a (belowAnnotD f d)+--belowAnnotD f d = f d++#ifdef USE_EXIST_Q+data Gfx = EXISTS(a) TSTHACK((Graphic EQV(a)) =>) G EQV(a)+-- deriving Show -- doesn't work because of a HBC bug++instance Show Gfx where showsPrec n (G x) s = "G "++{-showsPrec 10 x-} s++instance Graphic Gfx where+ measureGraphicK (G x) = measureGraphicK x++g x = atomicD (G x)++#else++g = atomicD++#endif++filledRectD size = g (FixD (size) [FillRectangle (Rect origin size)])+rectD size = g (FixD (size+1) [DrawRectangle (Rect origin size)])+ -- size+1 assumes that the line width is 1+blankD = g . blank' ++holeD =+ fgD "blue3" $ rectD size+ --stack [fgD "white" (filledRectD size),rectD size]+ where+ size = pP 15 13
+ hsrc/drawing/Expose.hs view
@@ -0,0 +1,27 @@+module Expose where++import Message+import Cont+--import Command+--import LayoutRequest+import Fudget+--import Xtypes+import Geometry(Rect,rmax)+import FRequest+import Event+--import Font++collectExposeK :: Bool -> Rect -> Int -> ([Rect] -> K a b) -> K a b+collectExposeK grX r aft c = collect [r] aft+ where collect rs aft = + if aft == 0 then c rs+ else waitForK (\r ->+ case r of+ Low (XEvt (Expose r aft')) | not grX -> Just (r,aft')+ Low (XEvt (GraphicsExpose r aft' _ _)) | grX -> Just (r,aft')+ _ -> Nothing) $ \(r,aft')->+ collect (r:rs) aft'+++maxExposeK grX r aft c = collectExposeK grX r aft $ \rs ->+ c (foldl1 rmax rs)
+ hsrc/drawing/FixedDrawing.hs view
@@ -0,0 +1,35 @@+module FixedDrawing where+import Graphic+import MeasuredGraphics(MeasuredGraphics(..),measureImageString)+import GCtx(GCtx(..))+import ResourceIds(GCId)+import LayoutRequest+import Geometry(Rect(..),Size(..))+import Command(DrawCommand)+import Drawcmd(move)+--import EitherUtils(Cont(..))++data FixedDrawing = FixD Size [DrawCommand] deriving Show++instance Graphic FixedDrawing where+ measureGraphicK (FixD s dcmds) (GC gc _) k =+ k (LeafM (plainLayout s True True) drawit)+ where+ drawit (Rect p _) = [(gc,move p dcmds)]++data FixedColorDrawing = FixCD Size [(GCId,[DrawCommand])] deriving Show++instance Graphic FixedColorDrawing where+ measureGraphicK (FixCD s gcdcmds) _ k =+ k (LeafM (plainLayout s True True) drawit)+ where+ drawit (Rect p _) =+ if p==0+ then gcdcmds+ else [(gc,move p dcmds)|(gc,dcmds)<-gcdcmds]+++newtype ImageString = ImageString String++instance Graphic ImageString where+ measureGraphicK (ImageString s) = measureImageString s
+ hsrc/drawing/FlexibleDrawing.hs view
@@ -0,0 +1,141 @@+module FlexibleDrawing where+import Geometry+import DrawTypes+--import Xtypes(CoordMode(..),Shape(..))+import LayoutRequest+--import EitherUtils(Cont(..))+import Utils(aboth)+import Graphic+import MeasuredGraphics(MeasuredGraphics(..))+import GCtx(GCtx(..))++data FlexibleDrawing = FlexD Size Bool Bool (Rect->[DrawCommand]) deriving Show++instance Graphic FlexibleDrawing where+ measureGraphicK (FlexD s fh fv drawf) (GC gc _) k =+ k (LeafM (plainLayout s fh fv) drawf')+ where drawf' r = [(gc,drawf r)]++filler fh fv d = FlexD (diag d) fh fv (\r->[FillRectangle r])++--filledRect = filler False False+hFiller = filler False True+vFiller = filler True False++flex' s = FlexD s False False+flex = flex' 5++blank' s = flex' s (const [])+blank = blank' 5++frame' s = flex' s (\r->[DrawRectangle (r `growrect` (-1))])+frame = frame' 5++ellipse = ellipse' 5+ellipse' s = arc' s 0 (360*64)+arc = arc' 5+arc' s a1 a2 = flex' s (drawarc a1 a2)++filledEllipse = filledEllipse' 5+filledEllipse' s = filledarc' s 0 (360*64)+filledarc = filledarc' 5+filledarc' s a1 a2 = flex' s (fillarc a1 a2)++drawarc a1 a2 r = [DrawArc (r `growrect` (-1)) a1 a2]+fillarc a1 a2 r = [FillArc (r `growrect` (-1)) a1 a2]++rpar = bFlex (drawarc (-60*64) (120*64).doubleleft)+lpar = bFlex (drawarc (120*64) (120*64).doubleright)++doubleleft (Rect p s@(Point w _)) = Rect (p-d) (s+d) where d=Point w 0+doubleright (Rect p s@(Point w _)) = Rect p (s+d) where d=Point w 0++-- top level pattern bindings (with pbu) can't be trusted...+lbrack = fst bracks+rbrack = snd bracks++bracks = aboth bFlex (draw False, draw True)+ where+ draw right r = [DrawLine (Line p1 p2) | (p1,p2) <- ls ]+ where (p1,p2,p3,p4) = corners (r `moverect` 1 `growrect` (-2))+ ls = if right+ then [(p1,p2),(p2,p4),(p3,p4)]+ else [(p1,p2),(p1,p3),(p3,p4)]++corners (Rect p s@(Point w h)) = (p,p+pP w 0,p+pP 0 h,p+s)++lbrace = fst braces+rbrace = snd braces++braces = aboth bFlex2 (draw False, draw True)+ where+ draw right r = [DrawLines CoordModePrevious ls]+ where (tl,tr,bl,br) = corners (r `moverect` 1 `growrect` (-2))+ h = ycoord (bl-tl)+ d = h `div` 2 - 4+ ls = if right+ then [tl,east 1,se 2,south d,se 2,sw 2,south d,sw 2,west 1]+ else [tr,west 1,sw 2,south d,sw 2,se 2,south d,se 2,east 1]++ west n = pP (-n) 0+ east n = pP n 0+ sw n = pP (-n) n+ se n = pP n n+ south n = pP 0 n++{-+polyLine p [] = []+polyLine p (v:vs) = (p,p'):polyLine p' vs+ where p' = p+v+-}++bFlex2 = bFlex' (pP 8 12)+bFlex = bFlex' (pP 5 10)+bFlex' size = FlexD size True False++rAngleBracket = bFlex2 (drawpoly . hMirror abPoints)+lAngleBracket = bFlex2 (drawpoly . abPoints)++abPoints = abPoints'+abPoints' r = [ur,ml,lr]+ where+ (ul@(Point lx ty),ur,_,lr@(Point rx by)) =+ corners (r `moverect` 1 `growrect` (-2))+ ml = Point (rx-d) my+ my = ty+h2+ h2 = (by-ty) `div` 2+ d = (h2 `div` 2) `min` (rx-lx)++triangleUp = flex' size (drawpoly . trianglePoints')+filledTriangleUp = flex' size (fillpoly . trianglePoints')+triangleDown = flex' size (drawpoly . vMirror trianglePoints')+filledTriangleDown = flex' size (fillpoly . vMirror trianglePoints')++size = Point 18 14++drawpoly ps = [DrawLines CoordModeOrigin ps]+fillpoly ps = [FillPolygon Convex CoordModeOrigin ps]+shrink = flip growrect (-1)++trianglePoints' = trianglePoints . shrink++trianglePoints (Rect p s@(Point w h)) = [p1,p2,p3,p1]+ where m = w `div` 2+ p1 = p+pP m 0+ p2 = p+s+ p3 = p+pP 0 h+++vMirror f r@(Rect (Point x0 y0) s@(Point _ h)) =+ [ m p | p <- f (Rect (Point x0 0) s)]+ where m (Point x y) = Point x (y1-y)+ y1 = y0+h-1+++hMirror f r@(Rect (Point x0 y0) s@(Point w _)) =+ [ m p | p <- f (Rect (Point 0 y0) s)]+ where m (Point x y) = Point (x1-x) y+ x1 = x0+w-1++padFD d (FlexD s fh fv f) = FlexD (s+diag (2*d)) fh fv f'+ where f' (Rect p s) = f (Rect (p+diag d) (s-diag d))
+ hsrc/drawing/Font.hs view
@@ -0,0 +1,194 @@+module Font(CharStruct(CharStruct,char_width,char_rbearing),+ FontStruct(..),FontStructList(..),+ FontStructF(FontStruct,font_id,font_ascent,font_descent,font_prop),+ FontDirection(..), FontProp(..), update_font_id, font_range,+ split_string, string_len, -- string_rect_mono,+ string_rect, string_box_size, string_bounds,+ next_pos, poslist, linespace,fsl2fs) where+import Geometry(Point(..), Rect(..), Size, pP, rR, rectsize, xcoord)+import Xtypes(Atom,FontId)+--import Utils(aboth)+--import HbcUtils(mapFst)+import Data.List(mapAccumL)+import Maptrace(ctrace) -- debugging+import Data.Array+--import qualified Data.Array as LA+--import qualified LA -- GHC bug workaround, can't use LA.!++default(Int)++data CharStruct = CharStruct {char_lbearing, char_rbearing,+ char_width, char_ascent, char_descent :: Int}+ deriving (Eq, Ord, Show, Read)++data FontDirection = FontLeftToRight | FontRightToLeft + deriving (Eq, Ord, Show, Read, Enum)++data FontProp = FontProp Atom Int deriving (Eq, Ord, Show, Read)++-- Only 8-bit characters and 2-byte matrixes. See fsl2fs too!+type FontStruct = FontStructF (Array Char CharStruct)+data FontStructF per_char =+ FontStruct {font_id :: FontId,+ font_dir :: FontDirection,+ first_char, last_char :: Char,+ font_complete :: Bool, -- all chars exist+ default_char :: Char,+ font_prop :: [FontProp],+ max_bounds, min_bounds :: CharStruct,+ per_char :: Maybe per_char,+ font_ascent, font_descent :: Int+ -- ^ logical extent above/below baseline for spacing+ }+ deriving (Eq, Ord, Show, Read)+{-+font_id (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = fid+font_ascent (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = asc+font_descent (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = de+per_char (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = ca+max_bounds (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = maxb+min_bounds (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = minb+font_range (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = (fc,lc)+default_char (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = dc+font_prop (FontStruct fid fd fc lc all' dc fps minb maxb ca asc de) = fps+-}+font_range fs = (first_char fs,last_char fs)++--update_font_id (FontStruct _ fd fc lc all' dc fps minb maxb ca asc de) fid = +-- FontStruct fid fd fc lc all' dc fps minb maxb ca asc de+update_font_id fs fid = fs{font_id=fid}++linespace fs = font_ascent fs + font_descent fs++char_struct default' fs c =+ case per_char fs of+ Nothing -> default' fs+ Just ca -> --ca ! c+ ca ! (if inRange (font_range fs) c -- or: bounds ca+ then -- debugging+ if inRange (bounds ca) c+ then c+ else ctrace "fontrange" (font_range fs,bounds ca,c) (default_char fs)+ else let c' = default_char fs+ in if inRange (bounds ca) c'+ then c'+ else ctrace "fontrange" (font_range fs,"default char",c') ' ')++lbearing fs = char_lbearing . char_struct min_bounds fs+rbearing fs = char_rbearing . char_struct max_bounds fs++poslist :: FontStruct -> String -> [Int]+poslist fs = map (char_width . char_struct max_bounds fs)++next_pos :: FontStruct -> String -> Int+next_pos fs = sum . poslist fs++-- string_bounds gives enclosing rect with respect to first character's origin+string_bounds :: FontStruct -> String -> Rect+string_bounds fs [] = Rect (Point 0 0) (Point 0 0)+string_bounds fs s =+ let cs = char_struct max_bounds fs+ x = lbearing fs (head s)+ y = -(maximum . map (char_ascent . cs)) s+ width = next_pos fs (take (length s - 1) s) + rbearing fs (last s)+ height = (maximum . map (char_descent . cs)) s - y+ in Rect (Point x y) (Point width height)++string_len :: FontStruct -> String -> Int+string_len fs s = (xcoord . rectsize . string_bounds fs) s++string_rect :: FontStruct -> String -> Rect+string_rect fs s =+ rR 0 (-font_ascent fs) (string_len fs s) (linespace fs)++string_box_size :: FontStruct -> String -> Size+string_box_size fs s = pP (next_pos fs s) (linespace fs)++split_string:: FontStruct -> String -> Int -> (String,String,Int)+split_string fs s x =+ -- find the first char that ends to the right of the wanted x position+ case dropWhile (\(_,_,xr)->xr<x) nxs of+ (n,xl,xr):_ ->+ -- xl<=x<=xr, wanted x position is inside the nth character+ if x-xl<xr-x+ then split n -- left edge of nth char is closer+ else split (n+1) -- right edge of nth char is closer+ [] -> (s,[],n) -- x position is after the last char of the string+ where+ split n = case splitAt n s of (s1,s2) -> (s1,s2,n)++ --n=length s, nxs= string & screen positions of all characters in the string+ ((n,_),nxs) = mapAccumL (\(n,x) w -> ((n+1,x+w),(n,x,x+w))) ((0,0)::(Int,Int)) ws++ -- Width of all characters:+ ws = poslist fs s+ ++{- old:+ let dist s' = abs (next_pos font s' - x)+ nearer (pre1, _, _) (pre2, _, _) = dist pre1 <= dist pre2+ better x y = if nearer x y then x else y+ in foldr1 better (allsplits s)++--allsplits s = [(take n s, drop n s, n) | n <- [0 .. length s]])+allsplits [] = [([],[],0)]+allsplits xxs@(x:xs) = ([],xxs,0): map (\(xs,ys,n)->(x:xs,ys,n+1)) (allsplits xs)+-}++--------++-- This is a temporary fix until we know how to construct Haskell arrays from C+type FontStructList = FontStructF [CharStruct]+{-+data FontStructList = FontStructList+ FontId+ FontDirection+ Char -- first character+ Char -- last character+ Bool -- all chars exist+ Char -- default char+ [FontProp]+ CharStruct -- min bounds+ CharStruct -- max bounds+ (Maybe [CharStruct])+ Int -- logical extent above baseline for spacing+ Int -- logical extent below baseline for spacing + deriving (Eq, Ord, Show, Read)+-}++--fontl_prop (FontStructList fid fd fc lc all' dc fps minb maxb ca asc de) = fps+fontl_prop = font_prop++fsl2fs (FontStruct fid fd fc lc all' dc fps minb maxb optclist asc de) =+ FontStruct fid fd fc lc all' dc fps minb maxb optca asc de+ where optca = fmap l2a optclist+ l2a clist = array (fc, lc) (zip ixs clist)+ -- !! This assumes single byte font, or 2 byte matrix font.+ -- !! Linear 16-bit fonts will not work.+ -- ! Using a linear array for a 2 byte matrix font wastes space!+ ixs = [toEnum (256*byte1+byte2) | byte1<-range (min_byte1,max_byte1),+ byte2<-range (min_byte2,max_byte2)]+ (min_byte1,min_byte2) = fromEnum fc `divMod` 256+ (max_byte1,max_byte2) = fromEnum lc `divMod` 256+{-+-- hack to circumvent limitation in generational garbage collector++data Array a b = Arr (a,a) (LA.Array Int (LA.Array Int b))+ deriving (Eq,Ord,Show,Read)++array :: (Ix a, Enum a) => (a,a) -> [(a,b)] -> Array a b+array bds l = Arr bds (LA.listArray (0,dix b2i-dix b1i)+ [LA.array rng (filter (inRange rng.fst) (mapFst fromEnum l))+ | offs <- [b1i,b1i+maxsize..b2i],+ rng <- [(offs,(offs+maxsize-1) `min` b2i)]])+ where (b1i,b2i) = aboth fromEnum bds++(!) :: (Ix a, Enum a) => Array a b -> a -> b+(!) (Arr (b1,b2) a) i = (a `LA.sub` dix (ii-fromEnum b1)) `LA.sub` ii where ii = fromEnum i++bounds :: (Ix a, Enum a) => Array a b -> (a,a)+bounds (Arr bds a) = bds++maxsize = 255+dix i = i `div` maxsize+-}
+ hsrc/drawing/FontProperty.hs view
@@ -0,0 +1,27 @@+module FontProperty (fontProperty) where++import Font(FontProp(..))+import InternAtom(internAtom,atomName)+import Xtypes(Atom(..))++-- The font_prop element of the FontStruct contains a list of FontProp,+-- each containing a pair of Int's: the first is the property name atom number,+-- the secind is the property value atom number. To get a property of a font+-- (which may or may not exist) it is necessary to try to get the atom+-- number for the property name, and, if successful, find out the element+-- of the list containing that number. Then, using the second number +-- in the element found, retrieve the value. If more than one property +-- with the same name is found, only the first will be returned.++fontProperty fsprops propn cont = + let match an' (FontProp an vn) = an' == an+ valatom (FontProp an vn) = vn+ in internAtom propn True $ \pna ->+ case pna of+ Atom 0 -> cont Nothing+ a ->+ case (map valatom (filter (match a) fsprops)) of+ [] -> cont Nothing+ vn:_ -> atomName (Atom (fromIntegral vn)) $ \vna -> cont vna++
+ hsrc/drawing/GCAttrs.hs view
@@ -0,0 +1,277 @@+{-# LANGUAGE CPP #-}+module GCAttrs(module GCAttrs,Cont(..)) where+--import Fudget+--import NullF(F,K)+import FudgetIO+import Xtypes+import EitherUtils(Cont(..))+import Font(FontStruct,font_id,font_range, font_prop, update_font_id)+import Color(tryAllocNamedColor,tryAllocColor)+import LoadFont(listFontsWithInfo,loadFont,loadQueryFont)+import FontProperty(fontProperty)+import CmdLineEnv(argKey)+import Utils(aboth,segments)+--import ListUtil(chopList,breakAt)++#include "exists.h"++data FontData+ = FID FontStruct+ | FS FontStruct++fdFontId (FID fs) = font_id fs+fdFontId (FS fs) = font_id fs++fontdata2struct (FS fs) k = k fs+fontdata2struct (FID fs) k = k fs++--newtype Name = Name String deriving (Eq,Show)+ -- The type Name is used instead of String since String is a type synonym+ -- and therefore can't be made an instance of a class.++#ifdef USE_EXIST_Q+data ColorSpec = EXISTS(a) TSTHACK((Show EQV(a),ColorGen EQV(a)) =>) ColorSpec EQV(a)+ -- deriving Show -- doesn't work because of a HBC bug+instance Show ColorSpec where showsPrec n (ColorSpec c) = showsPrec n c++data FontSpec = EXISTS(a) TSTHACK((Show EQV(a),FontGen EQV(a)) =>) FontSpeci EQV(a)+ -- deriving Show -- doesn't work because of a HBC bug+instance Show FontSpec where showsPrec n (FontSpeci f) = showsPrec n f++colorSpec x = ColorSpec x+fontSpec x = FontSpeci x+#else+data ColorSpec = StringCS ColorName | RGBCS RGB | PixelCS Pixel | ListCS [ColorSpec] deriving (Show)+data FontSpec = StringFS FontName | FontIdFS FontId | FontStructFS FontStruct | ListFS [FontSpec] deriving (Show)+#endif++--data ColorFallback = CF ColorName ColorName++--type GCAttrsSpec = GCAttributes ColorSpec FontSpec++class ColorGen a where+ IFNOEXIST(colorSpec :: a -> ColorSpec)+ tryConvColorK :: FudgetIO f => a -> Cont (f i o) (Maybe Pixel)++ -- Methods with defaults, to be overidden only in the Char instance:+ IFNOEXIST(colorSpecList :: [a] -> ColorSpec)+ convColorListK :: FudgetIO f => [a] -> Cont (f i o) (Maybe Pixel)++ convColorListK = convList tryConvColorK+ IFNOEXIST(colorSpecList = ListCS . map colorSpec)++convColorK c = tryConvColorK c . maybe err+ where err = error ("Can't allocate color: "++show c)++class FontGen a where+ IFNOEXIST(fontSpec :: a -> FontSpec)+ tryConvFontK :: FudgetIO f => a -> Cont (f i o) (Maybe FontData)++ -- Methods with defaults, to be overidden only in the Char instance:+ IFNOEXIST(fontSpecList :: [a] -> FontSpec)+ convFontListK :: FudgetIO f => [a] -> Cont (f i o) (Maybe FontData)++ IFNOEXIST(fontSpecList = ListFS . map fontSpec)+ convFontListK = convList tryConvFontK++convFontK f k = tryConvFontK f $ maybe (tryConvFontK "fixed" $ maybe err k) k+ where err = error ("Can't load font: "++show f)++convList try xs cont = conv xs+ where conv [] = cont Nothing+ conv (x:xs) = try x $ maybe (conv xs) (cont . Just)+++#ifdef USE_EXIST_Q+instance ColorGen ColorSpec where tryConvColorK (ColorSpec c) = tryConvColorK c+instance FontGen FontSpec where tryConvFontK (FontSpeci c) = tryConvFontK c+#else+instance ColorGen ColorSpec where+ colorSpec = id+ tryConvColorK cs =+ case cs of+ StringCS s -> tryConvColorK s+-- NameCS name -> tryConvColorK name+ PixelCS pixel -> tryConvColorK pixel+ RGBCS rgb -> tryConvColorK rgb+-- FallbackCS fb -> tryColorColorK fb+ ListCS cs -> tryConvColorK cs++instance FontGen FontSpec where+ fontSpec = id+ tryConvFontK fs =+ case fs of+-- NameFS (Name name) -> tryConvFontK name k+ StringFS name -> tryConvFontK name+ FontStructFS fstr -> tryConvFontK fstr+ ListFS fs -> tryConvFontK fs+#endif++--instance ColorGen ColorFallback where+-- IFNOEXIST(colorSpec = FallbackCS)+-- convColorK = convColorFallbackK++--convColorFallbackK (CF c1 c2) = allocNamedColorDefPixel defaultColormap c1 c2++instance ColorGen c => ColorGen [c] where+ IFNOEXIST(colorSpec = colorSpecList)+ tryConvColorK = convColorListK++instance FontGen a => FontGen [a] where+ IFNOEXIST(fontSpec = fontSpecList)+ tryConvFontK = convFontListK++-- To be able to allow Strings as color names, we have to make an instance for+-- Char. We actually don't want single Chars to be allowed as color names, but+-- to avoid run-time errors they are allowed (and treated as one-char Strings).+instance ColorGen Char where+ IFNOEXIST(colorSpec c = StringCS [c])+ IFNOEXIST(colorSpecList s = StringCS s)+ tryConvColorK c = convColorListK [c]+ convColorListK s k = tryAllocNamedColor defaultColormap s (k . fmap colorPixel)++-- In the "auto mode":++-- if a font is less than 256 chars, load it as is+-- if a font is monospaced, reuse the FontStruct, inserting+-- a font ID obtained for the font via loadFont (as the font name was returned+-- by listFontsWithInfo, we are safe assuming that it exists)+-- if a font is proportional and large then keep its FID in order+-- to query the server for characters metrics.++getFontData :: FudgetIO f => [Char] -> Cont (f i o) (Maybe FontData)+getFontData =+ case usefontstructs of+ "yes" -> qf+ "no" -> lf+ _ -> autof+ where+ qf fname k = loadQueryFont fname (k . fmap FS)+ lf fname k = + listFontsWithInfo fname 1 $ \ fis ->+ case fis of+ [] -> k Nothing+ (fn,fs):_ -> loadFont fname $ \fid -> k $ Just $ FID $ update_font_id fs fid+ autof fname k =+ listFontsWithInfo fname 1 $ \ fis ->+ case fis of+ [] -> k Nothing+ (fn,fs):_ -> let fprops = font_prop fs+ in fontProperty fprops "SPACING" $ \spacing ->+ fontProperty fprops "FONT" $ \font ->+ if char_count<=256+ then qf fn k+ else let fscons = if (fixed_width font spacing)+ then FS+ else FID+ in loadFont fname $ \fid ->+ k $ Just $ fscons $ update_font_id fs fid+ where+ char_count = hi-lo+ (lo,hi) = aboth fromEnum (font_range fs)++ fixed_width fnt spcng = + let spc = segments (/='-') fn+ spct = segments (/= '-') fnt'+ monosp = ["m", "c", "M", "C"]+ [fnt', spcng'] = map (\s -> case s of+ Just c -> c+ _ -> "\xFF") [fnt, spcng]+ lspc = length spc+ lspct = length spct+ in spcng' `elem` monosp || -- font property tells "monospaced"+ lspct > 11 && (spct !! 11) `elem` monosp || -- from font property if XLFD+ lspc > 11 && (spc !! 11) `elem` monosp || -- from font name if XLFD+ lspc == 1 && (head spc) == "fixed" -- no XLFD, guess by font alias++{--+ fixed_width = spc !! 11 `elem` ["m","c"]+--}+{--+ fixed_width+ | (spacing == (Just c)) = c `elem` monosp+ | ((length spct) > 11) = (spct !! 11) `elem` monosp+ | ((length spc) > 11) = (spc !! 11) `elem` monosp+ | ((length spc) == 1) && ((head spc) == "fixed") = True+ | otherwise = False++ fixed_width = if length spc>11+ then spc !! 11 `elem` ["m","c"]+ else --XFLD is missing, assume proportional, unless+ --the name of the font is "fixed"+ fn=="fixed"++ spc = chopList (breakAt '-') fn+ spct = chopList (breakAt '-') font+ monosp = ["m", "c", "M", "C"]+--}++instance FontGen Char where+ IFNOEXIST(fontSpec c = StringFS [c])+ IFNOEXIST(fontSpecList s = StringFS s)+ tryConvFontK f = convFontListK [f]+ convFontListK = getFontData++--instance ColorGen Name where+-- IFNOEXIST(colorSpec = NameCS)+-- tryConvColorK (Name s) = tryConvColorK s++tryConvColorRGBK rgb k = tryAllocColor defaultColormap rgb (k . fmap colorPixel)++instance ColorGen RGB where+ IFNOEXIST(colorSpec = RGBCS)+ tryConvColorK = tryConvColorRGBK++--instance FontGen Name where+-- IFNOEXIST(fontSpec = NameFS)+-- convFontK (Name s) = safeLoadQueryFont s+ +instance ColorGen Pixel where+ IFNOEXIST(colorSpec = PixelCS)+ tryConvColorK p k = k (Just p)++instance FontGen FontStruct where+ IFNOEXIST(fontSpec = FontStructFS)+ tryConvFontK fs k = k (Just (FS fs))++{--++instance FontGen FontId where+ IFNOEXIST(fontSpec = FontIdFS)+ tryConvFontK fs k = k (Just (FID fs))++--}++--convGCSpecK :: GCSpec -> (GCAttributeList->FontStruct->K i o) -> K i o+convGCSpecK fs attrs = gcattrsK fs attrs []+ where+ gcattrsK fs [] outattrs dr = dr (reverse outattrs) fs+ gcattrsK fs (attr : attrs) outattrs dr =+ let cp attr' = gcattrsK fs attrs (attr' : outattrs) dr+ in case attr of+ GCForeground colspec ->+ convColorK colspec $ \fg ->+ gcattrsK fs attrs (GCForeground fg : outattrs) dr+ GCBackground colspec ->+ convColorK colspec $ \fg ->+ gcattrsK fs attrs (GCBackground fg : outattrs) dr+ GCFont fspec ->+ convFontK fspec $ \fs' ->+ gcattrsK fs' attrs (GCFont (fdFontId fs') : outattrs) dr+ GCFunction f -> cp (GCFunction f)+ GCLineWidth w -> cp (GCLineWidth w)+ GCLineStyle s -> cp (GCLineStyle s)+ GCCapStyle s -> cp (GCCapStyle s)+ GCJoinStyle s -> cp (GCJoinStyle s)+ GCSubwindowMode m -> cp (GCSubwindowMode m)+ GCGraphicsExposures b -> cp (GCGraphicsExposures b)++gcFgA,gcBgA :: c -> [GCAttributes c FontSpec]+gcBgA c = [GCBackground c]+gcFgA c = [GCForeground c]++gcFontA :: f -> [GCAttributes ColorSpec f]+gcFontA f = [GCFont f]+++usefontstructs = argKey "fontstructs" "auto"
+ hsrc/drawing/GCtx.hs view
@@ -0,0 +1,38 @@+module GCtx where+import GCAttrs+import Xtypes+import Gc(createGC)+import Command(Drawable(..))+--import Font(FontStruct)+--import FudgetIO+--import NullF(F,K)+--import Maptrace(ctrace)++data GCtx = GC GCId FontData+ --deriving (Show) -- don't want to see FontStruct+instance Show GCtx where+ showsPrec d (GC gc fs) = ("GC "++) . showsPrec 10 gc . ("<<FontStruct>>"++)++gctx2gc (GC gc _) = gc++rootGCtx = GC rootGC (error "GCtx.rootGCtx0")+-- if usefontstructs then rootGCtx2 else rootGCtx0++--rootGCtx0 = GC rootGC (FID (error "GCtx.rootGCtx0"))+--rootGCtx1 = ...+--rootGCtx2 = GC rootGC (FS (error "GCtx.rootGCtx2"))++data GCSpec -- move to module Drawing?+ = SoftGC [GCAttributes ColorSpec FontSpec]+ | HardGC GCtx+ deriving (Show)++createGCtx drawable gctx@(GC gc fd) gcattrs k =+ --ctrace "gctrace" gc $+ convGCSpecK fd gcattrs $ \ gcattrs' fd' ->+ createGC drawable gc gcattrs' $ \ gc' ->+ --ctrace "gctrace" gc' $+ k (GC gc' fd')++wCreateGCtx x = createGCtx MyWindow $ x+pmCreateGCtx x = createGCtx . Pixmap $ x
+ hsrc/drawing/Gc.hs view
@@ -0,0 +1,26 @@+module Gc(pmCreateGC, wCreateGC, createGC, createGCF, wCreateGCF, pmCreateGCF) where+import Command+import Event+--import FudgetIO+import NullF(F{-,K-})+import Xrequest+import Xtypes+--import Maptrace(ctrace)++createGC drawable template attr =+ let cmd = CreateGC drawable template attr+ expected (GCCreated gc) = {-ctrace "gctrace" gc $-} Just gc+ expected _ = Nothing+ in xrequest cmd expected++--createGCK :: Drawable -> GCId -> GCAttributeList -> (GCId -> K a b) -> K a b+--createGCK = createGC++createGCF :: Drawable -> GCId -> GCAttributeList -> (GCId -> F a b) -> F a b+createGCF = createGC++wCreateGC x = createGC MyWindow x+pmCreateGC x = (createGC . Pixmap) x++wCreateGCF = createGCF MyWindow+pmCreateGCF = createGCF . Pixmap
+ hsrc/drawing/Graphic.hs view
@@ -0,0 +1,51 @@+module Graphic(module Graphic,MeasuredGraphics,emptyMG,emptyMG',GCtx,Cont(..)) where+import Fudget+import FudgetIO+import EitherUtils(Cont(..))+import Cont(conts)+import MeasuredGraphics(MeasuredGraphics(..),measureString,measurePackedString,emptyMG,emptyMG')+import GCtx(GCtx)+import PackedString(PackedString)+import Geometry() -- instance Num Point++class Graphic a where+ measureGraphicK :: FudgetIO k => a -> GCtx -> Cont (k i o) MeasuredGraphics+ measureGraphicListK :: FudgetIO k => [a] -> GCtx -> Cont (k i o) MeasuredGraphics+ -- Default method for lists:+ measureGraphicListK xs gctx cont =+ conts (`measureGraphicK` gctx) xs $ \ mgs ->+ cont (ComposedM mgs)++instance Graphic MeasuredGraphics where+ measureGraphicK cgfx gctx c = c cgfx++instance Graphic Char where+ measureGraphicK c = measureString [c]+ measureGraphicListK = measureString++instance Graphic a => Graphic [a] where+ measureGraphicK = measureGraphicListK++instance (Graphic a,Graphic b) => Graphic (a,b) where+ measureGraphicK (x,y) gctx cont =+ measureGraphicK x gctx $ \ mx ->+ measureGraphicK y gctx $ \ my ->+ cont (ComposedM [mx,my])++measureText x = (measureString.show) x++-- instance Text a => Graphics a where measureGraphicK = measureText+instance Graphic Int where measureGraphicK = measureText+instance Graphic Integer where measureGraphicK = measureText+instance Graphic Bool where measureGraphicK = measureText+instance Graphic Float where measureGraphicK = measureText+instance Graphic Double where measureGraphicK = measureText+instance Graphic PackedString where measureGraphicK = measurePackedString++instance (Graphic a,Graphic b) => Graphic (Either a b) where+ measureGraphicK = either measureGraphicK measureGraphicK++instance Graphic a => Graphic (Maybe a) where+ measureGraphicK = maybe (measureGraphicK (emptyMG 5)) measureGraphicK++--instance Graphic Void
+ hsrc/drawing/Graphic2Pixmap.hs view
@@ -0,0 +1,31 @@+module Graphic2Pixmap(graphic2PixmapImage,PixmapImage(..)) where+import DrawCompiledGraphics(drawK')+import MeasuredGraphics(compileMG)+import Graphic+import PixmapGen+import Pixmap(createPixmap)+import LayoutRequest(minsize)+import XDraw+import ResourceIds(copyFromParent)+import FixedDrawing+import FudgetIO+import NullF() -- instance FudgetIO K++graphic2PixmapImage g gctx cont =+ measureGraphicK g gctx $ \ mg -> convToPixmapK mg cont++measuredGraphics2Pixmap mg cont =+ let (cg,req) = compileMG id mg+ size = minsize req+ in createPixmap size copyFromParent $ \ pm ->+ drawK' (Pixmap pm) (undefined,const []) (const []) cg $+ cont (PixmapImage size pm)++instance PixmapGen MeasuredGraphics where+ convToPixmapK = measuredGraphics2Pixmap++instance PixmapGen FixedColorDrawing where+ convToPixmapK (FixCD size gcdcmds) cont =+ createPixmap size copyFromParent $ \ pm ->+ putLow (pmDrawMany pm gcdcmds) $+ cont (PixmapImage size pm)
+ hsrc/drawing/LoadFont.hs view
@@ -0,0 +1,72 @@+module LoadFont(loadQueryFont, queryFont, loadFont, loadQueryFontF, + queryFontF, loadFontF,safeLoadQueryFont, safeLoadQueryFontF,+ listFonts,listFontsF,listFontsWithInfo,tryLoadFont) where+import Command(XRequest(..))+import Event+import Font(fsl2fs) --FontStruct,FontStructList,+--import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import EitherUtils(stripMaybe,mapMaybe)+import Data.Maybe(fromJust)+import HbcUtils(mapSnd)+import Cont(tryM)+import Xrequest+import Xtypes++lf k fontname =+ let cmd = LoadFont fontname+ expected (FontLoaded fid) = Just fid+ expected _ = Nothing+ in k cmd expected++loadFont x = lf xrequest x+loadFontF = lf xrequestF++qf k fid =+ let cmd = QueryFont fid+ expected (FontQueried fs) = Just (fsl2fs (fromJust fs))+ expected _ = Nothing+ in k cmd expected++queryFont x = qf xrequest x+queryFontF = qf xrequestF++lqf k fontname =+ let cmd = LoadQueryFont fontname+ expected (FontQueried optfs) = Just (fmap fsl2fs optfs)+ expected _ = Nothing+ in k cmd expected++loadQueryFont x = lqf xrequest x+loadQueryFontF = lqf xrequestF++safeLqf lqf fn k =+ tryM (lqf fn)+ (lqf ("fixed"::FontName) $ \ (Just fs) -> k fs)+ k++safeLoadQueryFont x = safeLqf loadQueryFont x+safeLoadQueryFontF = safeLqf loadQueryFontF++lif k pattern maxnames =+ let cmd = ListFonts pattern maxnames+ expected (GotFontList fns) = Just fns+ expected _ = Nothing+ in k cmd expected++listFonts x = lif xrequest x+listFontsF = lif xrequestF++listFontsWithInfo pattern maxnames =+ let cmd = ListFontsWithInfo pattern maxnames+ expected (GotFontListWithInfo fis) = Just (mapSnd fsl2fs fis)+-- expected (GotFontListWithInfo fis) = Just (map ((,) pattern . fsl2fs) fis)+ expected _ = Nothing+ in xrequest cmd expected++-- Since loadFont succeeds and returns a FontId even if the font doesn't exist:+tryLoadFont fn k =+ listFonts fn 1 $ \ fns ->+ case fns of+ fn:_ -> loadFont fn (k . Just)+ _ -> k Nothing
+ hsrc/drawing/Pixmap.hs view
@@ -0,0 +1,30 @@+module Pixmap(bitmapFromData, readBitmapFile, createPixmap) where+import Command+import Event+--import Font(FontStruct)+--import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import LayoutRequest(LayoutRequest)+--import Message(Message(..))+--import Path(Path(..))+import Xrequest+--import Xtypes++createPixmap size depth =+ let cmd = CreatePixmap size depth+ expected (PixmapCreated pixmap) = Just pixmap+ expected _ = Nothing+ in xrequest cmd expected++readBitmapFile name =+ let cmd = ReadBitmapFile name+ expected (BitmapRead b) = Just b+ expected _ = Nothing+ in xrequest cmd expected++bitmapFromData bd =+ let cmd = CreateBitmapFromData bd+ expected (BitmapRead b) = Just b+ expected _ = Nothing+ in xrequest cmd expected+
+ hsrc/drawing/PixmapGen.hs view
@@ -0,0 +1,43 @@+module PixmapGen where+import Graphic+import MeasuredGraphics(MeasuredGraphics(..))+import GCtx(GCtx(..))+--import Command+--import Event+import DrawTypes+import Geometry(Rect(..),Size,origin)+import Xtypes+import FudgetIO+import NullF() -- instances, for hbc+import LayoutRequest(plainLayout)+import Gc+--import EitherUtils(Cont(..))+--import Io(appendChanK)+--import Pixmap(readBitmapFile)+--import Maybe(maybeToList)+--import ContinuationIO(stderr)++data PixmapImage = PixmapImage Size PixmapId++instance Graphic PixmapImage where+ measureGraphicK (PixmapImage size pixmap) (GC gc _) k =+ wCreateGC gc [GCGraphicsExposures False] $ \ gc' ->+ let r = Rect origin size+ ll = plainLayout size True True+ drawit (Rect p _) = [(gc,[CopyArea (Pixmap pixmap) r p])]+ in k (LeafM ll drawit)++---++class PixmapGen a where+ convToPixmapK :: FudgetIO c => a -> Cont (c i o) PixmapImage++measureImageK a gctx k =+ convToPixmapK a $ \ pmi ->+ measureGraphicK pmi gctx k++--This is not allowed in Haskell...+--instance PixmapGen a => Graphic a where measureGraphicsK = measureImageK++instance PixmapGen PixmapImage where+ convToPixmapK pmi k = k pmi
+ hsrc/drawing/TextExtents.hs view
@@ -0,0 +1,12 @@+module TextExtents where+import Xrequest(xrequest)+import Command+import Event++queryTextExtents16K fid str k =+ xrequest cmd expected $ \ (a,d,cs) -> k a d cs+ where+ cmd = QueryTextExtents16 fid str++ expected (TextExtents16Queried a d cs) = Just (a,d,cs)+ expected _ = Nothing
+ hsrc/drawing/TransCoord.hs view
@@ -0,0 +1,23 @@+module TransCoord where+import Command+import Event+import Fudget+import FRequest+import Geometry(Point)+import Xrequest+import Cont(cmdContK)+import Xtypes++getWindowRootPoint :: Cont (K a b) Point+getWindowRootPoint =+ let cmd = TranslateCoordinates+ expected (CoordinatesTranslated p) = Just p+ expected _ = Nothing+ in xrequestK cmd expected+++getWindowId :: Cont (K a b) Window+getWindowId = cmdContK (XCmd GetWindowId)+ (\r->case r of XEvt (YourWindowId w) -> Just w; _ -> Nothing)++-- Why is GetWindowId an XCommand?
+ hsrc/exists.h view
@@ -0,0 +1,33 @@+#if defined(__HBC__) || defined(__GLASGOW_HASKELL__) || defined(__NHC__) || defined(__PFE__)+#define USE_EXIST_Q+#else+#warning No existential types! The type Gfx will be omitted and the function g will be less general.+#endif++#ifdef USE_EXIST_Q+#define IFNOEXIST(e)+#define IFEXIST(e) e+#else+#define IFNOEXIST(e) e+#define IFEXIST(e)+#endif++-- Syntax for existential quantification varies:+#if defined(__HBC__)+#define EQV(x) ?x+#define EXISTS(x) +#elif defined(__GLASGOW_HASKELL__) || defined(__PFE__)+#define EQV(x) x+#define EXISTS(x) forall x .+#else+-- assume any free type variable is existential (like in NHC and old HBC)+#define EQV(x) x+#define EXISTS(x) +#endif+++#ifdef __PFE__+#define TSTHACK(e) e+#else+#define TSTHACK(e) e+#endif
+ hsrc/filters/DoubleClickF.hs view
@@ -0,0 +1,27 @@+module DoubleClickF where+import Fudget+import FRequest+import Xtypes+import Event+--import Font(FontStruct)+import Spops+--import Geometry(Point,Rect,Size(..))+import CompOps((>=..<))++doubleClickF :: Time -> F a b -> F a b+doubleClickF timeout fudget = fudget >=..< doubleClickSP 0 dummy+ where+ dummy = error "bug in DoubleClickF.hs"+ doubleClickSP n last =+ getSP $ \ tev@(path,ev) ->+ case ev of+ XEvt (ButtonEvent t wp rp mods press btn) ->+ if n==0 || press/=Pressed || t>lasttime+timeout ||+ btn/=lastbtn || mods/=lastmods || path/=lastpath+ then putSP tev $ doubleClickSP 1 tev+ else let n' = n+1+ tev' = (path,XEvt (ButtonEvent t wp rp mods (MultiClick n') btn))+ in putSP tev' $ doubleClickSP n' tev'+ where+ (lastpath,XEvt (ButtonEvent lasttime _ _ lastmods _ lastbtn)) = last+ _ -> putSP tev $ doubleClickSP n last
+ hsrc/filters/Filters.hs view
@@ -0,0 +1,15 @@+module Filters (+ -- * Filters+ --module Cache,+ module NewCache,+ module ShapeGroupMgr,module DoubleClickF) where+--import Cache+import NewCache+import ShapeGroupMgr+import DoubleClickF++{-+import Fudget+import Geometry(Rect)+import Xtypes(WindowAttributes,Time(..))+-}
+ hsrc/filters/FocusMgr.hs view
@@ -0,0 +1,179 @@+module FocusMgr(focusMgr) where+import Data.List((\\),sortBy)+import Data.Maybe(listToMaybe)+import Command+--import Direction+import Dlayout(invisibleGroupF)+import Event+--import Font(FontStruct)+import Fudget+import FRequest+--import Geometry(origin) --Line(..), Point(..), Rect(..), Size(..), origin)+--import LayoutRequest(LayoutRequest)+import LoopLow+import HbcUtils(union)+--import Message(Message(..))+import Path+import PathTree hiding (pos)+--import SP+import Spops+import CompSP+import Utils+import CmdLineEnv(argKey,argReadKey)+import WindowF(kernelTag,autumnize)+import Xtypes+--import List2(sort)++import Maptrace++getEventMask [] = Nothing+getEventMask (CWEventMask m : _) = Just m+getEventMask (_ : l) = getEventMask l++setEventMask em [] = [CWEventMask em]+setEventMask em (CWEventMask m : l) = CWEventMask em : l+setEventMask em (wa : l) = wa : setEventMask em l++focusBtn = Button 1+focusMods = [] --rotMods+rotMods = argReadKey "rotmods" [] :: ModState+rotKs = argKey "rotkey" "Tab" :: KeySym++entrymask = [KeyPressMask, EnterWindowMask, LeaveWindowMask]+mask = [KeyPressMask, KeyReleaseMask, EnterWindowMask, LeaveWindowMask]++mkFocusEvent io = io NotifyNonlinearVirtual NotifyNormal++focusMgr sizing ctt f = loopThroughLowF focusK0 igF+ where+ igF = invisibleGroupF sizing [] [CWEventMask mask] f+ focusK0 = prepostMapSP pre post + (focusK' False emptyPathTree False [] mask [] [] []) where+ pre (Left (t,m)) = (t,Left m)+ pre (Right (t,m)) = (t,Right m)+ post (t,Left m) = Left (t,m)+ post (t,Right m) = Right (t,m)++ --focusK' :: PathTree Bool -> Bool -> [(Bool,Path)] -> [EventMask] -> [(Path,(XEvent -> Maybe XEvent))] -> [Path] -> [(Bool,Path)] -> SP (Path,Either Command Event) (Path,Either Command Event) + focusK' focusin mapped inw grab mask tt shellTags etags = same where+ focusK = focusK' focusin mapped+ focusm = focusK inw grab mask tt+ modMapped tag raised = changeFocusc' mapped' id + [(and (spineVals mapped' t),t) | (_,t) <- etags]+ where mapped' = updateNode id True mapped (autumnize tag) (const raised)+ changeFocusc' mapped' c netags = + inw && listToMaybe (mappedtags etags) /= listToMaybe (mappedtags netags)+ `thenC` (leaveFocus etags . enterFocus netags) $ + c $+ focusK' focusin mapped' inw grab mask tt shellTags netags + changeFocusc = changeFocusc' mapped+ changeFocus = changeFocusc id+ rotate ts = case break fst ts of+ (unmapped,[]) -> ts+ (unmapped,t:mapped) -> mapped ++ unmapped ++ [t]+ nexttag = rotate etags+ prevtag = reverse (rotate (reverse etags))+ enterFocus et = putFocus et FocusIn `ifC` inw+ leaveFocus et = putFocus et FocusOut `ifC` inw+ putFocus et f = putFocus' et (mkFocusEvent f)+ mappedtags et = [t |(True,t)<- et]+ putFocus' et ev = case mappedtags et of + [] -> id+ (t:_) -> putSP (t, Right (XEvt ev))+ same = getSP focushandle+ focushandle tmsg@(tag,msg) = case msg of + Left cmd ->+ case cmd of + XCmd xcmd -> case xcmd of+ GrabEvents t -> putSP (tag, Left (XCmd $ GrabEvents (t || stag))) $+ stag `thenC` (leaveFocus etags .+ enterFocus [(True,tag)]) $+ focusK inw ((not stag,tag):grab) + mask tt shellTags etags+ UngrabEvents -> null grab' && inw `thenC` enterFocus etags $+ pass $ focusK inw grab' mask tt shellTags etags+ where grab' = drop 1 grab+ TranslateEvent t tmask -> putSP (kernelTag, + Left (XCmd $ ChangeWindowAttributes [CWEventMask umask])) $+ focusK inw grab umask ((tag,t):tt) shellTags etags + where umask = union mask tmask+ ChangeWindowAttributes cwa | ctt && not ktag && not stag ->+ case getEventMask cwa of+ Just em -> if issubset entrymask em then+ putSP (tag, Left (XCmd $ ChangeWindowAttributes + (setEventMask ((ButtonPressMask:+ em) \\ entrymask) cwa))) $+ null etags `thenC` enterFocus etags' $+ focusm shellTags etags'+ else passame+ where etags' = sortBy (\(_,x) (_,y)-> compare x y)+ ((False,tag):etags)+ Nothing -> passame+ DestroyWindow -> pass $ + -- not (null etags) && not (keep (head etags)) `thenC`+ enterFocus etags' $+ focusK inw grab mask tt' shellTags' (etags' :: [(Bool,Path)])+ where keep = not . subPath tag+ etags' = filter (keep.snd) etags+ shellTags' = filter keep shellTags+ tt' = filter (keep.fst) tt+ MapRaised -> changeMapping tag True+ UnmapWindow -> changeMapping tag False+ _ -> passame+ XReq (CreateMyWindow _) -> changeMapping tag False+ XReq (CreateRootWindow _ _) {- | not ktag -} ->+ pass $ focusm (autumnize tag: shellTags) etags+ XReq (CreateSimpleWindow rchild _) -> + changeMapping (absPath (autumnize tag) rchild) False+ _ -> passame+ where changeMapping tag raised = ctrace "focus1" (raised,tag) $ pass $ modMapped tag raised+ Right (XEvt ev) ->+ if stag then passame+ else case ev of+ ButtonEvent {state=mods,type'=Pressed,button=bno} | ctt && mods == focusMods + && bno == focusBtn && etag -> changeFocusc pass (aft++bef)+ where (bef,aft) = break (flip subPath tag.autumnize.snd) etags+ _ -> case flookup ev tt of+ Just (t,e) -> putSP (t,Right (XEvt e)) same+ Nothing -> if not ctt then passame else + case ev of+ KeyEvent {state=mods,type'=Pressed,keySym=ks} | ks == rotKs && ktag ->+ if (Shift:rotMods) `issubset` mods then changeFocus prevtag+ else if rotMods `issubset` mods then changeFocus nexttag+ else passame+ KeyEvent {} |tag==kernelTag || gtag' -> toFocus same+ EnterNotify {detail=d,focus=True} | tag==kernelTag -> handleEL False d True+ LeaveNotify {detail=d,focus=True} | tag==kernelTag -> handleEL False d False+ FocusIn {detail=d} | tag==kernelTag || gtag' -> handleEL True d True+ FocusOut {detail=d} | tag==kernelTag || gtag' -> handleEL True d False+ _ -> passame+ where toFocus = putFocus' etags ev + handleEL isFocusEv d e = if d == NotifyInferior + || (not isFocusEv && focusin) -- focus events have priority over crossing events+ then passame else+ (case grab of+ (my,t):_ -> if my then if ktag then focusEvToFocus+ else pass+ else if ktag then + putSP (t,Right (XEvt ev))+ else pass+ [] -> if ktag then focusEvToFocus else pass ) $ + focusK' focusin' mapped inw' grab mask tt shellTags etags+ where inw' = if ktag then e else inw+ focusin' = if ktag && isFocusEv then e else focusin+ focusEvToFocus = putFocus etags (if e then FocusIn else FocusOut)+ Right _ -> passame+ where pass = putSP tmsg+ passame = pass same+ ktag = tag == kernelTag || gtag+ stag = inGroup shellTags+ etag = inGroup (map (autumnize.snd) etags)+ gtag = case grab of (_,t):_ -> t == tag; [] -> False+ gtag' = case grab of (True,t):_ -> t == tag; [] -> False -- event grabbed by something in my shell+ inGroup tags = any (flip subPath tag) tags++flookup index' [] = Nothing+flookup index' ((t, p) : table') =+ case p index' of+ Nothing -> flookup index' table'+ Just e -> Just (t, e)
+ hsrc/filters/NewCache.hs view
@@ -0,0 +1,64 @@+module NewCache(allcacheF) where+import Command+--import Event+import FRequest+--import Fudget+--import Loopthrough+import Spops+import LoopLow+import Cont+import IsRequest+--import DialogueIO hiding (IOError)+import qualified Data.Map as OM++--import Maptrace(ctrace) -- debug+--import NonStdTrace(trace)++-- A new implementation of the X resource cache.+-- TODO: reference counters and the ability to free unused resources.++allcacheable xreq =+ case xreq of+ LoadFont fn -> True+ QueryFont f -> True+ LoadQueryFont s -> True+ ListFonts pat max -> True+ ListFontsWithInfo pat max -> True+ CreateGC d t as -> True+ -- FreeGC gcid + AllocNamedColor cm cn -> True+ AllocColor cm rgb -> True+ -- FreeColors cm [pixel] (Pixel 0)+ CreateFontCursor shape -> True+ ReadBitmapFile name -> True+ CreateBitmapFromData bdata -> True -- hmm, big request, small result...+ _ -> False++allcacheF = cacheF allcacheable++cacheF cacheable fud = loopThroughLowF (cc OM.empty) fud where+ cc table = same where+ same = getSP cachehandle+ cachehandle msg = case msg of + Left tc@(tag,c) ->+ case c of+ XReq xreq ->+ if cacheable xreq+ then case OM.lookup xreq table of+ Just r -> putSP (Right (tag,r)) $+ cc table+ Nothing -> waitresp $ \r ->+ --ctrace "trcache" ("alloc",c,d,r) $+ cc (OM.insert xreq r table)+ else waitresp $ \r -> same+ _ -> if isRequest c+ then waitresp $ \r -> same+ else psame+ where waitresp c = cmdContSP (Left tc)+ (\msg->case msg of Right te@(_,e) | isResponse e -> Just te+ _ -> Nothing) $ \tr@(_,r) ->+ putSP (Right tr) $ c r+ Right _ -> psame+ where+ pass = putSP msg+ psame = pass same
+ hsrc/filters/ShapeGroupMgr.hs view
@@ -0,0 +1,75 @@+module ShapeGroupMgr(shapeGroupMgr) where++--import Path+import LoopLow+import Command+--import Event+import Fudget+import FRequest+import Geometry+--import Message(Message(..))+--import NullF+--import Spacers+--import Alignment+import Spops+--import EitherUtils+import Data.Maybe(fromMaybe,mapMaybe)+import Utils+import Xtypes+import WindowF(kernelTag,getBWidth,adjustBorderWidth,border_width)+--import AuxTypes(Ordering(..)) -- HBC bug workaround 960405 TH.+--import Prelude hiding (Ordering)++doConfigure tag wins cws = lookup tag wins >>= \br ->+ let br' = upd br cws + upd br [] = br+ upd br@(bw,r@(Rect (Point x y) (Point w h))) (c:cs) = + upd (case c of+ CWX x' -> (bw,Rect (Point x' y) (Point w h))+ CWY y' -> (bw,Rect (Point x y') (Point w h))+ CWWidth w' -> (bw,Rect (Point x y) (Point w' h))+ CWHeight h' -> (bw,Rect (Point x y) (Point w h'))+ CWBorderWidth bw' -> (bw',r)+ _ -> br) cs+ in if br == br' then Nothing else Just $ replace (tag,br') wins++filterBorderwidth = mapMaybe (\c->case c of CWBorderWidth _ -> Nothing+ _-> Just c)+shapeGroupMgr :: F a b -> F a b+shapeGroupMgr f = loopThroughLowF (sg (border_width,[])) f where+ sg state@(bw,wins) =+ getSP $ \msg -> + let same = sg state+ pass = putSP msg+ passame = pass same + reshape bw wins = shape ShapeBounding bw $+ shape ShapeClip 0 $ sg (bw,wins) where+ shape kind bw =+ putSP (Left (kernelTag,+ XCmd $+ ShapeCombineRectangles + kind+ origin+ (map (adj bw.snd) wins) ShapeSet Unsorted))+ adj bw (lbw,Rect p s) = Rect (p `psub` (Point bw bw))+ (adjustBorderWidth (lbw+bw) s)+ in case msg of+ Left (tag,cmd) -> + case cmd of+ XReq (CreateSimpleWindow stag r) | tag == kernelTag ->+ pass $ sg (bw,(stag,(border_width,r)):wins)+ XCmd (ConfigureWindow cws) | tag == kernelTag ->+ let bw' = fromMaybe bw (getBWidth cws) + cws'= filterBorderwidth cws+ in+ putSP (Left (tag,XCmd (ConfigureWindow cws'))) $+ if bw == bw' then same else reshape bw' wins+ XCmd (ConfigureWindow cws) -> + case doConfigure tag wins cws of+ Nothing -> passame+ Just wins' -> pass $ reshape bw wins'+ XCmd DestroyWindow ->+ pass $ sg (bw,filter ((/=tag).fst) wins)+ _ -> passame+ _ -> passame+
+ hsrc/fudgets/BellF.hs view
@@ -0,0 +1,9 @@+module BellF where+import NullF(getF,putF)+import Command+import Xcommand++bellF = getF $ \ x ->+ xcommandF (Bell 0) $+ putF x $+ bellF
+ hsrc/fudgets/Border3dF.hs view
@@ -0,0 +1,146 @@+module Border3dF(border3dF) where+--import ButtonGroupF+import Color+import Command+import XDraw+import CompOps((>^=<))+import Defaults(bgColor, shadowColor, shineColor,new3d)+--import CmdLineEnv(argFlag)+import Dlayout(groupF)+import Event+import Fudget+--import FudgetIO+import FRequest+import Xcommand+import Gc+import Geometry(Point(..), origin, pP)+import GreyBgF(changeBg)+import LayoutRequest+--import Message(Message(..))+import NullF+import Spacer(marginF)+import EitherUtils(stripEither)+import Utils(swap)+import Xtypes+import GCtx(wCreateGCtx,GCtx(..))+import GCAttrs(gcFgA)++border3dF =+ if new3d+ then newBorder3dF+ else oldBorder3dF+ +newBorder3dF :: Bool -> Int -> F a b -> F (Either Bool a) b+newBorder3dF down edgew f =+ stripEither >^=< ((groupF startcmds kernel . marginF edgew) f)+ where+ startcmds =+ [XCmd $ ChangeWindowAttributes [CWEventMask [ExposureMask],+ CWBitGravity NorthWestGravity]]+ -- bit gravity reduces flicker on resize++ wCreateGC gc0 gcas cont =+ wCreateGCtx (GC gc0 undefined) gcas $ \ (GC gc _) -> cont gc+ gcFg x = wCreateGC rootGC $ gcFgA x+ kernel =+ changeBg bgColor $+ gcFg shineColor $ \ whiteGC ->+ gcFg "black" $ \ blackGC ->+ gcFg [shadowColor,"black"] $ \ shadowGC ->+ let dRAW s pressed =+ let lrc@(Point w h) = s-1+ ulc = 0; llc = pP 0 h; urc = pP w 0+ uli = 1; lli = llc+nw; lri = lrc-1; uri = urc-nw+ nw = pP 1 (-1)+ upper1 = [llc,ulc,urc]+ upper2 = [lli,uli,uri]+ lower1 = [llc,lrc,urc]+ lower2 = [lli,lri,uri]+ in if pressed+ then draw lower1 upper1 upper2+ else draw upper1 lower1 lower2+ drawlines gc ls = (gc,[DrawLines CoordModeOrigin ls])+ draw wls bls dls =+ [ClearWindow,+ DrawMany MyWindow [+ drawlines shadowGC dls,+ drawlines whiteGC wls,+ drawlines blackGC bls]]+ proc pressed size =+ getK $ \bmsg ->+ let same = proc pressed size+ draw = dRAW size+ redraw = draw pressed+ in case bmsg of+ Low (XEvt (Expose _ 0)) -> xcommandsK redraw same+ Low (LEvt (LayoutSize newsize)) | newsize/=size ->+ xcommandsK (dRAW newsize pressed) $ + -- redraw needed here because of bit gravity+ proc pressed newsize+ High change | change/=pressed ->+ xcommandsK (draw change) (proc change size)+ _ -> same+ proc0 pressed =+ getK $ \msg ->+ case msg of+ Low (LEvt (LayoutSize size)) -> proc pressed size+ High change -> proc0 change+ _ -> proc0 pressed+ in proc0 down++oldBorder3dF :: Bool -> Int -> F a b -> F (Either Bool a) b+oldBorder3dF down edgew f =+ stripEither >^=< ((groupF startcmds kernel . marginF edgew) f)+ where+ startcmds =+ [XCmd $ ChangeWindowAttributes [CWEventMask [ExposureMask],+ CWBitGravity NorthWestGravity]]+ -- bitgravity reduces flicker on resize+ kernel =+ changeBg bgColor $+ allocNamedColorPixel defaultColormap shineColor $ \shine ->+ allocNamedColorPixel defaultColormap shadowColor $ \shadow ->+ wCreateGC rootGC [GCFunction GXcopy,+ GCForeground shadow] $ \shadowGC ->+ wCreateGC shadowGC [GCForeground shine] $ \shineGC ->+ let dRAW s pressed =+ let lrc@(Point w h) = s+ e = edgew+ ulc = origin+ urc = pP w 0 -- pP (w - 1) 0+ llc = pP 0 h -- pP 0 (h - 1)+ uli = pP e e+ lli = pP e (h - edgew)+ lri = pP (w - edgew) (h - edgew)+ uri = pP (w - edgew) e+ upper = [ulc, urc, uri, uli, lli, llc]+ lower = [llc, lrc, urc, uri, lri, lli]+ (upperGC, lowerGC) = (if pressed+ then swap+ else id) (shineGC, shadowGC)+ in [ClearWindow,+ DrawMany MyWindow [+ (lowerGC,[FillPolygon Nonconvex CoordModeOrigin lower]),+ (upperGC,[FillPolygon Nonconvex CoordModeOrigin upper])]]+ proc pressed size =+ getK $ \bmsg ->+ let same = proc pressed size+ draw = dRAW size+ redraw = draw pressed+ in case bmsg of+ Low (XEvt (Expose _ 0)) -> xcommandsK redraw same+ Low (LEvt (LayoutSize newsize)) ->+ if newsize==size+ then same+ else xcommandsK (dRAW newsize pressed) $ + -- redraw needed here because of bit gravity+ proc pressed newsize+ High change -> xcommandsK (draw change) (proc change size)+ _ -> same+ proc0 pressed =+ getK $ \msg ->+ case msg of+ Low (LEvt (LayoutSize size)) -> proc pressed size+ High change -> proc0 change+ _ -> proc0 pressed+ in proc0 down
+ hsrc/fudgets/ButtonBorderF.hs view
@@ -0,0 +1,95 @@+module ButtonBorderF(buttonBorderF) where+--import BgF+import Border3dF+--import ButtonGroupF+import Color+import Command(XCommand(ChangeWindowAttributes,ClearArea,DrawMany,Draw))+import XDraw+import CompOps((>^=<))+import Defaults(look3d, shadowColor, shineColor,bgColor)+import Dlayout(groupF)+import Event+import Fudget+--import FudgetIO+import FRequest+import Xcommand+import Gc+import Geometry(Line(..), Point(..), Rect(..), origin, pP, padd, psub)+import LayoutRequest+--import Message(Message(..))+import NullF+import Spacer(marginF)+import EitherUtils(stripEither)+import Xtypes+import GreyBgF(changeBg)++buttonBorderF :: Int -> F a b -> F (Either Bool a) b+buttonBorderF = if look3d then border3dF False else stdButtonBorderF++stdButtonBorderF edgew f =+ let kernel =+ changeBg bgColor $+ allocNamedColorDefPixel defaultColormap shineColor "white" $ \shine->+ allocNamedColorDefPixel defaultColormap shadowColor "black" $ \shadow ->+ wCreateGC rootGC [GCFunction GXcopy, GCForeground shadow,+ GCBackground shine] $ \drawGC ->+ wCreateGC drawGC [GCForeground shine] $ \shineGC ->+ wCreateGC rootGC (invertColorGCattrs shine shadow) $ \invertGC ->+ let bpx = edgew+ bpy = edgew+ upperLeftCorner = Point bpx bpy+ dRAW s = + let size@(Point sx sy) = psub s (Point 1 1)+ rect = Rect origin size+ upperRightCorner = Point (sx - bpx) bpy+ lowerLeftCorner = Point bpx (sy - bpy)+ lowerRightCorner = psub size upperLeftCorner+ leftBorder = Line upperLeftCorner lowerLeftCorner+ upperBorder = Line upperLeftCorner upperRightCorner+ upperLeftLine = Line origin upperLeftCorner+ lowerRightLine = Line lowerRightCorner size+ incx = padd (Point 1 0)+ incy = padd (Point 0 1)+ decx = padd (Point (-1) 0)+ decy = padd (Point 0 (-1))+ lowerBorderPoints = [lowerLeftCorner, lowerRightCorner, + upperRightCorner, Point sx 0, size, Point 0 sy]+ borderPoints =+ [pP 1 1, pP 1 sy, size, pP sx 1, origin, upperLeftCorner, + incy lowerLeftCorner, (incx . incy) lowerRightCorner, + incx upperRightCorner, upperLeftCorner]+ in ( [ClearArea rect False, + DrawMany MyWindow [+ (shineGC,[FillPolygon Nonconvex CoordModeOrigin+ borderPoints]),+ (drawGC,[FillPolygon Nonconvex CoordModeOrigin + lowerBorderPoints, + DrawLine leftBorder, + DrawLine upperBorder, + DrawLine upperLeftLine]), + (invertGC,[DrawLine lowerRightLine]), + (drawGC,[DrawRectangle rect])]], + [Draw MyWindow invertGC $ FillPolygon Nonconvex + CoordModeOrigin borderPoints])+ proc pressed size =+ getK $ \bmsg ->+ let same = proc pressed size+ (drawit_size, pressit_size) = dRAW size+ redraw b = if b == pressed then [] else pressit_size+ in case bmsg of+ Low (XEvt (Expose _ 0)) -> xcommandsK (drawit_size ++ + (if pressed then pressit_size else [])) same+ Low (LEvt (LayoutSize newsize)) -> proc pressed newsize+ High change -> xcommandsK (redraw change) (proc change size)+ _ -> same+ proc0 pressed =+ getK $ \msg ->+ case msg of+ Low (LEvt (LayoutSize size)) -> proc pressed size+ High change -> proc0 change+ _ -> proc0 pressed+ in proc0 False++ startcmds = [XCmd $ ChangeWindowAttributes [CWEventMask [ExposureMask]]]+ in stripEither >^=< ((groupF startcmds kernel . marginF (edgew + 1)) f)+
+ hsrc/fudgets/ButtonF.hs view
@@ -0,0 +1,40 @@+module ButtonF(oldButtonF) where+import CompOps((>^^=<),(>=^<))+--import Defaults(argKey, bgColor, fgColor)+import GraphicsF(graphicsDispF',replaceAllGfx,setGfxEventMask)+import FDefaults+import Sizing(Sizing(..))+import Drawing() -- instance, for hbc+import Graphic()+--import GCAttrs+--import GCtx(wCreateGCtx,rootGCtx)+import DrawingUtils+--import FDefaults+import PushButtonF+--import Placer(spacerF)+import Spacers(marginS,compS)+import Alignment(aCenter)+import CondLayout(alignFixedS')+import SpEither(filterRightSP)+--import Xtypes+--import NullF()+--import FudgetIO()++-- All this just because of the !@?! monomorphism restriction+--import Fudget(F)+--import GraphicsF(GfxEvent)+--import MeasuredGraphics(DPath)+--import DrawingUtils --(Gfx)++oldButtonF halign margin fname bg fg keys lbl =+ filterRightSP >^^=< pushButtonF keys lblF+ where+ --lblF :: Graphic lbl => F lbl (GfxEvent DPath) -- the monorestr+ lblF = let --lblD :: Graphic lbl => lbl -> Drawing a Gfx -- the monorestr+ lblD = spacedD spacer . g+ custom x = setInitDisp (lblD lbl) .+ setGfxEventMask [] . setSizing Static .+ setBorderWidth 0 . setBgColorSpec bg .+ setFont fname . setFgColor fg $ x+ spacer = marginS margin `compS` alignFixedS' halign aCenter+ in graphicsDispF' custom >=^< replaceAllGfx . lblD
+ hsrc/fudgets/ButtonGroupF.hs view
@@ -0,0 +1,121 @@+module ButtonGroupF(+ buttonGroupF, menuButtonGroupF,+ --buttonMachineF,+ BMevents(..))+where+import Command+import CompOps((>=^<))+import Defaults(bgColor)+import Dlayout(groupF)+import Event+import Fudget+import FRequest+import Xcommand+--import Geometry(Line, Point, Rect, Size(..))+import GreyBgF(changeBg)+--import LayoutRequest(LayoutRequest)+import Loops(loopLeftF)+import Message(message) --Message(..),+import NullF+--import SpEither(mapFilterSP)+import Xtypes+import Utils++data BMevents = BMNormal | BMInverted | BMClick deriving (Eq, Ord, Show)++buttonGroupF = buttonGroupF' cmdButton+menuButtonGroupF = buttonGroupF' menuButton []++buttonGroupF' bp keys f = loopLeftF (buttonMachineF' bp keys f >=^< Right)++--buttonMachineF = buttonMachineF' cmdButton++buttonMachineF' bp keys = groupF [] (changeBg bgColor (buttonK bp keys))++data ButtonParams =+ BP { modstate :: ModState,+ mbutton :: Button,+ bmachine :: Button -> ModState -> K Bool BMevents }++elbMask = [EnterWindowMask, LeaveWindowMask, ButtonPressMask, ButtonReleaseMask]++cmdButton =+ BP { modstate = [],+ mbutton = Button 1,+ bmachine = buttonMachine }++menuButton =+ BP { modstate = [],+ mbutton = Button 1, -- not used+ bmachine = mbuttonMachine }++buttonMachine mousebutton modstate =+ setEventMask [] $+ xcommandK (GrabButton False mousebutton modstate grabbedMask) $+ bm BMNormal+ where+ grabbedMask = elbMask+ switch newme = putK (High newme) (bm newme)+ pressed = switch BMInverted+ normal = switch BMNormal+ clicked = putsK [High BMNormal, High BMClick] (bm BMNormal)+ changeMode =+ -- switch to menu button mode+ xcommandK (UngrabButton mousebutton modstate) $+ mbuttonMachine mousebutton modstate+ bm me =+ let nochange = bm me+ in getK $ \msg ->+ case msg of+ Low (XEvt event) ->+ case event of+ (EnterNotify {detail=d}) | d /= NotifyInferior -> pressed+ (LeaveNotify {detail=d}) | d /= NotifyInferior -> normal+ (ButtonEvent {state=s,type'=Pressed,button=b})+ | b == mousebutton && modstate `issubset` s -> pressed+ (ButtonEvent {type'=Released,button=b})+ | b == mousebutton -> if me == BMInverted+ then clicked+ else nochange+ (MenuPopupMode True) -> changeMode+ _ -> nochange+ High True -> changeMode+ _ -> nochange++mbuttonMachine mousebutton modstate =+ setEventMask elbMask $+ loop+ where+ loop = getK $ message low high+ out e = putK (High e) loop+ normal = out BMNormal+ pressed = out BMInverted+ clicked = out BMClick++ low (XEvt ev) = event ev+ low _ = loop+ event (ButtonEvent {type'=Released}) = clicked+ event (EnterNotify {}) = pressed+ event (LeaveNotify {}) = normal+ event (MenuPopupMode False) = buttonMachine mousebutton modstate+ event _ = loop++ high False = buttonMachine mousebutton modstate+ high _ = loop++buttonK :: ButtonParams -> [(ModState, KeySym)] -> K Bool BMevents+buttonK (BP {mbutton=mbutton, modstate=modstate, bmachine=bmachine }) keys =+ xcommandsK initcmds $ bmachine mbutton modstate+ where+ initcmds = transinit ++ [MeButtonMachine]++ transinit =+ if null keys+ then []+ else [TranslateEvent tobutton [KeyPressMask, KeyReleaseMask]]++ tobutton (KeyEvent t p1 p2 s pressed _ ks _) | (s, ks) `elem` keys =+ Just (ButtonEvent t p1 p2 modstate pressed mbutton)+ tobutton _ = Nothing++setEventMask mask = xcommandK (ChangeWindowAttributes [CWEventMask mask])
+ hsrc/fudgets/DButtonF.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE CPP #-}+module DButtonF(+ ButtonF,buttonF,buttonF',buttonF'',setLabel+ ) where+import FDefaults+import ButtonF(oldButtonF)+--import Fudget+--import Geometry(Rect)+import PushButtonF(Click)+import Xtypes+import Defaults(buttonFont,fgColor,bgColor)+import CmdLineEnv(argKeyList)+import CompOps((>^=<),(>=^^<))+--import Spops(concmapSP)+import SpEither(mapFilterSP)--filterRightSP+import EitherUtils(stripEither)+import SerCompF(idRightF)+import Spacers(Distance(..))+import Alignment(aCenter) --,Alignment(..)+import Graphic+import GCAttrs --(ColorSpec,colorSpec) -- + instances++#include "defaults.h"++newtype ButtonF lbl = Pars [Pars lbl]+data Pars lbl+ = FontSpec FontSpec+ | Keys [(ModState, KeySym)]+ | FgColorSpec ColorSpec+ | BgColorSpec ColorSpec+ | Margin Distance+ | Align Alignment+ | Label lbl++parameter_instance1(FontSpec,ButtonF)+parameter_instance1(Keys,ButtonF)+parameter_instance1(FgColorSpec,ButtonF)+parameter_instance1(BgColorSpec,ButtonF)+parameter_instance1(Margin,ButtonF)+parameter_instance1(Align,ButtonF)+parameter(Label)++buttonF s = buttonF' standard s+buttonF' pm s = noPF $ buttonF'' pm s++buttonF'' ::+ Graphic lbl => Customiser (ButtonF lbl) -> lbl -> PF (ButtonF lbl) Click Click+buttonF'' pmod s =+ stripEither >^=<+ idRightF (oldButtonF align marg font bg fg keys lbl >=^^< mapFilterSP relbl)+ where+ lbl = getLabel ps+ font = getFontSpec ps+ keys = getKeys ps+ ps = pmod ps0+ bg = getBgColorSpec ps+ fg = getFgColorSpec ps+ marg = getMargin ps+ align = getAlign ps+ ps0 = Pars [FontSpec (fontSpec buttonFont), Keys [],Margin 2,Align aCenter,+ FgColorSpec buttonfg, BgColorSpec buttonbg, Label s]+ --relbl pmod' = [lbl | let Pars ps'=pmod' (Pars []), Label lbl<-ps']+ relbl pmod' = getLabelMaybe (pmod' (Pars []))++buttonbg = colorSpec (argKeyList "buttonbg" [bgColor,"white"])+buttonfg = colorSpec (argKeyList "buttonfg" [fgColor,"black"])
+ hsrc/fudgets/DDisplayF.hs view
@@ -0,0 +1,200 @@+{-# LANGUAGE CPP #-}+module DDisplayF(--HasInitDisp(..),+ setSpacer,+ DisplayF,+ displayF,displayF',--displayF'',+ intDispF,intDispF',--intDispF'',+ labelF,labelF' --,labelF''+ ) where+import FDefaults+import GraphicsF(graphicsDispF',replaceAllGfx,setGfxEventMask)--GfxCommand+import Graphic+import Drawing() -- instances+import DrawingUtils(spacedD,g)--vboxD,blankD,hardAttribD,+import GCAttrs --(ColorSpec,colorSpec) -- + instances+--import GCtx(GCtx(..),wCreateGCtx,rootGCtx)+--import EitherUtils(mapEither)+--import FudgetIO+--import Fudget+import NullF(F)+--import Xtypes+import ResourceIds() -- synonym ColorName, for hbc+import Defaults(defaultFont,labelFont,paperColor,fgColor,bgColor)+import CmdLineEnv(argKeyList)+import CompOps((>=^^<),(>=^<),(>^^=<))+import CompSP(idLeftSP)+import Spops(nullSP)+import SpEither(filterRightSP)+import Alignment(aRight,aLeft,aCenter)+--import AlignF(noStretchF)+--import LoadFont(safeLoadQueryFont)+--import Font(string_box_size)+import Spacers(marginS,compS,hAlignS)--minSizeS,noStretchS,+import LayoutRequest(Spacer)+import Sizing(Sizing(..))+import CondLayout(alignFixedS')+--import Maybe(fromMaybe)++#include "defaults.h"++newtype DisplayF a = Pars [Pars a]++data Pars a+ = BorderWidth Int+ | FgColorSpec ColorSpec+ | BgColorSpec ColorSpec+ | FontSpec FontSpec+-- | Align Alignment+ | Spacer Spacer+ | Margin Int+ | InitDisp a+ | InitSize a+ | Sizing Sizing+ | Stretchable (Bool,Bool)+-- Don't forget to adjust instance Functor DisplayF above if you add stuff here!++type StringDisplayF = DisplayF String++parameter_instance1(BorderWidth,DisplayF)+parameter_instance1(FgColorSpec,DisplayF)+parameter_instance1(BgColorSpec,DisplayF)+parameter_instance1(FontSpec,DisplayF)+--parameter_instance1(Align,DisplayF)+parameter_instance1(Margin,DisplayF)++parameter_instance(InitDisp,DisplayF)+parameter(Spacer)+parameter_instance(InitSize,DisplayF)+parameter_instance1(Stretchable,DisplayF)+parameter_instance1(Sizing,DisplayF)++-- For backwards compatibility:+instance HasAlign (DisplayF a) where+ setAlign align (Pars ps) = Pars (Spacer (alignFixedS' align aCenter):ps)++labelDisplayF :: Graphic g => F g void -- because of monomorphism restriction+labelDisplayF = labelDisplayF' standard+labelDisplayF' pm = noPF $ labelDisplayF'' pm++labelDisplayF''+ :: Graphic g => Customiser (DisplayF g) -> PF (DisplayF g) g void+labelDisplayF'' pmod = + nullSP >^^=<+ graphicsDispF' custom >=^<+ pre >=^^<+ filterRightSP+ where+ custom =+ maybe id (setInitDisp . draw) initDisp .+ maybe id (setInitSize . draw) initSize .+ setGfxEventMask [] . setSizing sizing .+ setBorderWidth borderWidth . setBgColorSpec bgColor .+ setFont font . setFgColorSpec fgColor .+ setStretchable stretch+ pre = replaceAllGfx . draw + draw = marginD . g+ marginD = spacedD (marginS margin `compS` spacer)++ margin = getMargin ps+ borderWidth = getBorderWidth ps+ bgColor = getBgColorSpec ps+ fgColor = getFgColorSpec ps+ font = getFontSpec ps+ spacer = getSpacer ps+ stretch = getStretchable ps+ sizing = getSizing ps+ initSize = getInitSizeMaybe ps+ initDisp = getInitDispMaybe ps+ ps = pmod (Pars [Margin 4,BorderWidth 0,+ FgColorSpec dispfg, BgColorSpec dispbg,+ FontSpec (fontSpec defaultFont),+ Spacer (alignFixedS' aLeft aCenter),+ Stretchable (False,False),+ Sizing Dynamic{-,InitSize "",InitDisp ""-}])++displayF :: Graphic g => F g void -- because of monomorphism restriction+displayF = displayF' standard+displayF' custom = noPF $ displayF'' custom++displayF'' :: Graphic g => Customiser (DisplayF g) -> PF (DisplayF g) g void+displayF'' pmod = labelDisplayF'' pmod'+ where+ pmod' = pmod .+ --setInitSize "XXXXX" .+ setBorderWidth 1 .+ setStretchable (True,False) .+ setSpacer (hAlignS aLeft) .+ setSizing Growing+++labelF lbl = labelF' standard lbl+labelF' pm = noPF . labelF'' pm++labelF'' :: Graphic g => Customiser (DisplayF g) -> g -> PF (DisplayF g) a b+labelF'' pmod lbl = labelDisplayF'' pmod' >=^^< idLeftSP nullSP+ where+ pmod' = pmod.+ setInitDisp lbl.+ (setFgColor lblfg::(Customiser (DisplayF g))).+ setBgColor lblbg.+ setFont labelFont.+ setMargin 0 .+ setSizing Static++-- cu works around a deficiency in the type inference algorithm.+-- cu x y = id x y :: (Customiser (DisplayF a))++intDispF = intDispF' standard+intDispF' = noPF . intDispF''+intDispF'' :: Customiser (DisplayF Int) -> PF (DisplayF Int) Int a+intDispF'' pm = displayF'' (pm' 0) -- >=^< mapEither id show+ where pm' x = pm.setAlign aRight+ .setInitDisp x+ .setInitSize ((-maxBound) `asTypeOf` x)+-- .forgetInitDisp -- should be built into setInitDisp+ .(setSizing Static::(Customiser (DisplayF Int)))+ .setStretchable (False,False)++dispbg = colorSpec (argKeyList "dispbg" [paperColor,"white"])+dispfg = colorSpec (argKeyList "dispfg" [fgColor,"black"])++lblbg = colorSpec (argKeyList "lblbg" [bgColor,"white"])+lblfg = colorSpec (argKeyList "lblfg" [fgColor,"black"])++{-+forgetInitDisp :: DisplayF a -> DisplayF b+forgetInitDisp (Pars ps) = Pars (forget ps)+ where+ forget ps =+ case ps of+ [] -> []+ BorderWidth i:ps -> BorderWidth i:forget ps+ FgColor c:ps -> FgColor c:forget ps+ BgColor c:ps -> BgColor c:forget ps+ Font f:ps -> Font f:forget ps+ Align a:ps -> Align a:forget ps+ Margin i:ps -> Margin i:forget ps+ InitDisp x:ps -> forget ps+ InitSize s:ps -> InitSize s:forget ps+ Sizing s:ps -> Sizing s:forget ps+ Stretchable bb:ps -> Stretchable bb:forget ps+ +-}++{-+instance Functor DisplayF where+ map f (Pars ps) = Pars (map (mapPars f) ps)+ where+ mapPars f p =+ case p of+ BorderWidth i -> BorderWidth i+ FgColor c -> FgColor c+ BgColor c -> BgColor c+ Font f -> Font f+ Align a -> Align a+ Margin i -> Margin i+ InitDisp x -> InitDisp (f x)+ InitSize s -> InitSize s+ Sizing s -> Sizing s+ Stretchable bb -> Stretchable bb+-}
+ hsrc/fudgets/DRadioF.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE CPP #-}+module DRadioF(+ RadioGroupF,radioGroupF,radioGroupF',+ setPlacer+ ) where+import FDefaults+import RadioF(radioF)+import DToggleButtonF(HasLabelInside(..))+import NullF(F)+import LayoutRequest(Placer)+import Spacers() -- synonym Distance, for hbc+import Placers2(verticalLeftP')+--import Xtypes+import ResourceIds() -- synonym FontName, for hbc+import Defaults(buttonFont)+import Graphic+import GCAttrs --(FontSpec,fontSpec)++#include "defaults.h"++newtype RadioGroupF = Pars [Pars]+data Pars = LabelInside Bool | FontSpec FontSpec | Placer Placer++parameter(Placer)+parameter_instance(LabelInside,RadioGroupF)+parameter_instance(FontSpec,RadioGroupF)++radioGroupF lbl = radioGroupF' standard lbl++radioGroupF' :: (Graphic lbl,Eq alt )=> Customiser RadioGroupF -> [(alt,lbl)] -> alt -> F alt alt+radioGroupF' pmod alts startalt = + radioF placer inside font alts startalt+ where+ placer = getPlacer ps+ inside = getLabelInside ps+ font = getFontSpec ps+ ps = pmod ps0+ ps0 = Pars [LabelInside False,FontSpec (fontSpec buttonFont),Placer placer0]+ placer0 = verticalLeftP' 0
+ hsrc/fudgets/DStringF.hs view
@@ -0,0 +1,44 @@+module DStringF(+ stringF,stringF',--stringF'',+ passwdF,passwdF',passwdF'',+ intF,intF',intF''+ ,stringInputF,intInputF,passwdInputF+ ,stringInputF',intInputF',passwdInputF'+ ) where+import FDefaults+import StringF+--import Fudget+import CompOps+--import Geometry(Rect)+--import Xtypes+--import SpEither(filterRightSP)+import InputMsg(InputMsg,mapInp)+import InputSP(inputDoneSP)--InF(..),+import EitherUtils(mapEither)+import Data.Char(isDigit)++stringInputF = stringInputF' standard+intInputF = intInputF' standard+passwdInputF = passwdInputF' standard+stringInputF' pmod = inputDoneSP >^^=< stringF' pmod+intInputF' pmod = inputDoneSP >^^=< intF' pmod+passwdInputF' pmod = inputDoneSP >^^=< passwdF' pmod++stringF = stringF' standard+stringF' = noPF . stringF''++passwdF = passwdF' standard+passwdF' = noPF . passwdF''+passwdF'' = stringF'' . (.setShowString (map (const '*')))++intF = intF' standard+intF' = noPF . intF''++intF'' :: (Customiser StringF) -> PF StringF Int (InputMsg Int)+intF'' pmod = mapInp read' >^=<+ stringF'' (pmod.pm) >=^<+ mapEither id show+ where+ pm = setAllowedChar isDigit -- . setInitSize "1999999999"+ read' "" = 0+ read' s = read s
+ hsrc/fudgets/DToggleButtonF.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE CPP #-}+module DToggleButtonF(+ HasLabelInside(..),ToggleButtonF,+ toggleButtonF,toggleButtonF' --,toggleButtonF''+ ) where+import FDefaults+import ToggleButtonF(oldToggleButtonF')+import NullF(F)+import Xtypes+import Defaults(buttonFont)+import Graphic+import GCAttrs --(FontSpec,fontSpec) -- + instances++#include "defaults.h"++newtype ToggleButtonF = Pars [Pars]+data Pars = LabelInside Bool | FontSpec FontSpec | Keys [(ModState, KeySym)]++parameter_class(LabelInside,Bool)++parameter_instance(LabelInside,ToggleButtonF)+parameter_instance(FontSpec,ToggleButtonF)+parameter_instance(Keys,ToggleButtonF)++toggleButtonF lbl = toggleButtonF' standard lbl++toggleButtonF' :: (Graphic lbl)=> Customiser ToggleButtonF -> lbl -> F Bool Bool+toggleButtonF' pmod lbl = + oldToggleButtonF' inside font keys lbl+ where+ inside = getLabelInside ps+ font = getFontSpec ps+ keys = getKeys ps+ ps = pmod ps0+ ps0 = Pars [LabelInside False,FontSpec (fontSpec buttonFont), Keys []]
+ hsrc/fudgets/DialogF.hs view
@@ -0,0 +1,133 @@+{-# LANGUAGE CPP #-}+module DialogF(inputPopupOptF, inputPopupF, passwdPopupOptF,+ passwdPopupF, stringPopupOptF, stringPopupF,+ confirmPopupF, ConfirmMsg(..),+ oldConfirmPopupF, oldMessagePopupF,+ messagePopupF) where+import Spacer(marginHVAlignF,marginF)+import Alignment+import PushButtonF(Click(..))+import DButtonF+import FDefaults+import CompOps+import CompSP(preMapSP)+import Defaults(labelFont,bgColor,defaultSep)--buttonFont,fgColor,+import CmdLineEnv(argFlag)+import DDisplayF+import PopupF(popupShellF)+import Fudget+import Geometry(pP)+import Spops+import SpEither(filterJustSP,filterRightSP)+import StringF+import InputF(InF(..))+import InputMsg(ConfirmMsg(..),toConfirm,fromConfirm,InputMsg(..),inputLeaveKey)+--import EitherUtils(isM)+import Data.Maybe(isJust,maybeToList)+--import TextF(textF')+--import ListRequest(replaceAll)+--import NullF(startupF)+import Placer(vBoxF,hBoxF)+import AutoPlacer(autoP')+import Sizing+import Xtypes() -- synonyms, for hbc+import Graphic -- instances (+ class Graphic, because of the monomorphism restr)+import Drawing+import GCAttrs() -- instances++default(Int)++oldMessagePopupF = popupShellF "Message" Nothing (labelabove 50 ok >=^< Left)+oldConfirmPopupF = popupShellF "Confirm" Nothing (labelabove 50 confirm >=^< Left)++-- Grr! Type signatures required because of the mononorphism restriction+confirmPopupF :: Graphic msg => F msg (msg,ConfirmMsg)+messagePopupF :: Graphic msg => F msg (msg,Click)+confirmPopupF = msgPopupF confirm+messagePopupF = msgPopupF ok++msgPopupF buttons =+ popupShellF "Confirm" Nothing+ (filterRightSP>^^=< vBoxF (msgF>+<buttons)>=^<Left . layoutfix)+ where+#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)+ msgF :: Graphic a => F (Drawing lbl a) b+#endif+ msgF = marginHVAlignF 5 aCenter aCenter $ displayF' pm+ where pm = setBgColor [bgColor,"white"] . setSizing Dynamic .+ setFont labelFont . setBorderWidth 0+ layoutfix = PlacedD (autoP' (pP defaultSep 0)) . AtomicD++genStringPopupOptF title inp default' =+ inputPopupOptF title (inp default') (Just default')++genStringPopupF title inp default' =+ filterMaybePairF (genStringPopupOptF title inp default')++stringPopupOptF = genStringPopupOptF "String Entry" oldStringF+stringPopupF default' = filterMaybePairF (stringPopupOptF default')++passwdPopupOptF = genStringPopupOptF "Password Entry" oldPasswdF+passwdPopupF default' = filterMaybePairF (passwdPopupOptF default')++inputPopupOptF :: String -> InF a b -> Maybe b -> F (Maybe String, Maybe a) ((Maybe String, Maybe a), Maybe b)+inputPopupOptF title f default' =+ let stringconfirm =+ (filterDoneSP default' >^^=< vBoxF (f >+< confirm')) >=^< Left+ in popupShellF title+ Nothing+ (marginF 5 ((labelabove 50 stringconfirm >=^^< distPairSP)))++inputPopupF title f def = filterMaybePairF (inputPopupOptF title f def)++button k s = buttonF' (setKeys [([],k)]) s++button' k s =+ if argFlag "okkey" False+ then button k s+ else buttonF s+ -- This is a fix for the problem that when you press return in a+ -- stringPopupF, the next time the popup appears the string in it+ -- isn't selected.++#ifdef __HUGS__+label :: F String a -- for Hugs+#endif+label = displayF' pm+ where pm = setBorderWidth 0 . setBgColor [bgColor,"white"].setFont labelFont++ok = marginHVAlignF 0 aLeft aBottom (button "Return" "OK")+ok' = marginHVAlignF 0 aLeft aBottom (button' "Return" "OK")+cancel = marginHVAlignF 0 aRight aBottom (button "Escape" "Cancel")++confirm = toConfirm >^=< hBoxF (ok >+< cancel) >=^< fromConfirm+confirm' = toConfirm >^=< hBoxF (ok' >+< cancel) >=^< fromConfirm++labelabove len f = filterRightSP >^^=< vBoxF (label >+< f)++filterMaybePairF :: (F a (b, Maybe c)) -> F a (b, c)+filterMaybePairF f = preMapSP filterJustSP liftOpt >^^=< f++liftOpt (x, Nothing) = Nothing+liftOpt (x, Just y) = Just (x, y)++distPairSP = concmapSP (\(x, y) -> otol Left x ++ otol Right y)+ where otol f = maybeToList . fmap f++filterDoneSP =+ let fd s =+ getSP $ \msg ->+ let same = fd s+ in case msg of+ Right Confirm -> if isJust s then putSP s same else same+ Right Cancel -> putSP Nothing same+ Left (InputChange s') -> fd (Just s')+ Left (InputDone k s') | k /= inputLeaveKey -> putSP (Just s') $+ fd (Just s')+ Left _ -> same+ in fd++#ifdef __NHC__+-- nhc bug workaround+blaha=undefined::DisplayF+#endif
+ hsrc/fudgets/Edit.hs view
@@ -0,0 +1,362 @@+{-# LANGUAGE CPP #-}+module Edit(EditStop(..),editF, EditEvt(..), EditCmd(..)) where+import BgF+import Color+import Command+import DrawInWindow+import XDraw(clearArea)+import Defaults(inputFg, inputBg)+import CmdLineEnv(argReadKey, argKey)+import Dlayout(windowF)+import Edtypes+import Editfield+import Event+import Font+import Fudget+import FRequest+import Gc+import Geometry+import LayoutRequest(plainLayout,LayoutResponse(..))+import Message(message) --Message(..),+import NullF+import StateMonads+import Control.Monad(when)+import HbcUtils(apSnd)+import Xtypes+import UndoStack+import TryLayout+import Expose+import Maptrace+import GCAttrs(convFontK,fontdata2struct,FontSpec) -- instances+import InputMsg(InputMsg(InputChange))++default (Int) -- mostly for Hugs++data EditStop = + EditStopFn EditStopFn + | EditPoint Point + | EditLine EDirection++data EditCmd = + EditShowCursor Bool+ | EditMove EditStop IsSelect+ | EditReplace String+ | EditGetText+ | EditGetField+ | EditGetSelection+ | EditUndo+ | EditRedo + +data EditEvt+ = EditText String+ | EditField (String,String,String)+ | EditCursor Rect+ | EditChange (InputMsg String)+ deriving (Eq, Ord)++godir wanted current = if wanted < current then ELeft else ERight++toedstop :: (a ->String->String->(a,Maybe EDirection)) -> a -> EditStopFn+toedstop sf st b a = case sf st b a of+ (_,Nothing) -> EdStop+ (st',Just dir) -> EdGo dir (toedstop sf st')++notnull = not . null++inputbg = argKey "editbg" inputBg+inputfg = argKey "editfg" inputFg++selectbg = argKey "selectbg" inputfg+selectfg = argKey "selectfg" inputbg++editF :: FontSpec -> F EditCmd EditEvt+editF fontspec =+ let eventmask = [ExposureMask]+ startcmds = [XCmd $ ChangeWindowAttributes [CWBitGravity NorthWestGravity,+ CWEventMask eventmask]]+ in windowF startcmds (editK fontspec)++splitwith c [] = (([], False), [])+splitwith c (a : b) =+ if a == c+ then (([], True), b)+ else let ((x, g), y) = splitwith c b+ in ((a : x, g), y)++splitwithnl = splitwith newline+tabstop = 8+untab t s =+ case s of+ '\t':s -> let t' = (t `div` tabstop + 1) * tabstop+ in spaces (t'-t) ++ untab t' s+ c:s -> c:untab (if c == newline then 0 else (t+1)) s+ [] -> []++spaces n = replicate n ' '++editK fontspec = + convFontK fontspec $ \ fd ->+ fontdata2struct fd $ \ font ->+ changeGetBackPixel inputbg $ \bg -> + allocNamedColorPixel defaultColormap inputfg $ \fg -> + allocNamedColorPixel defaultColormap selectbg $ \sbg -> + allocNamedColorPixel defaultColormap selectfg $ \sfg -> + let fid = font_id font+ creategcs fg bg cont =+ wCreateGC rootGC [GCFunction GXcopy, GCFont fid,+ GCForeground fg, GCBackground bg] $ \gc ->+ wCreateGC gc [GCForeground bg, GCBackground fg] $ \igc -> cont (gc,igc)+ in creategcs fg bg $ \drawGCs ->+ creategcs sfg sbg $ \selectGCs ->+ wCreateGC rootGC (invertColorGCattrs bg fg) $ \invertGC -> + let drawimagestring =+ if snd (font_range font) > '\xff'+ then wDrawImageString16+ else wDrawImageString+ getCurp = apSnd (eolx.fst) . getLnoEdge+ getLCurp = getCurp . setFieldDir ELeft+ getRCurp = getCurp . setFieldDir ERight+ npos = next_pos font+ eolx = npos . reverse . fst . splitnl+ maxrmargin x s =+ if null s+ then x+ else let (l,r) = splitnl s+ in ctrace "editF1" (s,l,r,npos l) $ (x + npos l) `max` maxrmargin 0 r+ lno = fst+ xp = snd+ p2line (Point x y) = (y `quot` lheight, x - xoffset)+ line2p (l, x) = Point (x + xoffset) (l * lheight)+ lheight = linespace font+ move issel estop =+ do field <- loadField+ lastpos <- loadLastpos+ invIfShowCursor+ let curp = getCurp field+ stoppoint wantp p@(l, x) bef aft = + let dircomp = godir wantp+ dist p' = abs (lno wantp - lno p') + abs (xp wantp - xp p')+ dir = dircomp p+ ahead = if dir == ELeft then bef else aft+ in case ahead of+ [] -> (p, Nothing)+ c:cs -> let p' = if c == newline+ then (dirint dir + l, if dir == ERight+ then 0+ else eolx cs)+ else (l, x + dirint dir * npos [c])+ in (p', if dir == dircomp p'+ then Just dir+ else if dist p' < dist p+ then Just dir+ else Nothing)+ mf sf = moveField issel field sf+ (field', acc) =+ case estop of+ EditStopFn stopf -> mf stopf+ EditPoint p -> let lp = p2line p+ dir = godir lp curp+ in mf (toedstop (stoppoint lp) curp)+ EditLine dir -> let wantp = (dirint dir + lno curp, xp lastpos)+ in mf (toedstop (stoppoint wantp) curp)+ storeField field'+ let ol = lno curp+ nl = lno $ getCurp field'+ if issel+ then showlines (min ol nl) (max ol nl)+ else if notnull (getSelection field)+ then showSelLines field >> showlines nl nl+ else invIfShowCursor+ showSelLines field = + showlines (lno $ getLCurp field) (lno $ getRCurp field) + setSize (l,x) =+ do old@(ol,ox) <- loadTextWidth+ let new@(_,x') = (l,max x minWidth)+ when (old /= new) $+ do storeTextWidth new+ mtrace ("before trylayout "++show(x,x',ox))+ x <- toMs $ tryLayoutK $+ plainLayout (line2p (l,x') `padd` llmargin) True True+ mtrace "after trylayout"+ storeSize x+ where mtrace x = toMsc (ctrace "editF" x)+ replace' s =+ do field <- loadField+ size <- loadSize+ width <- loadWidth+ let (ll,lx) = getLCurp field+ uts = untab (length $ fst $ splitnl $ getBef field) s+ rl = lno $ getRCurp field+ field' = replaceField field uts+ nls = nlines uts+ nldown = nls - (rl - ll)+ copy src dest h =+ let srcp = line2p src+ r = Rect srcp (pP width h)+ in when (h>0) $+ putLowMs (wCopyArea (fst drawGCs) MyWindow+ r (line2p dest))+ (nlines,tw) <- loadTextWidth+ let changemarg new f = maxrmargin lx (new ++ fst (splitnl (getAft f)))+ oldm = changemarg (getSelection field) field+ newm = changemarg uts field'+ tw' = if newm >= tw+ then newm+ else if oldm < tw+ then tw+ else maxrmargin 0 (getField field')+ ss = (getLastLineNo field' + 1, tw')+ setSize ss+ storeField' field'+ us <- loadUndoStack+ us' <- doit us (field',ss) return+ storeUndoStack us'+ when (nldown /= 0) $+ let tleft a = (rl + a + 1, 0)+ tnl = tleft nldown+ in copy (tleft 0) tnl (ycoord size - lheight * lno tnl)+ showlines ll (ll + nls)+ dolines first last doline = du+ where du s p@(l,x) = let ((line,nl), rest) = splitwithnl s+ in if l > last || null s then return p+ else when (l >= first) (doline p (line,nl)) >> + du rest (if nl then (l+1,0) else (l,x+npos line))+ showLine (gc,rgc) lp (line, withnl) = + do let p = line2p lp+ d = pP 0 (font_ascent font)+ when (xp lp == 0) $+ putLowMs (clearArea (rR 0 (ycoord p) xoffset lheight) False)+ when (notnull line) $+ putLowMs (drawimagestring gc (p+d) line)+ when withnl $+ do width <- loadWidth+ let pc = padd p (pP (npos line) 0)+ size = Point (width - xcoord pc) lheight+ putLowMs (wFillRectangle rgc (Rect pc size))+ showlines first last =+ do field <- loadField+ showc <- loadShowCursor+ let clno = lno $ getLCurp field+ sel = getSelection field+ aft = getAft field+ takenl n s = let (l,r) = splitnl s+ in if n <= 0 then l else l++newline:takenl (n-1) r+ bef = reverse $ takenl (clno-first) $ getBef field+ show gcs = dolines first last (showLine gcs)+ show drawGCs bef (clno-nlines bef,0) >>=+ show (if showc then selectGCs else drawGCs) sel >>=+ show drawGCs (aft++[newline]) >>= \_ ->+ when (clno >= first && clno <= last) invIfShowCursor+ showCursor v = do cv <- loadShowCursor+ when (v /= cv ) $+ do field <- loadField+ storeShowCursor v+ if null (getSelection field) then+ invCursor+ else showSelLines field+ invIfShowCursor = do cv <- loadShowCursor+ when cv invCursor+ invCursor = do field <- loadField+ let lp = getCurp field+ sel = getSelection field+ when (null sel) $+ let p = line2p (apSnd ((-1) +) lp)+ s = pP 1 lheight+ cur = Rect p s+ in putLowMs (wFillRectangle invertGC cur)+ redraw = do --field <- loadField+ size <- loadSize+ putLowMs (clearArea (Rect origin size) True)+ expose r = let Line l1 l2 = rect2line r+ in showlines (lno (p2line l1)) (lno (p2line l2) + 1)+ undoredo d =+ do us <- loadUndoStack+ case d us of+ Nothing -> nopMs+ Just ((field,size),us') -> do storeUndoStack us'+ storeField' field+ setSize size+ redraw++ storeField' field' =+ do storeField field'+ putHighMs (EditChange $ InputChange $ getField field')++ puttext' f = do field <- loadField+ putHighMs (f field)++ puttext f = puttext' (EditText . f)++ putCursor =+ do field <- loadField+ let lastpos = getCurp field+ putHighMs (EditCursor $ Rect (line2p lastpos `psub` Point xoffset 0) + (Point xoffset lheight `padd` llmargin))++ handleLow msg =+ case msg of+ XEvt (Expose r aft) -> toMs (maxExposeK False r aft) >>= expose+ XEvt (GraphicsExpose r aft _ _) -> toMs (maxExposeK True r aft) >>= expose+ LEvt (LayoutSize s) -> storeSize s+ _ -> nopMs++ handleHigh cmd =+ do case cmd of+ EditShowCursor s -> showCursor s+ EditMove estop issel -> move issel estop+ EditReplace s -> replace' s+ EditGetText -> puttext getField+ EditGetField -> puttext' (EditField . getField')+ EditGetSelection -> puttext getSelection+ EditUndo -> undoredo undo+ EditRedo -> undoredo redo+ putCursor+ field <- loadField+ let lastpos = getCurp field+ case cmd of+ EditMove (EditLine _) _ -> nopMs+ _ -> storeLastpos lastpos++ proc = do message handleLow handleHigh =<< getKs+ proc+++ in stateK initstate (setSize (1,0) >> proc) nullK++minWidth = 10+xoffset = 2+llmargin = Point 2 2++defaultuslimit = Nothing+uslimit = let ul = argReadKey "undodepth" (-1)+ in if ul == -1 then defaultuslimit else Just ul++data EditState a = S { shocur :: Bool,+ twidth :: (Int,Int),+ undostack :: UndoStack a,+ field :: EditField,+ size :: Point,+ lastpos :: (Int,Int)+ }++--initstate = (False,(1,0),undoStack uslimit, createField "", origin, (0, 0))+initstate = S False (1,0) (undoStack uslimit) (createField "") origin (0, 0)++loadShowCursor = fieldMs shocur+loadTextWidth = fieldMs twidth+loadUndoStack = fieldMs undostack+loadField = fieldMs field+loadSize = fieldMs size+loadLastpos = fieldMs lastpos+--loadWidth = loadSize >>= \size -> return (xcoord size)+loadWidth = fmap xcoord loadSize+++#define MODMS(lbl) ( \ lbl -> (modMs ( \ s -> s { lbl=lbl } )))++storeShowCursor = MODMS(shocur)+storeTextWidth = MODMS(twidth)+storeUndoStack = MODMS(undostack)+storeField = MODMS(field)+storeSize = MODMS(size)+storeLastpos = MODMS(lastpos)
+ hsrc/fudgets/Editor.hs view
@@ -0,0 +1,214 @@+module Editor(oldEditorF,selectall,loadEditor,setEditorCursorPos) where+import Command+import CompOps((>+<))+import Cont(cmdContK')+import Cursor+import Defaults(menuFont,bgColor,metaKey)--defaultFont+import CmdLineEnv(argReadKey)+import QueryPointer+import TimerF+import Dlayout(groupF)+import Edtypes+import Edit--(EditStopT(..), EditCmd(..), EditEvt(..), IsSelect(..), editF)+import Event+--import Font(FontStruct)+import Fudget+import FRequest+import Geometry() -- instances, for hbc+import LayoutRequest+import Loops(loopCompThroughRightF)+--import Message(Message(..))+import NullF+--import Path(Path(..))+import PopupMenuF+--import SP+import SelectionF+--import Utils(mapList)--loop,+import Xtypes+import Data.Char(isAlpha,toLower,isPrint)+--import Graphic+import InputMsg(InputMsg(..))++default(Int) -- mostly for Hugs++ems = EditMove . EditStopFn+stopafter n dir = ems (sa n) + where sa n b a = if (n::Int) <= 0 then EdStop else EdGo dir (sa (n-1))+stop1 = stopafter 1++ifhd p l = not (null l) && p (head l)+aheadl dir b a = if dir == ELeft then b else a+ifdirhd p dir b a = ifhd p (aheadl dir b a)+stopwhen p dir = ems sw+ where sw b a = if ifdirhd p dir b a then EdStop+ else EdGo dir sw+stopat c = stopwhen (==c)+stopnl = stopat newline++stopborder p dir = ems sw+ where sw b a = if ifdirhd (not . p) dir b a &&+ ifdirhd p dir a b then EdStop+ else EdGo dir sw++stopword = stopborder isAlpha++neverstop = stopwhen (const False)++-- replaceAll is used for TextRequests+loadEditor s = selectall++[EditReplace s]+selectall = [neverstop ELeft False,+ neverstop ERight True]++setEditorCursorPos (row,col) =+ EditMove (EditPoint 0) False :+ concat (replicate (row-1) (down `funmap` False)) +++ [stopafter (col-1) ERight False]++horiz dir meta = stop1 dir : if meta then [stopword dir] else []+left = horiz ELeft+right = horiz ERight+up = [EditMove (EditLine ELeft)]+down = [EditMove (EditLine ERight)]++undo = [const EditUndo]+redo = [const EditRedo]++cursorbindings meta = + [("left", left meta), + ("right",right meta),+ ("up",up),+ ("down",down),+ ("b",left meta),+ ("f",right meta)] ++ctrls = [("e",[stopnl ERight]),+ ("a",[stopnl ELeft]),+ ("p",up),+ ("n",down),+ ("b",left False),+ ("f",right False),+ ("slash",undo),+ ("question",redo)]++selectleft meta = funmap (left meta) True+fl `funmap` x = [f x | f <- fl]+hasMeta mods = metaKey `elem` mods+hasControl mods = Control `elem` mods+cursorkey mods key = flip lookup (if hasControl mods then ctrls + else cursorbindings (hasMeta mods))+ (map toLower key) + >>= \l-> Just (funmap l (Shift `elem` mods))++isEnterKey key = key == "Return" || key == "KP_Enter"+printorenter mods key ascii =+ if hasMeta mods then Nothing+ else if isEnterKey key then+ Just [newline]+ else if key == "Tab" then Just ['\t']+ else if not (hasControl mods) then+ case ascii of+ c : _ | isPrint c -> Just [c]+ _ -> Nothing+ else Nothing+toEdF = High . Left . Right . Right++toSelF = High . Left . Right . Left . Left+toTimerF = High . Left . Right . Left . Right++toOut = High . Right++getEdSel = getEd EditGetSelection+getEdText = getEd EditGetText++getEd ecmd =+ cmdContK' (toEdF ecmd)+ (\e ->+ case e of+ High (Left (Right (Right (EditText t)))) -> Just t+ _ -> Nothing)++getSel =+ cmdContK' (toSelF PasteSel)+ (\e ->+ case e of+ High (Left (Right (Left (Left (SelNotify t))))) -> Just t+ _ -> Nothing)++replace' s = putK (toEdF $EditReplace s)+clearSel = replace' ""+copySel k = getEdSel $ (\s -> putK (toSelF (Sel s)) k)+click issel p = putK (toEdF $ EditMove (EditPoint p) issel)+starttimer = putK (toTimerF $ Just (scrolldel,scrolldel))+stoptimer = putK (toTimerF $ Nothing)+scrolldel = argReadKey "scrolldel" 200++oldEditorF font = loopCompThroughRightF g where+ g = groupF (map XCmd [ChangeWindowAttributes + [CWEventMask [KeyPressMask,EnterWindowMask,LeaveWindowMask]],+ ConfigureWindow [CWBorderWidth 1],+ GrabButton True (Button 1) [Any] + [ButtonPressMask,PointerMotionMask,ButtonReleaseMask]])+ (setFontCursor 152 $ editorK False False)+ (menu ((selectionF >+< timerF) >+< editF font))+ editorK bpressed focus = same where+ same = + getK $ \msg ->+ case msg of+ Low (XEvt event) ->+ case event of+ KeyEvent _ _ _ mods Pressed _ key ascii -> + if hasMeta mods && isEnterKey key+ then putInputDoneMsg key+ else+ case printorenter mods key ascii of+ Just s -> replace' s same+ Nothing -> case cursorkey mods key of+ Just eds -> putsK (map toEdF eds) same+ Nothing -> + if key `elem` ["Delete","BackSpace"] + then getEdSel $ \s -> + (if null s + then putsK (map toEdF + (selectleft (hasMeta mods)))+ else id) $ clearSel same+ else same+ MotionNotify {pos=p,state=mods} -> click True p same+ ButtonEvent {pos=p,state=mods,type'=Pressed,button=Button 1} ->+ starttimer $+ click (Shift `elem` mods) p $ showCursor True focus+ ButtonEvent {type'=Released,button=Button 1} -> + stoptimer $ showCursor False focus+ FocusIn {mode=NotifyNormal} -> showCursor bpressed True+ FocusOut {mode=NotifyNormal} -> showCursor bpressed False+ _ -> same+ High (Left (Right (Left (Right Tick)))) ->+ queryPointerK $ \(_,_,p,_) -> click True p same+ High (Left (Left mencmd)) -> case mencmd of+ MenCut -> copySel $ clearSel same+ MenCopy -> copySel same+ MenPaste -> getSel $ \s ->+ replace' s same+ High (Left (Right (Right ecmd))) -> + (case ecmd of+ EditCursor r -> putK (Low $ LCmd $+ layoutMakeVisible r)+ _ -> id) $+ putK (toOut ecmd) same+ High (Right ocmd) -> putK (toEdF ocmd) same+ _ -> same+ showCursor b f = putK (toEdF (EditShowCursor (b || f))) $ + editorK b f+ putInputDoneMsg key =+ getEdText $ \ s ->+ putK (toOut $ EditChange (InputDone key s)) $+ putsK (map toEdF selectall) $+ same++data MenEvt = MenCut | MenCopy | MenPaste deriving (Eq, Ord)++menu = oldPopupMenuF bgColor True menuFont (Button 3) [] [] + [(MenCut, []), (MenCopy, []), (MenPaste, [])]+ (\x -> case x of+ MenCut -> "Cut"+ MenCopy -> "Copy"+ MenPaste -> "Paste")
+ hsrc/fudgets/Edtypes.hs view
@@ -0,0 +1,12 @@+module Edtypes where++data EDirection = ELeft | ERight deriving (Eq, Ord)+++newline = '\n'++type EditStopFn = String -> String -> EditStopChoice+data EditStopChoice = EdGo EDirection EditStopFn | EdStop+type IsSelect = Bool++
+ hsrc/fudgets/FilePickF.hs view
@@ -0,0 +1,64 @@+module FilePickF(oldFilePickF,smallPickListF) where+import List2(sort)+import MoreF(pickListF)--,PickListRequest(..)+import ListRequest(replaceAll)+import CompOps+--import Defaults(menuFont)+import FilePaths+import IoF(ioF)+import HaskellIO(hIOerr)+import Fudget+import NullF(startupF,getK,putK)--F,K,+--import FudgetIO+import ReadFileF(readDirF)+--import Geometry(Point(..))+import LayoutDir(Orientation(..))+import LayoutOps+--import Spacer(layoutModifierF)+import Loops(loopLeftF)+import SerCompF(bypassF)+import InputMsg(stripInputMsg)--InputMsg(..),+import InputSP(inputLeaveDoneSP)--,inputDoneSP+import InputF(inputThroughF)--,InF(..)+import DStringF(stringF)+import EitherUtils(stripEither)+--import Message(Message(..))+import DialogueIO hiding (IOError)++dirF = aFilePath >^=< bypassF (inputLeaveDoneSP >^^=< stringF) -- startpath ?!!!++shownameF = inputThroughF stringF++startpath = "."++lsF = paths>^=<readDirF>=^<filePath+ where+ paths (dir,resp) =+ case resp of+ Right files -> (map (extendPath sdir) . sort . filter (/=".")) files+ --Left err -> [show err, filePath sdir]+ Left err -> [aFilePath "Error", sdir]+ where sdir = aFilePath dir++smallPickListF f = {-layoutModifierF lf-} (snd.stripInputMsg>^=<pickListF f>=^<replaceAll)+-- where lf (Layout _ fh fv) = Layout (Point 240 120) fh fv++oldFilePickF =+ let showdirF =+ startupF [aFilePath startpath]+ ((compactPath >^=< filePickListF) >==< lsF)+ filePickListF = smallPickListF pathTail+ routeK =+ getK $ \ msg ->+ case msg of+ High p ->+ let s = filePath p+ cont r = putK (High (r s)) routeK+ fileCont = cont Right+ dirCont = cont Left+ checkCont (Str ('d':_)) = dirCont+ checkCont _ = fileCont+ in hIOerr (StatusFile s) (const fileCont) checkCont+ f1 >=#=< f2 = (f1,Below) >#==< f2+ in shownameF >=#=<+ loopLeftF (((ioF routeK >==< showdirF) >=#=< dirF) >=^< stripEither)
+ hsrc/fudgets/GcWarningF.hs view
@@ -0,0 +1,43 @@+-- If you get a type error when compiling this with HBC, try removing -O.+module GcWarningF where+import Dlayout(windowF)+import Command(XCommand(ClearWindow,ChangeWindowAttributes,SetGCWarningHack))+import DrawInPixmap+import LayoutRequest+import Geometry(Rect(..))+import Xtypes+import FudgetIO+import FRequest(layoutRequestCmd)+import Xcommand+import NullF(nullK)+--import ResourceIds+import Pixmap(createPixmap)+import GCtx(GCtx(..),pmCreateGCtx,rootGCtx)+--import GCAttrs+import Defaults(bgColor)++-- Garbage Collection Warning Fudget++gcWarningF = windowF startcmds warnK+ where+ startcmds = [layoutRequestCmd (plainLayout size True True)]++ warnK =+ createPixmap size copyFromParent $ \ gcon ->+ createPixmap size copyFromParent $ \ gcoff ->+ fg gcon [bgColor,"white"] $ \ (GC bg _) ->+ fg gcon ["red","black"] $ \ (GC red _) ->+ putLow (pmFillRectangle gcon bg r) $+ putLow (pmFillRectangle gcoff bg r) $+ putLow (pmFillArc gcon red r 0 (360*64)) $+ xcommandK (SetGCWarningHack gcon gcoff) $+ xcommandK (ChangeWindowAttributes [CWBackPixmap gcoff]) $+ xcommandK ClearWindow $+ nullK+ where+ r = Rect 0 size+ fg pm colspec =+ pmCreateGCtx pm rootGCtx+ ([GCForeground colspec]::[GCAttributes [String] String])++ size = 10
+ hsrc/fudgets/GraphicsF.hs view
@@ -0,0 +1,576 @@+{-# LANGUAGE CPP #-}+module GraphicsF(GraphicsF,setCursorSolid,setGfxEventMask,+ setAdjustSize,setCursor,setDoubleBuffer,+ graphicsF,graphicsF',+ graphicsGroupF,graphicsGroupF',+ graphicsDispGroupF,graphicsDispGroupF',+ graphicsLabelF,graphicsLabelF',+ graphicsDispF,graphicsDispF',+ GfxEventMask(..),GfxChange(..),GfxCommand(..),GfxEvent(..),+ GfxFCmd,GfxFEvent,+ replaceGfx,replaceAllGfx,showGfx,highlightGfx) where+import Fudget+import FudgetIO+import Xcommand+import FRequest+import NullF(putK,putsK,getK,nullF)+import Spops(nullSP)+import CompSP(postMapSP)+import SpEither(filterLeftSP)--mapFilterSP+--import SerCompF(stubF)+import Command+import DrawInPixmap(pmFillRectangle,pmDrawPoint)+--import DrawInWindow(wCopyArea)+import Event+import Xtypes+import Geometry+import Gc+import Pixmap+import Cursor+--import Color+--import Font(font_id,string_box_size)+--import LoadFont(safeLoadQueryFont)+import BgF(changeGetBackPixel)+import Defaults(fgColor,bgColor,paperColor,labelFont)+import CmdLineEnv(argFlag,argKeyList,argReadKey)+import LayoutRequest+import Alignment+import Spacers(noStretchS,compS,minSizeS)+import Message+import CompOps+import CompSP(idRightSP)+import Dlayout(groupF)+import Utils(number,pairwith)+import HbcUtils(mapFst,mapSnd)+--import InputMsg+import Graphic+import CompiledGraphics+import MeasuredGraphics(MeasuredGraphics(SpacedM,MarkM),compileMG,DPath(..))--,emptyMG,emptyMG'+import Graphic2Pixmap+import GCtx(GCtx(..),wCreateGCtx,rootGCtx)+import GCAttrs+import MGOps(parentGctx,replaceMGPart,updateMGPart,groupMGParts,ungroupMGParts)+import IdempotSP+import DrawCompiledGraphics+import Rects(intersectRects,overlaps)+import EitherUtils(stripEither)--,mapEither+import Sizing(newSize,Sizing(..))+--import HO(apSnd)+--import Maybe(fromMaybe)+import Xrequest(xrequestK)+import StdIoUtil(echoStderrK)+--import ContinuationIO(stderr)+--import Maptrace(ctrace) -- debugging++import FDefaults+#include "defaults.h"+#include "exists.h"+-- Commands for grapihcsF: ---------------------------------------------------++data GfxChange gfx+ = GfxReplace (Bool,Maybe gfx)+ | GfxGroup Int Int -- position & length+ | GfxUngroup Int -- position+ +data GfxCommand path gfx+ = ChangeGfx [(path,GfxChange gfx)]+ | ChangeGfxBg ColorSpec+ | ChangeGfxBgPixmap PixmapId Bool -- True = free pixmap+#ifdef USE_EXIST_Q+ | EXISTS(bg) TSTHACK((Graphic EQV(bg)) =>) ChangeGfxBgGfx EQV(bg)+#endif+ | ChangeGfxCursor CursorId+ | ChangeGfxFontCursor Int+ | ShowGfx path (Maybe Alignment,Maybe Alignment) -- makes the selected part visible+ | BellGfx Int -- sound the bell+ | GetGfxPlaces [path] -- ask for rectangles of listed paths++replaceAllGfx = replaceGfx []+replaceGfx path gfx = ChangeGfx [(path,GfxReplace (False,Just gfx))]+showGfx path = ShowGfx path (Nothing,Nothing)+highlightGfx path on = ChangeGfx [(path,GfxReplace (on,Nothing))]++instance Functor GfxChange where+ fmap f (GfxReplace r) = GfxReplace (fmap (fmap f) r)+ fmap f (GfxGroup from count) = GfxGroup from count+ fmap f (GfxUngroup at) = GfxUngroup at++instance Functor (GfxCommand path) where+ fmap f cmd =+ case cmd of+ ChangeGfx changes -> ChangeGfx (mapSnd (fmap f) changes)+ -- _ -> cmd -- Operationally, the rest is the same as this line.+ ChangeGfxBg c -> ChangeGfxBg c+ ChangeGfxBgPixmap pm b -> ChangeGfxBgPixmap pm b+#ifdef USE_EXIST_Q+ ChangeGfxBgGfx gfx -> ChangeGfxBgGfx gfx+#endif+ ChangeGfxCursor cursor -> ChangeGfxCursor cursor+ ChangeGfxFontCursor shape -> ChangeGfxFontCursor shape+ ShowGfx path a -> ShowGfx path a+ BellGfx n -> BellGfx n+ GetGfxPlaces paths -> GetGfxPlaces paths++-- Events from graphicsF: ----------------------------------------------------++data GfxEvent path+ = GfxButtonEvent { gfxTime :: Time,+ gfxState :: ModState,+ gfxType :: Pressed,+ gfxButton:: Button,+ gfxPaths :: [(path,(Point,Rect))] }+ | GfxMotionEvent { gfxTime :: Time,+ gfxState :: ModState,+ gfxPaths :: [(path,(Point,Rect))] }+ | GfxKeyEvent { gfxTime :: Time,+ gfxState::ModState,+ gfxKeySym::KeySym,+ gfxKeyLookup::KeyLookup }+ | GfxFocusEvent { gfxHasFocus :: Bool }+ | GfxPlaces [Rect] -- response to GetGfxPlaces+ | GfxResized Size+ deriving (Eq,Show)+++-- graphicsF event masks: ----------------------------------------------------++data GfxEventMask = GfxButtonMask | GfxMotionMask | GfxDragMask | GfxKeyMask++allGfxEvents = [GfxButtonMask, GfxMotionMask, GfxDragMask, GfxKeyMask]+gfxMouseMask = [GfxButtonMask, GfxDragMask] -- backward compat++gfxEventMask = concatMap events+ where+ events GfxButtonMask = buttonmask+ events GfxMotionMask = motionmask+ events GfxDragMask = dragmask+ events GfxKeyMask = keventmask++ buttonmask = [ButtonPressMask,ButtonReleaseMask]+ motionmask = [PointerMotionMask]+ dragmask = [Button1MotionMask]+ keventmask =+ [KeyPressMask,+ EnterWindowMask, LeaveWindowMask -- because of CTT implementation+ ]++-- Customisers for graphicsF: ------------------------------------------------++newtype GraphicsF gfx = Pars [Pars gfx]++data Pars gfx+ -- Standard customisers:+ = BorderWidth Int+ | BgColorSpec ColorSpec+ | FgColorSpec ColorSpec+ | FontSpec FontSpec+ | Sizing Sizing+ | Stretchable (Bool,Bool)+ | InitSize gfx+ | InitDisp gfx+ -- Special customisers:+ | CursorSolid Bool+ | GfxEventMask [GfxEventMask]+ | AdjustSize Bool+ | Cursor Int -- pointer cursor shape for XCreateFontCursor+ | DoubleBuffer Bool+-- Could also support:+-- | Align Alignment+-- | Spacer Spacer+-- | Margin Int++parameter_instance1(BorderWidth,GraphicsF)+parameter_instance1(BgColorSpec,GraphicsF)+parameter_instance1(FgColorSpec,GraphicsF)+parameter_instance1(Sizing,GraphicsF)+parameter_instance1(FontSpec,GraphicsF)+parameter_instance1(Stretchable,GraphicsF)+parameter_instance(InitSize,GraphicsF)+parameter_instance(InitDisp,GraphicsF)+parameter(CursorSolid)+parameter(GfxEventMask)+parameter(AdjustSize)+parameter(Cursor)+parameter(DoubleBuffer)++-------------------------------------------------------------------------------++type GfxFCmd a = GfxCommand DPath a+type GfxFEvent = GfxEvent DPath++graphicsDispF :: Graphic a => F (GfxFCmd a) (GfxFEvent)+graphicsDispF = graphicsDispF' standard++graphicsLabelF lbl = graphicsLabelF' standard lbl++graphicsLabelF' customiser gfx = nullSP >^^=< d >=^^< nullSP'+ where d = graphicsF' (customiser . params)+ params = setInitDisp gfx .setGfxEventMask [] . setSizing Static .+ setBgColor bgColor . setBorderWidth 0+ nullSP' = nullSP -- :: (SP anything (GfxCommand MeasuredGraphics))+ -- this is a workaround necessary to resolve the overloading++graphicsDispF' :: Graphic gfx => Customiser (GraphicsF gfx) -> F (GfxFCmd gfx) (GfxFEvent)+graphicsDispF' customiser = graphicsF' (customiser . dispCustomiser)+graphicsDispGroupF fud = graphicsGroupF' dispCustomiser fud+graphicsDispGroupF' customiser fud =+ graphicsGroupF' (customiser . dispCustomiser) fud++dispCustomiser =+ setCursorSolid True . setGfxEventMask gfxMouseMask . setSizing Growing++graphicsF :: Graphic gfx => F (GfxFCmd gfx) (GfxFEvent)+graphicsF = graphicsF' standard++graphicsF' custom = filterLeftSP >^^=< graphicsGroupF' custom nullF >=^< Left++graphicsGroupF :: Graphic gfx => F i o -> F (Either (GfxFCmd gfx) i) (Either (GfxFEvent) o)+graphicsGroupF = graphicsGroupF' standard++--graphicsGroupF' :: (Graphic init,Graphic gfx => Customiser (GraphicsF init) -> F i o -> F (Either (GfxFCmd gfx) i) (Either (GfxFEvent) o)+graphicsGroupF' :: Graphic gfx => Customiser (GraphicsF gfx) -> F i o -> F (Either (GfxFCmd gfx) i) (Either (GfxFEvent) o)+graphicsGroupF' customiser fud = + let solid = getCursorSolid params+ mask = getGfxEventMask params+ sizing = getSizing params+ adjsize = getAdjustSize params+ doublebuffer = getDoubleBuffer params+ optcursor = getCursorMaybe params+ font = getFontSpec params+ bw = getBorderWidth params+ bgcol = getBgColorSpec params+ fgcol = getFgColorSpec params+ optx = getInitDispMaybe params+ optstretch = getStretchableMaybe params+ optinitsize = getInitSizeMaybe params+ params = customiser defaults+ defaults = Pars [BorderWidth 1,+ BgColorSpec (colorSpec paperColor),+ FgColorSpec (colorSpec fgColor),+ Sizing Dynamic,+ CursorSolid False,+ GfxEventMask allGfxEvents,+ AdjustSize True,+ DoubleBuffer defaultdoublebuffer,+ FontSpec (fontSpec labelFont)]+ eventmask = ExposureMask:+ gfxEventMask mask+ --grabmask = [ButtonReleaseMask, PointerMotionMask]+ -- NOTE: some code below assumes that motion events occur ONLY+ -- while Button1 is pressed!+ startcmds = [ChangeWindowAttributes [CWEventMask eventmask,+ CWBitGravity NorthWestGravity],+ ConfigureWindow [CWBorderWidth bw]--,+ --GrabButton False (Button 1) [] grabmask,+ --GrabButton False (Button 2) [] [ButtonReleaseMask]+ ]+ in --compMsgSP layoutOptSP (idRightSP idempotSP) `serCompSP`+ idRightSP (stripEither `postMapSP` idRightSP idempotSP) >^^=<+ groupF (fmap XCmd startcmds)+ (initK doublebuffer font optcursor fgcol bgcol $+ graphicsK0 solid sizing adjsize optstretch optinitsize optx)+ fud++dbeSwapBuffers cont =+ xrequestK (DbeSwapBuffers swapaction) Just $ \ (DbeBuffersSwapped _) -> cont++optDoubleBufferK False cont = cont Nothing+optDoubleBufferK True cont =+ xrequestK DbeQueryExtension Just $ \ (DbeExtensionQueried status major minor) ->+ let ok=status/=0+ in if not ok+ then echoStderrK "Sorry, double buffering not available." $+ cont Nothing+ else xrequestK (DbeAllocateBackBufferName swapaction) Just $ \ (DbeBackBufferNameAllocated backbuf) ->+ --xcommandK ClearWindow $+ cont (Just backbuf)++initK doublebuffer font optcursor fgcol bgcol k =+ changeGetBackPixel bgcol $ \ bg ->+ maybe id setFontCursor optcursor $+ convColorK [fgcol,colorSpec "black"] $ \ fg ->+ wCreateGCtx rootGCtx [GCFont [font,fontSpec "fixed"],GCForeground fg,GCBackground bg] $ \ gctx@(GC gc _) ->+ wCreateGC rootGC [GCForeground bg] $ \ cleargc ->+ createCursorGC gc bg fg $ \ higc ->+ optDoubleBufferK doublebuffer $ \ optbackbuf ->+ k optbackbuf gctx bg cleargc higc++optCompileGraphicK gctx optgfx cont =+ case optgfx of+ Nothing -> cont Nothing+ Just gfx ->+ measureGraphicK gfx gctx $ \ mg ->+ cont (Just (mg,compileMG id mg))++graphicsK0 solid sizing adjsize optstretch optinitsize optx optbackbuf gctx bg cleargc higc =+ graphicsK1 + where+ graphicsK1 =+ optCompileGraphicK gctx optinitsize $ \ optcgsize ->+ optCompileGraphicK gctx optx $ \ optcgx ->+ graphicsK2 optcgsize optcgx+ graphicsK2 optcgsize optcgx =+ graphicsK init+ where+ optSizeS = fmap (minSizeS . minsize . snd . snd) optcgsize+ optStretchS = fmap stretchS optstretch+ where stretchS (sh,sv) = noStretchS (not sh) (not sv)+ spacerM =+ case (optStretchS,optSizeS) of+ (Just stretchS,Just sizeS) -> SpacedM (stretchS `compS` sizeS)+ (Just stretchS,_ ) -> SpacedM stretchS+ (_ ,Just sizeS) -> SpacedM sizeS+ _ -> MarkM gctx++ -- All incoming and outgoing paths have to be adjusted because of+ -- the extra spacer. The functions pathIn & pathOut handle this.+ init = pairwith (compileMG id) $ spacerM $ maybe (emptyMG 10) fst optcgx+ -- Stretchiness is applied to all drawings as it should be, but+ -- optinitsize should be applied only to the first drawing!!!+ + pathIn path = 0:path+ -- pathOut (0:path) = path++ -- locatePointOut p = mapFst pathOut . locatePoint p+ locatePointOut p (CGMark cg) = locatePoint p cg+ -- bug if top node isn't a CGMark !!++ graphicsK (mg,(cg,req)) =+ putLayoutReq req $+ idleK cleargc req mg cg solid []++ idleK cleargc req mg cg active es =+ seq size $ -- prevents a space leak when sizing==Dynamic, TH 980724+ getK $ message lowK highK+ where+ size = minsize req -- == current window size most of the time+ curR = hiR (solid||active)+ same = idleK cleargc req mg cg active es+ newcleargc cleargc' = idleK cleargc' req mg cg active es++ optInsertNew mg cg gctx path optreq optnew k =+ case optnew of+ Nothing -> k mg cg optreq+ Just new -> measureGraphicK new gctx $ \ newmg ->+ let mg' = replaceMGPart mg path newmg+ (cg',req) = compileMG (newSize sizing size) mg'+ in k mg' cg' (Just req)++ updGraphicsK mg cg optreq [] c =+ case optreq of+ Just req' | not (similar req' req)+ -> --ctrace "updgfx" (show (req,req')) $+ putLayoutReq req' $ c req' mg cg False+ _ -> c req mg cg True+ updGraphicsK mg cg optreq ((path,change):changes) c =+ case change of+ GfxReplace r -> replace r+ GfxGroup from count -> group from count+ GfxUngroup pos -> ungroup pos+ where+ replace (hi,optnew) =+ optInsertNew mg cg (parentGctx gctx mg path) path optreq optnew $ \ mg' cg' optreq' ->+ let cg'' = case (hi,optnew) of+ (False,Nothing) -> cgupdate cg' path removecursor+ (True,_) -> cgupdate cg' path addcursor+ _ -> cg'+ in updGraphicsK mg' cg'' optreq' changes c++ group from count = updGraphicsK mg' cg' optreq changes c+ where mg' = updateMGPart mg path (groupMGParts from count)+ cg' = cgupdate cg path (cgGroup from count)++ ungroup pos = updGraphicsK mg' cg' optreq changes c+ where mg' = updateMGPart mg path (ungroupMGParts pos)+ cg' = cgupdate cg path (cgUngroup pos)++ bufDrawChangesK = maybe drawChangesK backBufDrawChangesK optbackbuf+ bufDrawK = maybe drawK backBufDrawK optbackbuf++ backBufDrawChangesK backbuf beQuick cur new old changes cont =+ drawChangesK' (Just (DbeBackBuffer backbuf,cleargc)) False cur new old changes $+ dbeSwapBuffers $+ cont+ backBufDrawK backbuf cur clip cg cont =+ drawK' (DbeBackBuffer backbuf) cur clip cg $+ dbeSwapBuffers $+ --putLow (wCopyArea gc (DbeBackBuffer backbuf) (Rect 0 size) 0) $+ cont+ where (GC gc _) = gctx++ buttonEvent t p state type' button =+ -- High level output tagged Left is sent through idempotSP+ putHigh (Left $+ GfxButtonEvent t state type' button (locatePointOut p cg)) $+ same+ motionEvent t p state =+ -- High level output tagged Left is sent through idempotSP+ putHigh (Left $ GfxMotionEvent t state (locatePointOut p cg)) $+ same+ key t mods sym lookup =+ putHigh (Right $ GfxKeyEvent t mods sym lookup) $ same++ highK (ShowGfx path align) = mkPathVisible cg (pathIn path) align same+ highK (BellGfx n) = xcommandK (Bell n) same++ highK (GetGfxPlaces paths) =+ putHigh (Right $ GfxPlaces $ fmap (cgrect . cgpart cg . pathIn) paths) $+ same+ highK (ChangeGfxBg bgspec) =+ convColorK bgspec $ \ bgcol ->+ xcommandK (ChangeWindowAttributes [CWBackPixel bgcol]) $+ xcommandK clearWindowExpose $+ wCreateGC rootGC [GCForeground bgcol] $ \ cleargc' ->+ -- FreeGC cleargc+ newcleargc cleargc'+ highK (ChangeGfxBgPixmap pixmap freeIt) =+ xcommandK (ChangeWindowAttributes [CWBackPixmap pixmap]) $+ xcommandK clearWindowExpose $+ wCreateGC rootGC [GCFillStyle FillTiled,GCTile pixmap] $ \ cleargc' ->+ -- FreeGC cleargc+ (if freeIt then xcommandK (FreePixmap pixmap) else id) $+ newcleargc cleargc'+#ifdef USE_EXIST_Q+ highK (ChangeGfxBgGfx gfx) =+ graphic2PixmapImage gfx gctx $ \ (PixmapImage size pm) ->+ highK (ChangeGfxBgPixmap pm True)+#endif+ highK (ChangeGfxCursor cursor) =+ defineCursor cursor $+ xcommandK Flush $+ same+ highK (ChangeGfxFontCursor shape) =+ setFontCursor shape $+ xcommandK Flush $+ same+ highK (ChangeGfx changes0) =+ updGraphicsK mg cg Nothing changes $ \ req' mg' cg' beQuick ->+ bufDrawChangesK beQuick (higc,curR) cg' cg (fmap fst changes) $+ --mkChangeVisible cg' changes $+ idleK cleargc req' mg' cg' active []+ where changes = mapFst pathIn changes0++ changeActive active' =+ if active'==active+ then same+ else putHigh (Left $ GfxFocusEvent { gfxHasFocus=active' }) $+ bufDrawChangesK True (higc,hiR (solid||active')) cg cg (cursorPaths cg) $+ idleK cleargc req mg cg active' es++ lowK (XEvt e) = eventK e+ lowK (LEvt lresp) = layoutK lresp+ lowK _ = same++ layoutK lresp =+ case lresp of+ LayoutSize size'+ | adjsize ->+ if size' == size then same+ else let cg'' = foldr restorecursor cg' (cgcursors cg)+ where+ restorecursor path cg = cgupdate cg path addcursor+ (cg',_) = compileMG (const size') mg+ in putHigh (Left $ GfxResized size') $+ bufDrawChangesK True (higc,curR) cg'' cg [] $+ idleK cleargc req' mg cg'' active es+ | otherwise -> idleK cleargc req' mg cg active es+ where req' = mapLayoutSize (const size') req+ _ -> same++ eventK event =+ case event of+ Expose r 0 ->+ let rs = r:es+ in bufDrawK (higc,curR) (intersectRects rs) (prune rs cg) $+ idleK cleargc req mg cg active []+ Expose r _ -> idleK cleargc req mg cg active (r:es)+ FocusIn {} -> changeActive True+ FocusOut {} -> changeActive False++ ButtonEvent {time=t, pos=pos, type'=type', button=button, state=state} ->+ buttonEvent t pos state type' button+ MotionNotify {time=t,pos=pos,state=state} -> motionEvent t pos state+ KeyEvent t _ _ mods Pressed _ sym lookup -> key t mods sym lookup+ _ -> same++prune rs (CGMark cg) = CGMark (prune rs cg)+prune rs (CGraphics r cur cmds cgs) =+ if any (overlaps r) rs+ then if null cmds -- || all (null.snd) cmds+ then CGraphics r cur cmds (fmap (prune rs) cgs)+ else CGraphics r cur cmds cgs+ -- cmds may overlap with cgs, so+ -- if cmds are redrawn then all cgs should be redrawn too.+ else CGraphics r cur [] [] -- subtree rectangles are inside parent rectangles.++{-+locatePoint' p cg = fmap addrect $ locatePoint p cg+ where+ addrect = pairwith (cgrect . cgpart cg)+-}++locatePoint p (CGMark cg) = [(0:path,geom)|(path,geom)<-locatePoint p cg]+ -- ^^ the wrong geometry will be return if CGMark came from a SpacerM !!+locatePoint p (CGraphics r _ _ gs) =+ if p `inRect` r+ then let ps = fmap (locatePoint p) gs+ in case [ (i:path,pr) | (i,paths)<-number 1 ps, (path,pr)<-paths] of+ [] -> [([],(p-rectpos r,r))]+ ps -> ps+ else []++cursorPaths (CGMark cg) = fmap (0:) (cursorPaths cg)+cursorPaths (CGraphics _ cur _ gs) =+ if cur+ then [[]]+ else [i:p | (i,g)<-number 1 gs, p<-cursorPaths g]++hiR True = solidCursorRects+hiR False = hollowCursorRects++solidCursorRects r = [r]++hollowCursorRects (Rect (Point x y) (Point w h)) =+ [rR x y w lw,rR x y lw h,rR x (y+h-lw) w lw,rR (x+w-lw) y lw h]+ where lw=minimum [2,w,h]++--putSize cg = putLayoutReq (Layout (cgsize cg) False False)++mkChangeVisible cg changes =+ case [ path | (path,(True,_))<-changes] of+ path:_ -> mkPathVisible cg path (Nothing,Nothing)+ _ -> id++mkPathVisible cg path align =+ putLayout (lMkVis (cgrect (cgpart cg path)))+ where+ lMkVis r = LayoutMakeVisible (r `growrect` 5) align+ -- growrect compensates for a layout bug !!++putLayoutReq = putLayout . LayoutRequest+--putSpacer = putLayout . LayoutSpacer+putLayout = putK . Low . LCmd++createCursorGC gc bg fg cont =+ --allocNamedColorDefPixel defaultColormap cursorcolor "white" $ \ hipix ->+ tryConvColorK cursorcolor $ \ opthipix ->+ let hipix = fromMaybe fg opthipix+ in if hipix/=bg && hipix/=fg && not mono+ then wCreateGC gc [GCForeground hipix] $ \ cursorgc ->+ cont cursorgc+ else createPixmap (Point 2 2) copyFromParent $ \ pm ->+ wCreateGC gc [GCForeground bg] $ \ cleargc ->+ putsK [Low $ pmFillRectangle pm cleargc (rR 0 0 2 2),+ Low $ pmDrawPoint pm gc 0] $+ wCreateGC gc [GCFillStyle FillTiled,GCTile pm] $ \ cursorgc ->+ cont cursorgc++similar l1 l2 =+ minsize l1==minsize l2 &&+ fixedh l1==fixedh l2 &&+ fixedv l1==fixedv l2++cursorcolor = argKeyList "cursor" ["yellow"]+mono = argFlag "mono" False+defaultdoublebuffer = argFlag "doublebuffer" False+swapaction = argReadKey "swapaction" DbeCopied
+ hsrc/fudgets/GuiElems.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE CPP #-}+module GuiElems (+ -- * GUI elements+ -- ** Buttons+ module DButtonF, module DRadioF, module DToggleButtonF,+ module Border3dF,module ButtonBorderF,+ module ButtonF,module ButtonGroupF,+ module PushButtonF,module QuitButtonF,+ module QuitF,module RadioF,+ module ToggleButtonF,module ToggleGroupF,+ -- ** Graphics+ module GraphicsF,+ module HyperGraphicsF,+ -- ** Menus+ module MenuButtonF,module MenuF,module MenuPopupF,+ -- ** Popups+ module DialogF,+ module PopupMenuF,+ module FilePickF,+ -- ** Text elements+ module LabelF,+ module DDisplayF,module DStringF,+ module MoreF, module MoreFileF,+ module StringF, module TextF,+ module TerminalF,+ -- ** Special indicators+ module OnOffDispF,+ module GcWarningF,+ module BellF,+ -- ** Editors+ module Edit,module Editor,module Edtypes,module InputEditorF+ ) where+import Border3dF+import ButtonBorderF+import ButtonF+import ButtonGroupF+import DialogF+import Edit+import Editor+import Edtypes+import InputEditorF+import FilePickF+import GraphicsF+import HyperGraphicsF+import LabelF+import MenuButtonF+import MenuF+import MenuPopupF+import TextF+import MoreF+import MoreFileF+import PopupMenuF+import PushButtonF+import QuitButtonF+import QuitF+import RadioF+import StringF+import TerminalF+import ToggleGroupF+import ToggleButtonF+import OnOffDispF+import DButtonF+import DToggleButtonF+import DRadioF+import DDisplayF+import DStringF+import GcWarningF+import BellF++#ifdef __NHC__+import FDefaults -- Needed re-export instances for these classes+#endif
+ hsrc/fudgets/HyperGraphicsF.hs view
@@ -0,0 +1,76 @@+module HyperGraphicsF where+--import Fudget+--import Defaults(paperColor)+--import InputMsg(inputDone)+import Utils(swap)+--import Xtypes(ColorName)+import Loops(loopThroughRightF)+import SerCompF(mapstateF)+--import Graphic+import Drawing+import DrawingOps+import GraphicsF+import FDefaults+import HbcUtils(assoc)+import Sizing(Sizing(..))+--import GCAttrs() -- instances+import Event(Pressed(..))+--import Maptrace(ctrace) -- debugging+--import SpyF(teeF) -- debugging+--import CompOps((>==<)) -- debugging++hyperGraphicsF x = hyperGraphicsF' standard x++{-+hyperGraphicsF' :: (Eq annot,Graphic g) =>+ Customiser (GraphicsF (Drawing annot g)) ->+ Drawing annot g ->+ F (Either (Drawing annot g) (annot,Drawing annot g))+ annot+-}+hyperGraphicsF' custom init =+ loopThroughRightF+ (mapstateF ctrl state0)+ ({-teeF show "\n" >==<-} graphicsDispF' (custom . params))+ where+ --tr x = ctrace "hyper" (show x) x -- debugging+ params = setInitDisp init .+ setGfxEventMask [GfxButtonMask] .+ setSizing Dynamic+ state0 = (annotPaths init,init)++ ctrl state@(paths,drawing) = either input output+ where+ same = (state,[])+ output = either new newpart+ where+ --new d = newpart' d []+ -- avoid space leak for this common case:+ new d = ((annotPaths d,d),[Left (replaceAllGfx d)])+ newpart (a,d) = assoc (newpart' d) same paths a+ newpart' d path = ((paths',drawing'),[Left (replaceGfx path d)])+ where drawing' = replacePart drawing path d+ paths' = annotPaths drawing'+ -- Space leak: drawing' isn't used until user clicks+ -- in the window, so the old drawing is retained in+ -- the closure for drawing'++ input msg =+ case msg of+ GfxButtonEvent { gfxType=Pressed, gfxPaths=gfxPaths } -> mouse gfxPaths+ _ -> same+ where+ lblPart = maybeDrawingPart drawing . drawingAnnotPart drawing . fst+ mouse paths =+ --ctrace "hyper" (show paths) $+ case [lbl|Just (LabelD lbl _)<-map lblPart (reverse paths)] of+ lbl:_ -> (state,[Right lbl])+{- -- All nodes have unique paths now, so this should not be necessary:+ Just d ->+ case annotChildren d of+ ([],LabelD a _):_ -> (state,[Right a])+ _ -> same+-}+ _ -> same++ annotPaths = map swap . drawingAnnots
+ hsrc/fudgets/InputEditorF.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE CPP #-}+module InputEditorF(+ EditorF,+ inputEditorF,inputEditorF',+ editorF,editorF')+ where+import Editor(oldEditorF,loadEditor)+import Edit(EditEvt(..))+--import InputMsg(InputMsg(..))+import CompOps+import SpEither(mapFilterSP)+import Spops(concatMapSP)+import ResourceIds() -- synonym FontName, for hbc+import GCAttrs --(FontSpec,fontSpec)+import Defaults(defaultFont)+import FDefaults++#include "defaults.h"++inputEditorF = inputEditorF' standard++inputEditorF' pm =+ mapFilterSP change >^^=< editorF' pm >=^^< concatMapSP loadEditor+ where+ change (EditChange inputmsg) = Just inputmsg+ change _ = Nothing++editorF = editorF' standard++editorF' customiser = oldEditorF font+ where+ font = fromMaybe (fontSpec defaultFont) $ getFontSpecMaybe ps+ ps = (customiser::(Customiser EditorF)) (Pars [])++newtype EditorF = Pars [Pars]++data Pars+ = FontSpec FontSpec++parameter_instance(FontSpec,EditorF)
+ hsrc/fudgets/LabelF.hs view
@@ -0,0 +1,28 @@+module LabelF(labRightOfF, labLeftOfF, labBelowF, labAboveF, tieLabelF) where+import Spacer(noStretchF,marginHVAlignF)+import Alignment+import CompOps((>=^<), (>^=<))+import DDisplayF(labelF)+--import Fudget+--import Geometry+import LayoutDir(Orientation(..))+import LayoutOps+import EitherUtils(stripEither)+--import Xtypes++--tieLabelF :: Orientation -> Alignment -> String -> F a b -> F a b+tieLabelF orient align text fudget =+ let disp = labelF text+ fv = orient == Above || orient == Below+ fh = not fv+ lblF = noStretchF fh fv (marginHVAlignF 0 align align disp)+ in (stripEither >^=< ((lblF,orient) >#+< fudget)) >=^< Right+++labF orient = tieLabelF orient aCenter+labAboveF x = labF Above x+labBelowF x = labF Below x+labLeftOfF x = labF LeftOf x+labRightOfF x = labF RightOf x++-- eta expanded because of monomorphism restriction
+ hsrc/fudgets/MenuButtonF.hs view
@@ -0,0 +1,44 @@+module MenuButtonF(menuButtonF,menuLabelF) where+import ButtonGroupF+import CompOps((>^^=<),(>=^<))+import SpEither(filterRightSP)+import SerCompF(idRightF)+import Defaults(inputFg,inputBg)+--import EitherUtils(stripEither)+import PushButtonF(Click(..))+import ResourceIds(FontName(..))--ColorName(..),+import Spacers(sepS)+import GraphicsF+import FDefaults+import DrawingUtils(g,boxD,spacedD)--fgD,fontD,+import Graphic+import Drawing(DPath)+import Geometry(pP)+import Fudget+import Sizing(Sizing(..))+import GCAttrs()++menuButtonF :: Graphic lbl => FontName -> lbl -> F lbl Click+menuButtonF fname label =+ filterRightSP >^^=< menuButtonGroupF (idRightF lblF >=^< prep)+ where+ lblF = menuLabelF fname label+ toDisp = Left+ through = Right+ prep (Left BMNormal) = toDisp (Left False)+ prep (Left BMInverted) = toDisp (Left True)+ prep (Left BMClick) = through Click+ prep (Right e) = toDisp (Right e)++menuLabelF :: Graphic lbl => FontName -> lbl -> F (Either Bool lbl) (GfxEvent DPath)+menuLabelF fname label =+ lblF >=^< pre+ where+ lblF = graphicsDispF' custom+ custom = setBgColor inputBg . setInitDisp (lblD label) .+ setGfxEventMask [] . setSizing Dynamic . setBorderWidth 0 .+ setFgColor inputFg . setFont fname+ lblD label = boxD [spacedD (sepS (pP 3 1)) $ g label]++ pre (Left highlight) = highlightGfx [] highlight+ pre (Right label') = replaceAllGfx (lblD label')
+ hsrc/fudgets/MenuF.hs view
@@ -0,0 +1,254 @@+module MenuF(simpleMenuF, menuAltsF, menuF, oldMenuF, buttonMenuF, buttonMenuF', grabberF, MenuState,menuDown,EqSnd(..),fstEqSnd,sndEqSnd,toEqSnd) where+import Command+import Event+import Geometry(pP,Point(..),Size,inRect,Rect(..))+import Message(message )--Message(..),+import Fudget+import FRequest+import FudgetIO+import StreamProcIO+import Xcommand+import NullF+import CompOps((>^=<), (>=^<), (>=^^<), (>^^=<),(>+<))+import Dlayout(groupF)+import SerCompF(bypassF)--,idRightF+import Loops(loopCompThroughRightF)+import LayoutDir(LayoutDir(..))+import LayoutF(listLF)+import LayoutRequest(LayoutResponse(..))+import Placers+import Spacers() -- synonym Distance, for hbc+import MenuButtonF+import MenuPopupF+import Spops(nullSP)+import MapstateK+import SpEither(filterRightSP)+import EitherUtils(mapEither)--stripEither+import Xtypes+import Defaults(menuFont)+import CmdLineEnv(argFlag)+import Graphic+import Data.Array+--import DialogueIO hiding (IOError)+import ShowCommandF(showCommandF)+import Debug.Trace(trace)++data EqSnd a b = EqSnd a b++instance (Eq b) => Eq (EqSnd a b) where+ EqSnd a1 b1 == EqSnd a2 b2 = b1 == b2++fstEqSnd (EqSnd a b) = a+sndEqSnd (EqSnd a b) = b+toEqSnd x = map (uncurry EqSnd) x++menuF :: (Graphic mlbl,Graphic albl) => mlbl -> [(alt,albl)] -> F alt alt+menuF name altlbls =+ bypassF ((nalts!) . sndEqSnd >^=< + simpleMenuF menuFont name lblns fstEqSnd >=^^< nullSP)+ where+ (alts,lbls) = unzip altlbls+ lblns = zipWith EqSnd lbls ixs+ n = length alts+ ixs = [1 .. n]+ nalts = array (1,n) (zip ixs alts)+++simpleMenuF fname name = oldMenuF fname name . map (\x -> (x,[]))++oldMenuF :: (Graphic c, Eq b, Graphic a) => FontName -> a -> [(b, [(ModState, KeySym)])] -> (b -> c) -> F a b +oldMenuF fname name alts show_alt =+ grabberF [] (buttonMenuF Horizontal fname name alts menuAlts>=^<mapEither id Left)+ where+ menuAlts = menuAltsF' fname (map fst alts) show_alt >=^^< filterRightSP++menuAltsF' fname alts show_alt =+ fst >^=< listLF (verticalP' 0) (map altButton alts)+ where+ altButton (alt{-, keys-}) = (alt, menuButtonF fname {-keys-} (show_alt alt))++menuAltsF fname alts show_alt =+ menuPopupF (menuAltsF' fname alts show_alt) >=^< Left++grabberF alts mF = loopCompThroughRightF (groupF startcmds grabK0 mF)+ where+ startcmds = map XCmd transinit+ grabK0 = grabK False++ transinit =+ if null keys+ then []+ else [TranslateEvent tobutton [KeyPressMask, KeyReleaseMask]]+ where+ keys = concatMap snd alts+ tobutton e@(KeyEvent {state=s,keySym=ks}) | (s, ks) `elem` keys = Just e+ tobutton _ = Nothing+ grabK up = getK $ message low high+ where+ keyalts = [(k,a)|(a,ks)<-alts,k<-ks]+ same = grabK up+ popdown = grabK False+ popup = grabK True+ low event =+ case event of+ XEvt (KeyEvent {state=s,keySym=ks,type'=Pressed}) ->+ puts [Left (Right alt)|(key,alt)<-keyalts,(s,ks)==key] same+ _ -> same+ high = either fromLoop fromOutside+ fromLoop = either menuCoordination menuSelection+ fromOutside x = putHigh (Left (Right x)) same+ menuSelection x = putHigh (Right x) same+ menuCoordination newState =+ case (up,newState) of+ (False,MenuUp _) ->+ --trace "grabberF: GrabEvents False" $+ xcommandK (GrabEvents False) popup+ (True,MenuDown) ->+ --trace "grabberF: UngrabEvents" $+ xcommandK UngrabEvents popdown+ _ -> same++data MenuState = MenuDown | MenuUp MenuMode deriving (Show)+type MenuMode = Bool -- True = sticky+menuDown = MenuDown+menuUpSticky = MenuUp True+menuUpMPopup = MenuUp False+-- Invariant: menu state never changes directly from MenuDown to menuUpSticky,+-- i.e., when a menu first pops up, it always outputs menuUpMPopup++data ButtonMenuState =+ S { mpopup,othermpopup,sticky,debug::Bool, size::Size } deriving (Show)+bstate0 = S False False False False 0++{-+buttonMenuF :: (Graphic a) =>+ LayoutDir -> FontName -> a ->+ [(b, [(ModState, KeySym)])] ->+ F (Either MenuState b) b ->+ F (Either MenuState (Either a b)) (Either MenuState b)+-}+buttonMenuF x = buttonMenuF' False x+buttonMenuF' delayed dir fname name alts menuAltsF =+ loopCompThroughRightF $+ showCommandF "buttonMenuF" $+ groupF startcmds+ (mapstateK proc bstate0)+ (filterRightSP >^^=< (menuLabelF fname name >+< theMenuF))+ where+ theMenuF = menuPopupF' delayed menuAltsF+ topopup = High . Left . Right . Left+ tosubmenus = High . Left . Right . Right . Left+ inputtosubmenus = High . Left . Right . Right . Right+ out = High . Right . Right+ othermenu = High . Right . Left+ toDisp = High . Left . Left+ relabel = toDisp . Right+ adjust =+ case dir of+ Vertical -> \ (Point w _) -> pP w (-1)+ Horizontal -> \ (Point _ h) -> pP (-1) h+ proc state@(S{mpopup=mpopup,othermpopup=othermpopup,sticky=sticky,size=size,debug=debug}) =+ message low high+ where+ dbg x = if debug then trace ("buttonMenuF "++x) else id++ popdownyield = popdown' True [] --pop down because other menu popped up+ popdownlast = -- pop down, no other menu is up+ dbg "popdownlast" $+ popdown' False [othermenu MenuDown]+ popdown' mpopup' msgs =+ (state{othermpopup=mpopup'},+ msgs++[tosubmenus menuDown,topopup PopdownMenu])++ stickyMode =+ dbg "othermenu menuUpSticky" $+ (state{sticky=True},+ [othermenu menuUpSticky,topopup PopupMenuStick])++ mPopupMode b = (state{mpopup=b},[])+ highlight = toDisp . Left+ put msgs = (state,msgs)++ high = either fromMenu (either fromOtherMenu fromOutside)+ fromOutside = either newLabel altInput+ newLabel lbl = (state,[relabel lbl])+ altInput x = (state,[inputtosubmenus x])++ fromOtherMenu newMode =+ dbg ("fromOtherMenu "++show newMode) $+ case newMode of+ MenuUp False -> popdownyield -- other menu popped up, pop down+ MenuUp True -> (state{othermpopup=False},[])+ MenuDown -> popdown' False []++ fromMenu alt =+ (state{sticky=False},+ [tosubmenus menuDown,othermenu menuDown,out alt])+ low resp =+ dbg (unlines [show state, show resp,""]) $+ case resp of+ XEvt event ->+ case event of+ ButtonEvent {button=Button 2,type'=Pressed,state=mods} ->+ trace "Button 2" $+ (state{debug=Control `elem` mods},[])+ --ButtonEvent _ winpos rootpos mods Pressed (Button 1) ->+ ButtonEvent {pos=winpos,rootPos=rootpos,state=mods,type'=Pressed,button=Button 1} ->+ dbg "output othermenu True" $+ (state{sticky=False},+ [othermenu menuUpMPopup, -- tell other menus to pop down+ topopup (PopupMenu (rootpos-winpos+adjust size) event)+ --highlight True,+ --Low (GrabEvents False)+ ])+ LeaveNotify {mode=NotifyUngrab,detail=NotifyInferior}+ | stickyMenus && not mpopup -> stickyMode+ LeaveNotify {mode=NotifyUngrab} {- | not sticky-} -> popdownlast+ -- ^^ these events get lost in focusMgr it seems+ ButtonEvent {pos=pos,button=Button 1,type'=Released}+ | not (stickyMenus && pos `inRect` (Rect 0 size)) -> popdownlast+ --workaround+ LeaveNotify {detail=detail}+ | detail/=NotifyInferior ->+ if False --mpopup+ then popdownlast+ else put [highlight False]+ EnterNotify {rootPos=rootpos,pos=winpos,mode=NotifyNormal}+ | mpopup || othermpopup ->+ dbg "output othermenu True" $+ (state{sticky=False},+ [othermenu menuUpMPopup, -- tell other menus to pop down+ topopup (PopupMenu (rootpos-winpos+adjust size) event),+ highlight True])+ | otherwise -> put [highlight True]+ KeyEvent {state=s,type'=Pressed,keySym=ks} ->+ case [ a | (a,keys) <- alts, (s,ks) `elem` keys] of+ a:_ -> put [out a]+ _ -> error "MenuF.clickF bug"+ MenuPopupMode b -> mPopupMode b+ _ -> (state,[])+ LEvt (LayoutSize size') -> (state{size=size'},[])+ _ -> (state,[])++ startcmds = map XCmd (MeButtonMachine : grab +++ [ConfigureWindow [CWBorderWidth 1],+ ChangeWindowAttributes wattrs] +++ transinit)+ grab = [GrabButton True (Button 1) [] ptrmask]+ ptrmask = [ButtonPressMask, ButtonReleaseMask]+ wattrs = [CWEventMask eventmask]+ eventmask = [LeaveWindowMask, EnterWindowMask,+ ButtonPressMask -- Button 2 press, for debuggin only!+ ]++ keys = concatMap snd alts++ transinit =+ if null keys+ then []+ else [TranslateEvent tobutton [KeyPressMask, KeyReleaseMask]]+ where+ tobutton e@(KeyEvent {state=s,keySym=ks}) | (s, ks) `elem` keys = Just e+ tobutton _ = Nothing++stickyMenus = argFlag "stickymenus" False
+ hsrc/fudgets/MenuPopupF.hs view
@@ -0,0 +1,117 @@+module MenuPopupF(PopupMenu(..), menuPopupF, menuPopupF') where+import Command+import Cursor+import Shells(unmappedShellF')+import FDefaults() -- synonym Customiser, for hbc+import DShellF(setFocusMgr)+import Event+import Fudget+import FRequest+import Geometry(Point)+import Loops(loopCompThroughRightF,loopThroughRightF)+--import Message(Message(..))+import CompSP(prepostMapSP)+import SerCompF(mapstateF)+import NullF+import Xtypes+import Data.List(union)++data PopupMenu+ = PopupMenu Point XEvent -- Time to pop up the menu.+ | PopupMenuStick -- The mouse button has been released, but stay up.+ | PopdownMenu -- Time to hide the menu.+ deriving Show+ --deriving (Eq, Ord)++menuPopupF = menuPopupF' False++menuPopupF' delayed menu =+ loopCompThroughRightF (dF $ unmappedShellF' pm startcmds popupShellK menu')+ where+ dF = if delayed then delayF else id+ pm = setFocusMgr False+ menu' = handleButtonMachinesF menu+ startcmds = [XCmd $ ChangeWindowAttributes wattrs,+ XCmd $ ConfigureWindow [CWBorderWidth 1]]+ wattrs = [CWEventMask [], CWSaveUnder True, CWOverrideRedirect True]++popupShellK =+ setFontCursor 110 downK+ where+ mouse (ButtonEvent {}) = True+ mouse (EnterNotify {}) = True+ mouse _ = False+ samekey (KeyEvent {keySym=ks}) ks' = ks == ks'+ samekey _ _ = False++ toMenu = High . Left . Right+ toBms = High . Left . Left+ out = High . Right++ popdown = map (Low . XCmd) [UnmapWindow]+ popup p = toBms True:map (Low . XCmd) [moveWindow p, MapRaised]++ downK =+ getK $ \msg ->+ case msg of+ High (Right (Left (PopupMenu p ev))) -> putsK (popup p) $ upK ev+ High (Right (Right x)) -> putK (toMenu x) $ downK+ High (Left x) -> putK (out x) $ downK+ _ -> downK++ upK ev =+ getK $ \msg ->+ case msg of+ High (Right (Left (PopupMenu p ev))) -> putsK (popup p) $ upK ev+ High (Right (Left PopdownMenu)) -> putsK popdown $ downK+ High (Right (Left PopupMenuStick)) -> putK (toBms False) $ upK ev+ High (Right (Right x)) -> putK (toMenu x) $ upK ev+ High (Left x) ->+ if mouse ev+ then putsK (out x : popdown) $ downK+ else putK (out x) $ upK ev+ Low (XEvt (KeyEvent {type'=Released, keySym=ks})) ->+ if samekey ev ks+ then putsK popdown downK+ else upK ev+ _ -> upK ev++{- handleButtonMachineF fud records the paths of all button machines in fud, so+ that a message can be broadcast to them when the MenuPopup mode changes.+ It also keeps track of the current mode to avoid sending the same mode twice.+-}++handleButtonMachinesF fud =+ loopThroughRightF ctrlF (liftbm fud)+ where+ ctrlF = mapstateF ctrl (False,[])++ ctrl state@(mode,bms) = either fromLoop fromOutside+ where+ fromLoop (Left path) = addbm path+ fromLoop (Right y) = out y++ fromOutside (Left mode') = changeMode mode'+ fromOutside (Right x) = inp x++ addbm path = ((mode,[path] `union` bms),[Left (Left (path,mode))])+ -- Tell the new button the current mode. (Needed in case it is+ -- dynamically created inside a menu.)+ out y = (state,[Right y])+ inp x = (state,[Left (Right x)])++ changeMode mode' =+ if mode'/=mode+ then ((mode',bms),[Left (Left (path,mode')) | path<-bms])+ -- !! This will send msgs also to buttons that have been destroyed+ else (state,[])++ liftbm (F sp) = F $ prepostMapSP pre post sp+ where+ pre (High (Left (path,mode))) = Low (path,XEvt (MenuPopupMode mode))+ pre (High (Right x)) = High x+ pre (Low tevent) = Low tevent++ post (Low (path,XCmd MeButtonMachine)) = High (Left path)+ post (Low tcmd) = Low tcmd+ post (High y) = High (Right y)
+ hsrc/fudgets/MoreF.hs view
@@ -0,0 +1,65 @@+module MoreF(+ moreF,moreF',+ pickListF,pickListF',PickListRequest(..)+) where++import Fudget+--import Xtypes+import ResourceIds() -- synonym ColorName, for hbc+import Spops+import Geometry+import ScrollF(oldVscrollF,grabScrollKeys)+import TextF+import Spacer(marginF)+import SerCompF(absF)+import Loops(loopThroughRightF)+import CompOps((>=^<))+import StringUtils(rmBS,expandTabs)+import Defaults(labelFont,paperColor)+import GCAttrs() -- instances++import FDefaults+--import Alignment+import InputMsg(InputMsg,mapInp)+import ListRequest(ListRequest(..),replaceAll,replaceItems,applyListRequest)++txtF' pmod = marginF 5 $+ --alignSepF 5 aLeft aTop $+ textF' pmod++--stringListF :: Size -> FontName -> F TextRequest (InputMsg (Int,String))+stringListF' size pmod = oldVscrollF grabScrollKeys (size,size) (txtF' pmod)++moreF = moreF' standard++moreF' :: Customiser TextF -> F [String] (InputMsg (Int,String))+moreF' pmod =+ stringListF' (pP 480 260) pmod' >=^<(replaceAll.map (rmBS.expandTabs 8))+ where+ pmod' = pmod.setBgColor paperColor++type PickListRequest a = ListRequest a++pickListF = pickListF' standard++pickListF' :: Customiser TextF -> (a->String) -> F (PickListRequest a) (InputMsg (Int,a))+pickListF' pmod show =+ loopThroughRightF (absF (pickSP [])) altListF+ where+ pmod' = pmod.setFont labelFont+ altListF = oldVscrollF grabScrollKeys (Point 240 260,Point 480 390) (txtF' pmod')+ pickSP alts =+ getSP $ \msg ->+ case msg of+ Right plreq@(ReplaceItems from cnt newalts') ->+ let alts' = applyListRequest plreq alts+ newalts = map show newalts'+ in putSP (Left (replaceItems from cnt newalts)) $+ evalSpine alts' $ -- prevents a space leak+ pickSP alts'+ Right (HighlightItems ns) -> putSP (Left (HighlightItems ns)) $ pickSP alts+ Right (PickItem n) -> putSP (Left (PickItem n)) $ pickSP alts+ Left msg -> putSP (Right (mapInp (\(n,_)->(n,alts!!n)) msg)) (pickSP alts)++evalSpine [] = id+evalSpine (x:xs) = evalSpine xs
+ hsrc/fudgets/MoreFileF.hs view
@@ -0,0 +1,44 @@+module MoreFileF(+ moreFileShellF,+ moreShellF,moreShellF',+ moreFileF+) where+import MoreF(moreF')+import Command+import CompOps((>==<), (>=^<), (>^=<), (>=^^<))+import Shells(unmappedShellF, unmappedSimpleShellF)+import Fudget+import FRequest+import ReadFileF(readFileF)+--import Message(Message(..))+import SpEither(toBothSP)+import Spops(concmapSP)+--import Xtypes+import EitherUtils(stripEither)+import FDefaults+import InputMsg(InputMsg)+import DialogueIO() -- instances, for hbc+++moreShellF' pmod name = unmappedSimpleShellF name $ moreF' pmod+moreShellF = moreShellF' standard++moreFileF :: F String (InputMsg (Int, String))+moreFileF = moreFileF' standard+moreFileF' pmod = moreF' pmod >=^< contents >==< readFileF++moreFileShellF =+ let startcmds = [XCmd $ StoreName "More Fudget"]+ titleK = K{-kk-} $ concmapSP changeName -- titleK never outputs anything+ in stripEither >^=< unmappedShellF startcmds titleK moreFileF >=^^< toBothSP++contents (name,file) =+ case file of+ Right s -> lines s+ Left err -> [name++": "++show err] -- missing Show instance for IOError+ --Left err -> [name++": error"]++changeName msg =+ case msg of+ High name -> [Low $ XCmd $ StoreName name, Low $ XCmd MapRaised]+ _ -> []
+ hsrc/fudgets/OnOffDispF.hs view
@@ -0,0 +1,30 @@+module OnOffDispF where+import CompOps((>=^<),(>^^=<))+import NullF(F)+import Spops(nullSP)+--import Xtypes+import ResourceIds() -- synonym ColorName, for hbc+import Geometry(Point(..))+import MeasuredGraphics(emptyMG)+import GraphicsF(graphicsDispF',GfxCommand(..),setGfxEventMask)+import FDefaults+import GCAttrs+--import Drawing( ) -- instances+import Graphic( )+import Defaults(bgColor, fgColor)+import CmdLineEnv(argKey)+import Sizing(Sizing(..))++onOffDispF :: Bool -> F Bool nothing+onOffDispF start = nullSP >^^=< graphicsDispF' custom >=^< pre+ where+ custom = setInitDisp (emptyMG dsize) . setGfxEventMask [] .+ setSizing Static . setBorderWidth 0 .+ setBgColor (color start)+ color on = if on then onColor else offColor+ dsize = Point 7 7+ --pre :: Bool -> GfxCommand Bool -- resolving overloading...+ pre = ChangeGfxBg . colorSpec . color++offColor = argKey "toggleoff" bgColor+onColor = argKey "toggleon" fgColor
+ hsrc/fudgets/PopupMenuF.hs view
@@ -0,0 +1,90 @@+module PopupMenuF(popupMenuF,oldPopupMenuF,oldPopupMenuF') where+--import ButtonGroupF+import Command+import CompOps((>=^<), (>^=<),(>+<))--(>==<), +import InfixOps((>=..<))--(>^^=<),+import Dlayout(groupF)+import Event+--import Font(FontStruct)+import Fudget+import FRequest+--import Geometry(Line, Point, Rect, Size(..))+import GreyBgF(changeBg)+--import LayoutRequest(LayoutRequest)+import MenuF(menuAltsF,toEqSnd,fstEqSnd,sndEqSnd)--EqSnd,+import MenuPopupF(PopupMenu(..))+import DynListF(dynF)+--import Message(Message(..))+import Path(here)+import SerCompF(serCompLeftToRightF)--idRightF,+import Spops+import EitherUtils(mapEither)+import Xtypes+import CompSP(serCompSP)+import Defaults(bgColor,menuFont)+import Utils(pair)+import NullF(delayF)+--import ShowCommandF(showCommandF) -- debugging+--import SpyF(teeF) -- debugging++--popupMenuF :: [(alt,String)] -> F i o -> F (Either x i) (Either alt o)+popupMenuF alts f =+ mapEither fstEqSnd id>^=<+ oldPopupMenuF bgColor True menuFont (Button 3) [] []+ (pre alts) sndEqSnd f+ >=^< mapEither pre id+ where+ pre = map (`pair` []) . toEqSnd++oldPopupMenuF bgcolor grab fname button mods keys alts show_alt f = + serCompLeftToRightF $+ oldPopupMenuF' bgcolor grab fname button mods keys alts show_alt f++oldPopupMenuF' bgcolor grab fname button mods keys alts show_alt f =+ let grabeventmask = [ButtonPressMask, ButtonReleaseMask]+ grabcmd = if grab then [GrabButton True button mods grabeventmask]+ else []+ eventmask =+ (if null keys then [] else [KeyPressMask, KeyReleaseMask]) +++ (if grab then [] else (OwnerGrabButtonMask:grabeventmask)) +++ [LeaveWindowMask]+ startcmds = grabcmd ++ [ChangeWindowAttributes [CWEventMask eventmask]]+ ungrab = concatMapSP un where+ un (High m) = [High m,Low (here,XCmd UngrabEvents)]+ un m = [m]++ F dynAltsFSP = dynAltsF+ dynAltsF =+ dynF (altsF alts) >=^< mapEither altsF id+ where+ altsF alts' = delayF' (menuAltsF fname (map fst alts') show_alt)+ -- !! keyboard shortcuts ignored !!+ delayF' f = delayF f >=..< filterSP notDestroy+ --delayF' = id+ --delayF' f = delayF (showCommandF "altsF" f >==< teeF show "altsF: ")+ notDestroy (_,XEvt (DestroyNotify _)) = False+ notDestroy _ = True++ in (groupF (map XCmd startcmds)+ (changeBg bgcolor (actionK grab button keys mods))+ (F{-ff-} (ungrab `serCompSP` dynAltsFSP) >+< f))++actionK grab button keys mods = K{-kk-} $ concmapSP action where+ toF = High . Right+ toMenu = High . Left . Right+ newMenu = High . Left . Left+ action msg = case msg of+ High (Right hmsg) -> [toF hmsg]+ High (Left alts) -> [newMenu alts] -- breaks backwards compatibility...+ Low (XEvt ev) -> case ev of+ ButtonEvent {rootPos=rootPos,state=m,type'=Pressed,button=b} | m == mods && b == button -> + [Low $ XCmd (GrabEvents True),toMenu (PopupMenu rootPos ev)]+ KeyEvent {rootPos=rootPos,state=m,type'=Pressed,keySym=ks} | (m, ks) `elem` keys -> + [toMenu (PopupMenu rootPos ev)]+ LeaveNotify {mode=NotifyUngrab} -> + [Low $ XCmd UngrabEvents,toMenu PopdownMenu]+ ButtonEvent {type'=Released} -> + [Low $ XCmd UngrabEvents,toMenu PopdownMenu]+ KeyEvent {type'=Released} -> [toMenu PopdownMenu]+ _ -> []+ Low _ -> []
+ hsrc/fudgets/PushButtonF.hs view
@@ -0,0 +1,21 @@+module PushButtonF(pushButtonF, pushButtonF', Click(..)) where+import ButtonBorderF+import ButtonGroupF+import InputMsg(Click(..))+import CompOps((>=^<))+import Defaults(edgeWidth)+--import Fudget+import SerCompF(idRightF)++pushButtonF = pushButtonF' edgeWidth++pushButtonF' edgew keys f =+ buttonGroupF keys (idRightF (buttonBorderF edgew f) >=^< prep)+ where+ toBorder = Left . Left+ toFudget = Left . Right+ through = Right+ prep (Left BMNormal) = toBorder False+ prep (Left BMInverted) = toBorder True+ prep (Left BMClick) = through Click+ prep (Right e) = toFudget e
+ hsrc/fudgets/QuitButtonF.hs view
@@ -0,0 +1,21 @@+module QuitButtonF where+import Spacer(marginHVAlignF)+import Alignment+import DButtonF+import FDefaults+import CompOps((>==<))+--import Defaults(buttonFont)+--import Event(Event(..))+--import Fudget+--import PushButtonF+import QuitF+--import AuxTypes(Modifiers(..))+import Defaults(metaKey)+import Graphic( )++quitButtonF =+ quitF >==<+ marginHVAlignF 0 aRight aBottom+ (buttonF' (setKeys [([metaKey], "q")]) "Quit")++
+ hsrc/fudgets/QuitF.hs view
@@ -0,0 +1,19 @@+module QuitF(quitIdF, quitF) where+import FudgetIO+import HaskellIO+import NullF+import DialogueIO hiding (IOError) -- Exit++--quitF :: F a b+quitF =+ getHigh $ \ _ ->+ hIOSuccF (Exit 0) $+ nullF++--quitIdF :: (a -> Bool) -> F a a+quitIdF p =+ getHigh $ \ msg ->+ (if p msg+ then hIOSuccF (Exit 0)+ else putHigh msg) $+ quitIdF p
+ hsrc/fudgets/RadioF.hs view
@@ -0,0 +1,49 @@+module RadioF(radioF, oldRadioGroupF) where+import Spacer(noStretchF)+--import Alignment(Alignment(..))+--import ButtonGroupF+import CompOps((>==<), (>=^<))+import HbcUtils(lookupWithDefault)+--import Fudget+--import Geometry(Point, Rect, Size(..))+import LayoutF(listLF)+--import Placers+import Loops(loopLeftF)+import SerCompF(absF)+import Spops+import EitherUtils(stripEither)+import ToggleButtonF(oldToggleButtonF')+--import Xtypes+import Utils(pair)++radioF placer inside fname alts startalt =+ oldRadioGroupF placer inside fname (map fst alts) startalt (lookupWithDefault alts (error "radioF"))++oldRadioGroupF placer inside fname alts startalt show_alt =+ let radioAlts = radioButtonsF placer inside fname alts show_alt+ buttons = radioAlts >=^< stripEither+ in loopLeftF (excludeF startalt >==< buttons) >=^< (`pair` True)++radioButtonsF placer inside fname alts show_alt =+ listLF placer (map radiobutton alts)+ where+ radiobutton alt =+ (alt, noStretchF False True $ + oldToggleButtonF' inside fname [] (show_alt alt))++excludeF start =+ absF (putsSP [Left (start, True)] (excl start))+ where+ excl last' =+ getSP $ \msg ->+ case msg of+ (new, False) -> if new == last'+ then putsSP [Left (new, True)] (cont new)+ else same+ (new, True) -> if new == last'+ then putsSP [Right new] (cont new)+ else putsSP [Left (last', False), Right new] (cont new)+ where+ same = excl last'+ cont last'' = excl last''+
+ hsrc/fudgets/StringF.hs view
@@ -0,0 +1,339 @@+{-# LANGUAGE CPP #-}+module StringF(+ stringF'',StringF,+ {-HasBorderWidth(..),HasAllowedChar(..),HasShowString(..),-}+ getAllowedChar,setAllowedChar,getShowString,setShowString,+ setInitStringSize,+ getCursorPos,setCursorPos,getInitString,setInitString,+ generalStringF, oldIntF, oldPasswdF, oldStringF, bdStringF, oldGeneralStringF+ ) where+import BgF(changeGetBackPixel)+--import Color+import Command+import DrawInWindow+import CompOps((>=^<), (>^=<))+--import Utils(bitand)+import HbcWord+import Cursor+import Defaults(defaultFont, inputFg, inputBg, metaKey)+import CmdLineEnv(argKey, argKeyList)+import Dlayout(windowF)+import Event+import Font(split_string,font_ascent,next_pos,linespace,font_id,string_box_size,font_range)+import Fudget+--import FudgetIO+import FRequest+import Xcommand+import Gc+import Xtypes+import Geometry(Point(..), pP, rR,pmax)+import LayoutRequest(plainLayout,LayoutResponse(..))+--import LoadFont+--import Message(Message(..))+import NullF+--import Spops+import StringEdit+import InputMsg(InputMsg(..),mapInp,inputLeaveKey)+import InputF(InF(..))+import SelectionF+import Loops(loopThroughRightF)+import Sizing+#ifdef __GLASGOW_HASKELL__+import FDefaults hiding (setInitSize,getInitSize,getInitSizeMaybe)+#else+-- Some versions of HBC fail if you mention a constructor class in an import spec.+--import FDefaults hiding (HasInitSize)+import FDefaults(cust,getpar,getparMaybe,HasBorderWidth(..),HasSizing(..),HasBgColorSpec(..),HasFgColorSpec(..),HasFontSpec(..),Customiser(..),PF(..))+#endif+import Data.Char(isPrint,isDigit)+import GCAttrs --(ColorSpec,colorSpec,convColorK) -- + instances++default(Int)++-- chr/ord are defined in *some* versions of the library module Char...+chr' = toEnum . wordToInt :: (Word->Char)+ord' = fromIntegral . fromEnum :: (Char->Word)+++#include "defaults.h"++newtype StringF = Pars [Pars]++parameter(AllowedChar)+parameter(ShowString)+parameter(CursorPos)+parameter(InitString)++parameter_instance(BorderWidth,StringF)+parameter_instance(FgColorSpec,StringF)+parameter_instance(BgColorSpec,StringF)+parameter_instance(FontSpec,StringF)+parameter_instance(Sizing,StringF)+--parameter_instance(InitSize,StringF) -- StringF has wrong kind for this+parameter(InitSize)++setInitStringSize = setInitSize -- avoid name clash++data Pars+ = BorderWidth Int+ | FgColorSpec ColorSpec+ | BgColorSpec ColorSpec+ | FontSpec FontSpec+ | AllowedChar (Char->Bool)+ | ShowString (String->String)+ | InitSize String+ | Sizing Sizing+ | CursorPos Int -- puts cursor after the nth character+ | InitString String++isTerminator key = key `elem` ["Escape", "Return", "KP_Enter", "Tab", "Up", "Down"]++isBackSpace (c : _) = c == '\BS' || c == '\DEL'+isBackSpace _ = False++ctrl c = chr' (bitAnd (ord' c) (65535-96))++isCtrl c (c':_) = c' == ctrl c+isCtrl _ _ = False++isKill = isCtrl 'u'++modchar mods c0 = if metaKey `elem` mods then chr' (ord' c0 `bitOr` 128) else c0++cursorBindings' =+ [(([], "Left"), moveCursorLeft),+ (([], "Right"), moveCursorRight),+ (([], "Home"), moveCursorHome),+-- (([], "Up"), moveCursorHome),+ (([], "End"), moveCursorEnd),+-- (([], "Down"), moveCursorEnd),+-- (([Shift],"Control"), moveCursorHome), -- ???+-- (([Shift],"Control"), moveCursorEnd), -- ???+ (([Shift],"Left"), extendCursorLeft),+ (([Shift],"Right"), extendCursorRight),+ (([Shift],"Home"), extendCursorHome),+ (([Shift],"Up"), extendCursorHome),+ (([Shift],"End"), extendCursorEnd),+ (([Shift],"Down"), extendCursorEnd)]+ ++ emacsBindings++emacsBindings = + [(([Control], "b"), moveCursorLeft),+ (([Control], "f"), moveCursorRight),+ (([Control], "e"), moveCursorEnd),+ (([Control], "a"), moveCursorHome)]++cursorKey' mods key = lookup (filter (<=Mod5) mods,key) cursorBindings'++hmargin = 3+vmargin = 2++placecursor font (Point x _) field =+ case getField field of+ [] -> field+ cs -> let (lcs, rcs, _) = split_string font cs (x - hmargin)+ in createField2 (lcs, rcs)++showinputfield gc gcinv font show' = showinputfield'+ where+ drimstr = if snd (font_range font) > '\xff'+ then wDrawImageString16+ else wDrawImageString++ showinputfield' active field =+ let y = font_ascent font + 1+ draw x s = if null s then [] else [drimstr gc (pP x y) s]+ showpart gc' s0 (x, cmds) =+ let s = show' s0+ in (x + next_pos font s, draw x s ++ cmds)+ showcursor s (x1, cmds) =+ let (x2, cmds') = showpart gc s (x1, cmds)+ cmd = if active+ then [wFillRectangle gcinv+ (rR (x1 - 1) 1+ (x2 - x1 + 1) (linespace font))]+ else []+ in (x2, cmds' ++ cmd)+ in snd (showField (showpart gc) showcursor field (hmargin, []))++createField' pos s =+ if pos<0+ then createField s+ else createField2 (splitAt pos s)++stringK bw initsize sizing bgcolor fgcolor fontspec allowedchar show' cursor defaultText active =+ setFontCursor 152 $+ xcommandK (ConfigureWindow [CWBorderWidth bw]) $+ changeGetBackPixel bgcolor $ \bg ->+ convColorK fgcolor $ \fg ->+ convFontK fontspec $ \ fd ->+ fontdata2struct fd $ \ font ->+ wCreateGC rootGC [GCFunction GXcopy, GCFont (font_id font),+ GCForeground fg, GCBackground bg] $ \drawGC ->+ wCreateGC rootGC (invertColorGCattrs bg fg) $ \invertGC ->+ let drawit field active = map Low (XCmd ClearWindow : drawcmds)+ where drawcmds = shinpf active field+ shinpf = showinputfield drawGC invertGC font show'+ stringproc size' field active =+ let redraw f =+ putsK (drawit f active) (stringproc size' f active)+ nochange = stringproc size' field active+ newsize s = stringproc s field active+ changeactive a = putsK (drawit field a) $+ stringproc size' field a+ emit msg f a = putsK (drawit f a ++ [High (Right msg)]) $+ stringproc size' f a+ emitchange f =+ let gf = getField f+ in updlayout size' gf (emit (InputChange gf) f active)+ emitdone key f = emit (InputDone key (getField f)) f active+ emitleave =+ emit (InputDone inputLeaveKey (getField field)) field False+ paste = putK (High (Left PasteSel)) nochange+ copy = putK (High (Left (Sel (getField field)))) nochange+ in getK $ \msg ->+ case msg of+ Low (XEvt event) ->+ case event of+ Expose _ _ -> redraw field+ KeyEvent _ _ _ mods Pressed _ key ascii ->+ case ascii of+ c0 : _ | allowedchar c -> ec (insertItem field c)+ where c = modchar mods c0+ _ | isTerminator key ->+ emitdone key (createField (getField field))+ | isBackSpace ascii -> ec (deleteItemLeft field)+ | isCtrl 'd' ascii -> ec (deleteItemRight field)+ | isCtrl 'k' ascii -> ec (deleteToEnd field)+ | isCtrl 'y' ascii -> paste+ | isCtrl 'c' ascii -> copy+ | isCtrl 'w' ascii -> copy -- should acutally be cut+ | isKill ascii -> ec (createField "")+ | otherwise ->+ case cursorKey' mods key of+ Just ed -> redraw (ed field)+ _ -> case key of+ "SunPaste" -> paste+ "SunCopy" -> copy+ _ -> --putK (Low (Bell 0)) $+ nochange+ where ec = emitchange+ ButtonEvent {pos=p, button=Button 1} ->+ redraw (placecursor font p field)+ ButtonEvent {button=Button 2} -> paste+ FocusIn {} -> changeactive True+ FocusOut {} -> emitleave+ _ -> nochange+ Low (LEvt (LayoutSize nsize)) -> newsize nsize+ High (Right (Right newtext)) ->+ if newtext/=getField field+ then emitchange (createField newtext)+ --else updlayout size' newtext (redraw (createField newtext))+ else nochange+ High (Right (Left customiser)) ->+ reconfigure customiser field active+ High (Left (SelNotify cs)) ->+ emitchange (insertItemsSelected field s)+ where s = filter allowedchar cs+ _ -> nochange++ reconfigure pmod field active =+ -- !! unload fonts, free GCs & colors...+ stringK bw' initsize' sizing' bgcolor' fgcolor' fontspec' allowed' show'' cursor' txt' active+ -- !!! Bad: active will be reset to False.+ -- !! A new layout request will be output (useful if font changed).+ where ps = pmod (Pars [BorderWidth bw,+ BgColorSpec bgcolor,+ FgColorSpec fgcolor,+ FontSpec fontspec,+ AllowedChar allowedchar,+ ShowString show',+ CursorPos (-1), -- !!+ InitSize initsize,+ Sizing sizing])+ bw' = getBorderWidth ps+ initsize' = txt' --getInitSize ps -- hmm !!+ sizing' = getSizing ps+ bgcolor' = getBgColorSpec ps+ fgcolor' = getFgColorSpec ps+ fontspec' = getFontSpec ps+ allowed' = getAllowedChar ps+ show'' = getShowString ps+ txt' = getField field+ cursor' = getCursorPos ps++ sizetext text = pP (2*hmargin) (2*vmargin) + string_box_size font text+ size = pmax (sizetext defaultText) (sizetext initsize)+ updlayout curSize gf =+ let reqSize = sizetext gf+ nsize = newSize sizing curSize reqSize+ in if nsize /= curSize then putlayoutlims nsize else id+ putlayoutlims size' =+ putK (Low (layoutRequestCmd (plainLayout size' False True)))+ in putlayoutlims size $+ stringproc size (createField' cursor defaultText) active++generalStringF bw initsize sizing bg fg fontspec allowedchar show' cursor txt =+ loopThroughRightF winF selectionF+ where+ eventmask = [ExposureMask, KeyPressMask, ButtonPressMask,+ EnterWindowMask, LeaveWindowMask -- to be removed+ ]+ startcmds = [XCmd $ + ChangeWindowAttributes [CWBitGravity NorthWestGravity,+ CWEventMask eventmask+ {-,CWBackingStore Always-}]+ ]+ winF = windowF startcmds + (stringK bw initsize sizing bg fg fontspec+ allowedchar show' cursor txt False)++stringF'' :: (Customiser StringF) -> PF StringF String (InputMsg String)+stringF'' pmod = generalStringF bw initsize sizing bg fg font allowed show cursor initstring+ where+ ps = pmod (Pars [BorderWidth 1,+ BgColorSpec inputbg,+ FgColorSpec inputfg,+ FontSpec stringfont,+ AllowedChar isPrint',+ ShowString id,+ InitSize "xxxxx",+ Sizing Growing,+ CursorPos (-1),+ InitString ""])+ bw = getBorderWidth ps+ bg = getBgColorSpec ps+ fg = getFgColorSpec ps+ font = getFontSpec ps+ allowed = getAllowedChar ps+ show = getShowString ps+ --initsize = "xxxxx"+ initsize = getInitSize ps+ sizing = getSizing ps+ cursor = getCursorPos ps+ initstring = getInitString ps+++oldGeneralStringF bw sizing font allowed show txt =+ generalStringF bw "xxxxx" sizing inputbg inputfg font allowed show (-1) txt >=^< Right++bdStringF bw dyn font = oldGeneralStringF bw dyn font isPrint' id++oldStringF :: String -> InF String String+oldStringF = bdStringF 1 Growing stringfont++oldPasswdF :: String -> InF String String+oldPasswdF = oldGeneralStringF 1 Static stringfont isPrint' (map (const '*'))++oldIntF :: Int -> InF Int Int+oldIntF default' =+ mapInp read >^=<+ oldGeneralStringF 1 Static stringfont isDigit id (show default') >=^<+ show++stringfont = fontSpec (argKey "inputfont" defaultFont)+inputbg = colorSpec (argKeyList "stringbg" [inputBg])+inputfg = colorSpec (argKeyList "stringfg" [inputFg])++-- Workaround limitations of HBC's Char.isPrint to allow Unicode input.+isPrint' c = c>'\xff' || isPrint c
+ hsrc/fudgets/TerminalF.hs view
@@ -0,0 +1,130 @@+module TerminalF(terminalF,cmdTerminalF,TerminalCmd(..)) where+import Spacer(marginF)+--import Alignment(Alignment(..))+import BgF+import Color+import Command+import FRequest+import DrawInWindow(wDrawImageString,wDrawImageString16,wCopyArea)+import XDraw+import Defaults(paperColor, fgColor)+import Dlayout(simpleGroupF, windowF)+import Event+import Font+import Fudget+--import FudgetIO+import Gc+import Geometry(Point(..), Rect(..), origin, pP, padd,)-- rectsize+import LayoutRequest+--import Placer(spacerF)+--import Spacers+import LoadFont+--import Message(Message(..))+import NullF+import StateMonads+--import EitherUtils(mapMaybe, stripMaybeDef)+import Xtypes+import CompOps+import GCAttrs() -- instances++grmarginF m f = simpleGroupF [] (marginF m f)++data TerminalCmd+ = TermText String -- add string on a new line+ | TermAppend String -- append string to last line+ | TermClear++terminalF :: FontName -> Int -> Int -> F String a+terminalF fname nrows ncols = cmdTerminalF fname nrows ncols >=^< TermText++cmdTerminalF :: FontName -> Int -> Int -> F TerminalCmd a+cmdTerminalF fname nrows ncols =+ let wattrs = [CWBackingStore WhenMapped, CWEventMask [ExposureMask]]+ in grmarginF 2+ (windowF [XCmd $ ChangeWindowAttributes wattrs,+ XCmd $ ConfigureWindow [CWBorderWidth 1]]+ (terminalK fname nrows ncols))++terminalK fname nrows ncols =+ safeLoadQueryFont fname $ \fs ->+ allocNamedColorPixel defaultColormap fgColor $ \fg ->+ changeGetBackPixel paperColor $ \bg ->+ wCreateGC rootGC [GCFunction GXcopy, GCFont (font_id fs), GCForeground fg, GCBackground bg]+ (terminalK1 fs nrows ncols)++m1 $$$ m2 = m1>>m2++m1 $> xm2 = m1 >>= xm2++terminalK1 fs nrows ncols gc =+ let charsize@(Point charw charh) = string_box_size fs "M"+ startsize = curpos nrows ncols+ size = startsize+ curpos row col = pP (charw * col) (charh * row)+ drawpos row col = padd (curpos row col) (pP 0 (font_ascent fs))+ drimstr = if snd (font_range fs) > '\xff'+ then wDrawImageString16+ else wDrawImageString+ k =+ getKs $>+ (\msg ->+ (case msg of+ Low (XEvt (Expose _ 0)) -> redraw+ Low (LEvt (LayoutSize newsize)) -> setSize newsize+ Low _ -> nopMs+ High cmd -> case cmd of+ TermText line -> addDrawLine line+ TermAppend s -> appendDrawLine s+ TermClear -> clearit) $$$+ k)+ drawline (r, l) =+ loadMs $>+ (\(lines', row, col, nrows', ncols') ->+ putLowMs (drimstr gc (drawpos r 0) l))+ redraw =+ loadMs $>+ (\(lines', row, col, nrows', ncols') ->+ putLowMs clearWindow $$$+ foldr (\l -> (drawline l $$$)) nopMs (zip [0 ..] (reverse lines')))+ setSize (Point x y) =+ loadMs $>+ (\(lines', row, col, nrows', ncols') ->+ let ncols'' = x `quot` charw+ nrows'' = y `quot` charh+ row' = row `min` nrows''+ col' = col `min` ncols''+ lines'' = take nrows'' lines'+ in storeMs (lines'', row', col', nrows'', ncols'') $$$ redraw)+ addLine line =+ loadMs $>+ (\(lines', row, col, nrows', ncols') ->+ if row < nrows' - 1 then+ let lines'' = line : lines'+ row' = row + 1+ in storeMs (lines'', row', col, nrows', ncols')+ else+ let lines'' = take nrows' (line : lines')+ in storeMs (lines'', row, col, nrows', ncols') $$$+ putLowsMs [wCopyArea gc+ MyWindow+ (Rect (pP 0 charh)+ (curpos (nrows' - 1) ncols'))+ origin,+ clearArea (Rect (curpos row 0)+ (curpos 1 ncols'))+ False])+ appendLine s =+ loadMs $> \(lines', row, col, nrows', ncols') ->+ case lines' of+ [] -> storeMs ([s],row+1,col,nrows',ncols')+ l:ls -> storeMs ((l++s):ls, row, col, nrows', ncols')+ clearit = loadMs $> \(lines, row, col, nrows, ncols) ->+ storeMs ([],-1,0,nrows,ncols) $$$ redraw+ addDrawLine line =+ (addLine line $$$ loadMs) $> + (\(lines', row, col, nrows', ncols') -> drawline (row, line))+ appendDrawLine s =+ (appendLine s $$$ loadMs) $>+ (\(line:_, row, col, nrows', ncols') -> drawline (row, line))+ in putK (Low (layoutRequestCmd (plainLayout size False False))) $+ stateK ([], -1, 0, nrows, ncols) k nullK
+ hsrc/fudgets/TextF.hs view
@@ -0,0 +1,300 @@+{-# LANGUAGE CPP #-}+module TextF(textF,textF',textF'',TextF,+ TextRequest(..)) where+import Fudget+import FudgetIO+import FRequest+import NullF+import Utils+import Geometry+import Xtypes+import Event+import Command+import XDraw+import Dlayout+import DoubleClickF+import BgF+--import Color+--import EitherUtils(mapfilter)+import Data.Maybe(mapMaybe)+import Message(message) --Message(..),+import Font+--import LoadFont+import Gc+import InputMsg+import LayoutRequest+import Alignment(aLeft) --Alignment(..),+import Defaults(defaultFont,bgColor,fgColor)+import Sizing+import FDefaults+import GCAttrs --(ColorSpec,convColorK,colorSpec)+import ListRequest(ListRequest(..),listEnd)+#include "../defaults/defaults.h"++default(Int) -- mostly for Hugs+++#ifndef __HBC__+#define fromInt fromIntegral+#endif++type TextRequest = ListRequest String++newtype TextF = Pars [Pars]++data Pars+ = BorderWidth Int+ | FgColorSpec ColorSpec+ | BgColorSpec ColorSpec+ | FontSpec FontSpec+ | Align Alignment+ | Margin Int+ | InitText [String]+-- | InitSize String+ | Stretchable (Bool,Bool)+ | Sizing Sizing++parameter_instance(BorderWidth,TextF)+parameter_instance(FgColorSpec,TextF)+parameter_instance(BgColorSpec,TextF)+parameter_instance(FontSpec,TextF)+parameter_instance(Align,TextF)+parameter_instance(Margin,TextF)+parameter_instance(InitText,TextF)+--parameter_instance(InitSize,TextF)+parameter_instance(Sizing,TextF)+parameter_instance(Stretchable,TextF)++textF = textF' standard+textF' pm = noPF $ textF'' pm++textF'' :: Customiser TextF ->+ PF TextF TextRequest (InputMsg (Int, String))+textF'' pmod =+ let ps :: TextF+ ps = pmod (Pars [BorderWidth 0,+ FgColorSpec textfg,+ BgColorSpec textbg,+ Margin 2,+ Align aLeft,+ InitText [],--InitSize "",+ Stretchable (False,False),+ Sizing Dynamic,+ FontSpec (fontSpec defaultFont)])+ bw = getBorderWidth ps+ fg = getFgColorSpec ps+ bg = getBgColorSpec ps+ font = getFontSpec ps+ init = getInitText ps+ minstr = "" --getInitSize ps+ margin = getMargin ps+ align = getAlign ps+ sizing = getSizing ps+ stretch = getStretchable ps++ eventmask = [ExposureMask, ButtonPressMask]+ startcmds = map XCmd + [ConfigureWindow [CWBorderWidth bw],+ ChangeWindowAttributes+ [CWEventMask eventmask+ ,CWBitGravity (horizAlignGravity align)+ ,CWBackPixmap none -- elim flicker caused by XClearArea+ ]]+ in doubleClickF doubleClickTime $+ windowF startcmds $ textK0 bg fg font stretch align sizing margin minstr init+++textK0 bg fg font (flexh,flexv) align sizing margin minstr init =+ changeGetBackPixel bg $ \ bgcol ->+ convColorK fg $ \ fgcol ->+ --allocNamedColorPixel defaultColormap fg $ \ fgcol ->+ convFontK font $ \ fd ->+ fontdata2struct fd $ \ fs ->+ wCreateGC rootGC [GCFont (font_id fs),+ GCForeground fgcol,+ GCBackground bgcol] $ \gc ->+ wCreateGC gc [GCForeground bgcol,+ GCBackground fgcol] $ \gcinv ->+ let minw = next_pos fs minstr+ in textK1 bgcol gc gcinv fs (not flexh) (not flexv) align sizing margin minw init++textK1 bgcol gc gcinv fs fh fv align sizing margin minw =+ replaceTextK origin origin [] [] 0 listEnd+ where+ ll size = Low (layoutRequestCmd (plainLayout size fh fv))+ ls = linespace fs+ base = font_ascent fs + margin+ margsize = diag (2*margin)++ measure = map (pairwith (next_pos fs))+ txtwidth mtxt = maximum (1:minw:map snd mtxt)+ -- 0 width not allowed for windows++ drimstr = if snd (font_range fs) > '\xff'+ then DrawImageString16+ else DrawImageString++ txtsize mtxt =+ let width = txtwidth mtxt+ height = max 1 (ls*length mtxt) -- 0 height not allowed for windows+ in Point width height++ replaceTextK winsize@(Point winwidth winheight) size sel mtxt dfrom dcnt newtxt=+ let lines = length mtxt+ from = min lines (if dfrom==listEnd then lines else dfrom)+ after = lines-from+ cnt = min after (if dcnt==listEnd then after else dcnt)+ newcnt = length newtxt+ diff = newcnt-cnt+ scrollsize= after-cnt+ newlines = lines+diff+ sel' = mapMaybe reloc sel+ reloc n = if n<from then Just n+ else if n<from+cnt then Nothing+ else Just (n+diff)+ mtxt' = take from mtxt ++ measure newtxt ++ + (if scrollsize>0 then drop (from+cnt) mtxt else [])+ newwidth = txtwidth mtxt'+ newsize = Point newwidth (ls*newlines)+ llcmd = let realwinsize@(Point w h) = winsize+diag margin+ winsize'@(Point w' h') = newsize +margsize+ change =+ winsize==origin ||+ newSize sizing realwinsize winsize'/=realwinsize+ in if change+ then [ll (newsize + margsize)]+ else []+ --width = xcoord size+ drawwidth = max newwidth (winwidth-margin)+ -- !! always scrolls/clears the full width of the window+ scrollrect= rR margin (margin+ls*(from+cnt))+ drawwidth (ls*scrollsize)+ scrolldest= Point margin (margin+ls*(from+newcnt))+ scrollcmd = if scrollsize>0 && diff/=0+ then [Low (wDraw gc $ CopyArea MyWindow scrollrect scrolldest)]+ else []+ drawrect = rR margin (margin+ls*from) (drawwidth+margin) (ls*newcnt)+ -- add margin to width to erase text in the margin+ -- when the text is wider than the window.+ belowrect = rR margin (margin+ls*newlines) drawwidth (-ls*diff)+ clearcmd = (if newcnt>0+ then let vrect = growrect drawrect (pP 5 5) -- !! tmp fix+ in clearArea drawrect True+++ [Low (LCmd (layoutMakeVisible vrect))]+ else [])+++ (if diff<0+ then [Low $ XCmd $ ClearArea belowrect False]+ -- Needed because of margin and other things+ -- that cause the window to be taller than the+ -- text.+ -- clearcmd must be done after scrollcmd !!+ else [])+ clearArea r e = map (Low . XCmd) + [ChangeWindowAttributes [CWBackPixmap none],+ ClearArea r e,+ ChangeWindowAttributes [CWBackPixel bgcol]]+ -- Some backround may be lost if the windows becomes+ -- obscured while the BackPixmap is none !!!+ in if diff>0+ then resizeK llcmd $ \ newwinsize ->+ putsK (scrollcmd++clearcmd) $+ textK (newwinsize - diag margin) newsize sel' mtxt'+ else putsK (scrollcmd++clearcmd++llcmd) $+ textK winsize newsize sel' mtxt'++ textK :: Size -> Size -> [Int] -> [(String,Int)] ->+ PK TextF TextRequest (InputMsg (Int,String))+ textK winsize@(Point winwidth _) size sel mtxt =+ -- winsize is the size of the window excluding the right & bottom margins+ getK $ message lowK (either paramChangeK textRequestK)+ where+ same = textK winsize size sel mtxt+ textRequestK msg =+ case msg of+ ReplaceItems dfrom dcnt newtxt ->+ replaceTextK winsize size sel mtxt dfrom dcnt newtxt+ HighlightItems sel' ->+ changeHighlightK sel' $+ textK winsize size sel' mtxt+ PickItem n -> output inputMsg n+ _ -> same+ lowK event =+ case event of+ XEvt (ButtonEvent {button=Button 1,pos=Point _ y, type'=press}) ->+ let l=y `quot` ls+ pressmsg = case press of+ MultiClick 2 -> inputMsg+ _ -> InputChange+ in output pressmsg l+ XEvt (Expose {rect=r}) ->+ redrawTextK r $+ same+ XEvt (GraphicsExpose {rect=r}) ->+ redrawTextK r $+ same+ LEvt (LayoutSize newwinsize) ->+ textK (newwinsize - diag margin) size sel mtxt+ _ -> same+ paramChangeK _ = same -- !!! Dynamic customisation not implemented yet+ output pressmsg l = (if l>=0 && l<length mtxt+ then putK (High (pressmsg (l,fst(mtxt!!l))))+ else id) $ same++ changeHighlightK sel' =+ putsK (mkvis++[Low $ wDrawMany (map draw changes)])+ where+ changed n = (n `elem` sel) /= (n `elem` sel')+ nmtxt = number 0 mtxt+ changes = [l | l@(n,_)<-nmtxt, changed n]+ selected = [l | l@(n,_)<-nmtxt, n `elem` sel']+ draw (n,(s,w)) = (dgc sel' n,[drimstr (Point (x0 w) (base+n*ls)) s])+ mkvis =+ case (selected,last selected) of -- needs lazy evalution!+ ([],_) -> []+ ((n1,(_,w1)):_,(n2,(_,w2))) ->+ [Low (LCmd (layoutMakeVisible vrect))]+ where vrect = rR x1 y1 (x2-x1+5) (y2-y1+5)+ x1 = min (x0 w1) (x0 w2) -- !!! Should use min/max+ x2 = max (x0 w1) (x0 w2) -- !!! of all changes.+ y1 = n1*ls+ y2 = (n2+1)*ls++ redrawTextK r@(Rect (Point x y) (Point w h)) =+ let first = (max 0 (y-margin)) `quot` ls+ last = (y+h-1) `quot` ls+ lines = number first (take (last-first+1) (drop first mtxt))+ firsty = base+ls*first+ ys = [firsty,firsty+ls..]+ in putsK [Low $ XCmd $ ClearArea r False,+ Low $ wDrawMany+ [(dgc sel n,[drimstr (Point x1 ly) s]) | + ((n,s,x1,x2),ly)<-zip (map xi lines) ys,x<x2 && (x+w)>=x1]]+ -- !! The x coordnates should probably be stored+ -- rather than recomputed every time the text is+ -- redrawn...++ xi (n,(s,w)) = (n,s,x1,x2) where x1=x0 w; x2=x1+w+ x0 w = margin+floor (align*fromInt (winwidth-margin-w))+ -- !!! Problem: can't be sure that bitgravity moves stuff+ -- to the same pixel coordinates that are computed here...++ dgc sel n = if n `elem` sel -- inefficient !!+ then gcinv+ else gc++resizeK cmd cont = putsK cmd $ waitForMsg ans $ cont+ where ans (Low (LEvt (LayoutSize newsize))) = Just newsize+ ans _ = Nothing++doubleClickTime = 400 -- The double click timeout should not be hard wired like this...+textbg = colorSpec [bgColor,"white"]+textfg = colorSpec [fgColor,"black"]++horizAlignGravity align =+ case (align::Alignment) of+ 0 -> NorthWestGravity+ 0.5 -> NorthGravity+ 1 -> NorthEastGravity+ _ -> ForgetGravity++--take' n | n>=0 = take n
+ hsrc/fudgets/ToggleButtonF.hs view
@@ -0,0 +1,37 @@+module ToggleButtonF(toggleF, oldToggleButtonF, oldToggleButtonF') where+--import Alignment+import Spacer(marginF)+import CompOps((>=^<), (>^=<),(>+<),(>=^^<))+import CompSP(idRightSP)+import SpEither(filterRightSP)+import Spacers(compS,vCenterS,noStretchS)--,centerS,hvAlignS,spacerP+--import Placers(horizontalP)+import Placer(hBoxF,spacer1F)+import EitherUtils(stripEither)+import OnOffDispF+import ButtonBorderF+import ToggleGroupF+--import Geometry(Point(..))+import GraphicsF(graphicsLabelF')+import Defaults(look3d, edgeWidth)+import FDefaults -- setFont++toggleF inside keys lblF =+ toggleGroupF keys $+ if inside+ then buttonBorderF edgew (mF lblF) >=^^< idRightSP filterRightSP+ else stripEither >^=< hBoxF (sF (buttonBorderF edgew indicatorF) >+< cF lblF)+ where+ indicatorF = mF (onOffDispF False)+ mF = marginF innersep+ sF = spacer1F (noStretchS True True `compS` vCenterS)+ cF = spacer1F (noStretchS False True `compS` vCenterS)+ innersep = 2+ edgew = if look3d then edgeWidth else max 0 (edgeWidth-1)++oldToggleButtonF x = oldToggleButtonF' False x++oldToggleButtonF' inside fname keys lbl =+ stripEither >^=< toggleF inside keys lblF >=^< Left+ where+ lblF = graphicsLabelF' (setFont fname) lbl
+ hsrc/fudgets/ToggleGroupF.hs view
@@ -0,0 +1,25 @@+module ToggleGroupF(toggleGroupF) where+import ButtonGroupF+import CompOps((>=^^<))+import Spops(mapstateSP)+import Fudget+--import Geometry(Line(..), Point(..), Rect(..), Size(..))+--import Message(Message)+import SerCompF(idLeftF)+import Xtypes(KeySym(..), ModState(..))++toggleGroupF :: [(ModState, KeySym)] -> (F (Either (Either Bool Bool) a) b) -> F (Either Bool a) (Either Bool b)+toggleGroupF keys f =+ let toPressed = Right . Left . Left+ toStateF = Right . Left . Right+ toFudget = Right . Right+ through = Left+ change s = (s, [toStateF s, through s])+ prep s (Right (Left ns)) = change ns+ prep s (Left BMClick) = change (not s)+ prep s (Left BMNormal) = (s, [toPressed False])+ prep s (Left BMInverted) = (s, [toPressed True])+ prep s (Right (Right m)) = (s, [toFudget m])+ in buttonGroupF keys (idLeftF f >=^^< mapstateSP prep False)++
+ hsrc/ghc-dialogue/AsyncInput.hs view
@@ -0,0 +1,415 @@+{-# LANGUAGE CPP, MagicHash, UnboxedTuples #-}+{- Obsolete OPTIONS -optc-I/usr/X11R6/include -optc-DNON_POSIX_SOURCE -fvia-C -}+--+module AsyncInput+ (doSocketRequest,doSelect,getAsyncInput',initXCall,XCallState)+ where+import P_IO_data({-Request(..),-}Response(..))+import Xtypes+import Sockets as S+import DLValue+import Unsafe.Coerce -- !!!+--import ResourceIds+import Utils(swap)++import XCallTypes+import StructFuns+import Xlib+import EncodeEvent+import Marshall+import MyForeign+import GHC.Exts(addrToAny# )+import GHC.Ptr(FunPtr(..))++--import Ap+import HbcUtils(lookupWithDefault)+import Data.Maybe(mapMaybe)+import Control.Monad(when)+import Data.Traversable(traverse)++import PQueue++import Data.IORef(newIORef,readIORef,writeIORef,IORef)+import System.Posix.DynamicLinker as DL++import PackedString(unpackPS,lengthPS{-,packCBytesST,psToByteArray-})++default (Int)++#include "newstructfuns.h"++H_STRUCTTYPE(fd_set)++allocaInt = allocaElem (0::Int)++type AiTable = [(Fd,Descriptor)]++type IOVar a = IORef a++newIOVar = newIORef+readIOVar = readIORef+writeIOVar = writeIORef++type MsTime = Int++data XCallState = XCallState+ Cfd_set -- ^ read fd_set+ (IOVar Fd) -- ^ highest fd in read fd_set+ (IOVar AiTable)+ (IOVar (PQueue MsTime (MsTime,Timer)))+ (IOVar Time)++initXCall =+ XCallState+ <$> newPtr+ <*> newIOVar 0+ <*> newIOVar []+ <*> newIOVar empty+ <*> newIOVar 0++type Fd = Int32++foreign import ccall "unistd.h read" cread :: Fd -> Addr -> CSize -> IO CSize+foreign import ccall "unistd.h write" cwrite :: Fd -> CString -> CSize -> IO CSize+foreign import ccall "sys/socket.h" accept :: Fd -> CsockAddr -> Addr -> IO Fd++getAsyncInput' (XCallState fds maxfdvar aitable tq tno) =+ AsyncInput <$> do+ ai <- readIOVar aitable+ let timeLeft =+ do tqv <- readIOVar tq+ case inspect tqv of+ Nothing -> return Nothing+ Just ((t,_),_) ->+ do ms <- mstime+ return . Just . max 0 $ t - ms+ + let doSelect = do+ timeout <- traverse newTimeVal =<< timeLeft+ readfds <- newPtr+-- _casm_ ``bcopy(%0,%1,sizeof(fd_set));'' fds readfds+ bcopy_fdset fds readfds+ maxfdvar <- readIOVar maxfdvar+ n <- select (maxfdvar+1) readfds timeout+ maybe (return ()) freePtr timeout+ let findFd fd = do+ s <- fromC <$>+-- _casm_ ``%r=FD_ISSET(%0,(fd_set*)%1);'' fd readfds+ fd_isset fd readfds+ if not s then findFd (fd+1) + else let d = lookAi fd in case d of+ DisplayDe _ -> mkEvent fd d+ SocketDe _ ->+ let bufsize = 2000+ in alloca bufsize $ \ buf ->+ do got <- tryP "read" (>=0) $ cread fd buf (fromIntegral bufsize)+ str <- unmarshallString' (CString buf) (fromIntegral got)+ return (d,SocketRead str)+ LSocketDe _ ->+ allocaInt $ \ addrlen ->+ do addr <- newsockAddr+ sfd <- tryP "accept" (>=0) $ + --_ccall_ ACCEPT fd addr addrlen+ accept fd addr addrlen+ sf <- getfilep sfd "r+"+ --buf <- stToIO $ newCharArray (1,1000)+ --tryP "hostName" (==0) $ _ccall_ hostName addr buf+ --peer <- cstring <$> mutByteArr2Addr buf+ let peer = ""+ return (d,SocketAccepted (So sf) peer)++ _ -> error "getAsyncInput3"+ e <- if n == -1 then error . ("select "++) =<< strerror =<< errno+ else if n > 0 then findFd 0+ else do tno <- removetimeq tq+ return (TimerDe tno,TimerAlarm)+ freePtr readfds+ return e++ mkEvent fd d = do+ (window,fev) <- {-motionCompress display =<<-} getNextEvent display+ return (descriptor,XEvent (window,fev))+ where descriptor@(DisplayDe display) = d+ + lookAi = lookupWithDefault ai (error "getAsyncInput2")+ dispde x@(fd,DisplayDe _) = Just x+ dispde _ = Nothing+ case mapMaybe dispde ai of+ [] -> doSelect+ (fd,d@(DisplayDe display)):_ -> do+ q <- xPending display+ if q>0 then mkEvent fd d else doSelect++newTimeVal tleft =+ do timeout <- newPtr+ SET(timeVal,Int,timeout,tv_usec,(tleft `mod` 1000) * 1000)+ SET(timeVal,Int,timeout,tv_sec,(tleft `div` 1000))+ return timeout++foreign import ccall "sys/select.h select" cselect :: Int32 -> Cfd_set -> Cfd_set -> Cfd_set -> CtimeVal -> IO Int32+--foreign import ccall "unistd.h" getdtablesize :: IO Int++select :: Int32 -> Cfd_set -> Maybe CtimeVal -> IO Int32+select nfds readfds timeout = start where+ start = do+ n <- cselect nfds readfds nullPtr nullPtr (maybe nullPtr id timeout)+{-+ case timeout of+ Nothing -> + _casm_ ``%r=select(getdtablesize(),%0,NULL,NULL,NULL);'' readfds+ Just t -> + _casm_ ``%r=select(getdtablesize(),%0,NULL,NULL,%1);'' readfds t+-}+ + if n /= -1 then return n else do+ e <- errno+ if e == CCONST(EINTR) --- || e == CCONST(EAGAIN)+ then start -- again+ else return n+--}+foreign import ccall "asyncinput.h get_errno" errno :: IO Int+--errno :: IO Int+--errno = _casm_ ``%r=errno;''++foreign import ccall "sys/socket.h" listen :: Fd -> Int32 -> IO Int+foreign import ccall "sys/socket.h" socket :: Int32 -> Int32 -> Int32 -> IO Fd+foreign import ccall "stdio.h" fopen :: CString -> CString -> IO Int -- hmm+foreign import ccall "stdio.h" fclose :: Int -> IO Int++foreign import ccall "asyncinput.h" in_connect :: CString -> Int32 -> Int32 -> IO Int32+foreign import ccall "asyncinput.h" in_bind :: Int32 -> Int32 -> IO Fd+foreign import ccall "asyncinput.h" get_stdin :: IO Int++doSocketRequest (XCallState fds maxfdvar aitable tq tno) sr =+ case sr of+ CreateTimer interval first -> do+ tqv <- readIOVar tq+ tnov <- readIOVar tno+ now <- mstime+ writeIOVar tq (insert tqv (now+first,(interval,Ti tnov)))+ writeIOVar tno (tnov+1)+ returnS (Timer (Ti tnov))+ DestroyTimer t -> do+ tqv <- readIOVar tq+ writeIOVar tq (remove tqv t)+ return Success+ OpenSocket host port -> do+ chost <- marshallString host+ s <- tryP "in_connect" (>=0) $ +-- _casm_ ``%r=in_connect(%0,%1,SOCK_STREAM);'' chost port+ in_connect chost (fromIntegral port) (fromIntegral CCONST(SOCK_STREAM))+ sf <- getfilep s "r+"+ freePtr chost+ returnS (Socket (So sf))+ OpenLSocket port -> do+ s <- tryP "in_bind" (>=0) $ if port == 0 +-- then _casm_ ``%r=socket(AF_INET,SOCK_STREAM,0);''+ then socket (fromIntegral CCONST(AF_INET)) (fromIntegral CCONST(SOCK_STREAM)) 0+-- else _casm_ ``%r=in_bind(%0,SOCK_STREAM);'' port+ else in_bind (fromIntegral port) (fromIntegral CCONST(SOCK_STREAM))+ tryP "listen" (==0) $ listen s 5+ SocketResponse . LSocket . LSo <$> getfilep s "r+"+ WriteSocket s str -> writeSocket s str+ WriteSocketPS s str ->+ do writeSocket s (unpackPS str) -- grr!+ returnS (Wrote (lengthPS str)) -- grr!+{-+ do+ fd <- fileno s+ r <- tryP "WriteSocket[out]" (>=0) $ + _casm_ ``%r=write(fileno((FILE*)%0),%1,%2);'' s (psToByteArray str) (lengthPS str)+-- bawrite fd (psToByteArray str) (lengthPS str)+ return (SocketResponse (Wrote r))+-}+ CloseSocket (So s) -> close s+ CloseLSocket (LSo s) -> close s+ GetStdinSocket -> SocketResponse . Socket . So <$>+-- _casm_ ``%r=stdin;''+ get_stdin+ GetSocketName (So s) -> socketname s+ GetLSocketName (LSo s) -> socketname s+ StartProcess cmd doIn doOut doErr -> startProcess cmd doIn doOut doErr+ DLOpen path -> do dh <- dlopen path [RTLD_LAZY]+ case dh of+ Null -> failu =<< dlerror+ _ -> returnS $ S.DLHandle (DL dh)+ DLClose (DL dh) -> do dlclose dh ; return Success+ DLSym (DL dh) name ->+ do FunPtr fp <- dlsym dh name+ case addrToAny# fp of+ (# hval #) -> returnS . DLVal $ DLValue (unsafeCoerce hval)+ OpenFileAsSocket name mode -> do+ cname <- marshallString name+ cmode <- marshallString mode+ s <- tryP "OpenSocketAsFile[fopen]" (/=0) $ fopen cname cmode+ freePtr cname+ freePtr cmode+ returnS $ (Socket . So) s+ _ -> error ("Not implemented: "++show sr)+ where returnS = return . SocketResponse+ close s = do+ fclose s+ return Success+ socketname s =+ allocaInt $ \ lenp ->+ do sa <- newsockAddr+-- tryP "GetLSocketName" (==0) $ _ccall_ GETSOCKNAME (s::Int) sa lenp+ tryP "GetLSocketName" (==0) $ getsockname s sa lenp+ len <- peek lenp+ strp <- GETC(sockAddr,char *,CString,sa,sa_data)+-- Str . unpackPS <$> (stToIO $ packCBytesST len strp)+ Str <$> unmarshallString' strp len++writeSocket (So s) str =+ do let n = length str+ fd <- get_fileno s+ cstr <- marshallString' str n+ tryP "WriteSocket[out]" (>=0) $ +-- _casm_ ``%r=write(fileno((FILE*)%0),%1,%2);'' s cstr n+ cwrite fd cstr (fromIntegral n)+ freePtr cstr+ return Success++foreign import ccall "sys/socket.h" getsockname :: Int -> CsockAddr -> Addr -> IO Int+foreign import ccall "stdio.h" fdopen :: Int32 -> CString -> IO Int++getfilep s mode = tryP "fdopen" (/=0) $+ do cmode <- marshallString (mode::String)+-- _ccall_ fdopen (s::Int) cmode :: IO Int+ fdopen s cmode :: IO Int++foreign import ccall "string.h strerror" cstrerror :: Int -> IO CString+strerror e = unmarshallString =<< cstrerror e++tryP e p io = do+ r <- io+ if p (r{-::Int-}) then return r else do+-- cstr <- _casm_ ``%r=strerror(errno);''+ s <- strerror =<< errno+ failu (e++": "++ s)+++peekq tq = do+ tqv <- readIOVar tq+ return (inspect tqv)++removetimeq tq = do+ tqv <- readIOVar tq+ case inspect tqv of+ Just ((first,v@(interval,tnov)),tqv') -> do+ let tqv2 = if interval == 0 then tqv'+ else insert tqv' (first+interval,v)+ writeIOVar tq tqv2+ return tnov+ +foreign import ccall "sys/time.h" gettimeofday :: CtimeVal -> Addr -> IO ()++mstime = do+ now <- newtimeVal+-- _casm_ ``gettimeofday(%0,NULL);'' now+ gettimeofday now nullAddr+ s <- GET(timeVal,Int,now,tv_sec)+ us <- GET(timeVal,Int,now,tv_usec)+ return (s * 1000 + us `div` 1000 :: Int)+++foreign import ccall "asyncinput.h" fdzero :: Cfd_set -> IO ()+foreign import ccall "asyncinput.h fdset" fd_set :: Fd -> Cfd_set -> IO ()+foreign import ccall "asyncinput.h fdisset" fd_isset :: Fd -> Cfd_set -> IO Int+foreign import ccall "asyncinput.h" bcopy_fdset :: Cfd_set -> Cfd_set -> IO ()++doSelect :: XCallState -> [Descriptor] -> IO Response+doSelect (XCallState fds maxfdvar aitable _ _) dl =+ do+ fdzero fds+ ait <- concat <$> mapM descriptor dl+ let fds = map fst ait+ writeIOVar aitable ait+ writeIOVar maxfdvar (maximum fds)+ mapM_ fdset fds+ return Success+ where descriptor d = case d of+ LSocketDe (LSo s) -> withd $ get_fileno s+ SocketDe (So s) -> withd $ get_fileno s+ OutputSocketDe (So s) -> withd $ get_fileno s+ DisplayDe ({-Display-} d) -> withd $ +-- _casm_ ``%r=((Display*)%0)->fd;'' d+ xConnectionNumber d -- hmm+ TimerDe _ -> return []+ _ -> do putStr "Unexpected descriptor: ";print d;return []+ where withd m = m >>= \fd -> return [(fd,d)]++ fdset :: Fd -> IO ()+ --fdset s = _casm_ ``FD_SET(%0,(fd_set*)%1);'' s fds+ fdset s = fd_set s fds++foreign import ccall "asyncinput.h" get_fileno :: Int -> IO Fd+{-++-- Register problems with FD_ZERO under Redhat 6.1 Linux-i386...+--fdzero :: Cfd_set -> IO ()+--fdzero fds = _casm_ ``{ fd_set *s=%0; FD_ZERO(s);}'' fds+--fdzero fds = _ccall_ FD_ZERO fds++mutByteArr2Addr :: MutableByteArray RealWorld Int -> IO Addr+mutByteArr2Addr arr = _casm_ `` %r=(void *)%0; '' arr+--}++foreign import ccall "unistd.h" fork :: IO Int+foreign import ccall "unistd.h" execl :: CString -> CString -> CString -> CString -> Int -> IO Int+foreign import ccall "unistd.h" pipe :: Addr -> IO Int+foreign import ccall "unistd.h" dup :: Fd -> IO Fd+foreign import ccall "asyncinput.h" disable_timers :: IO ()++startProcess cmd doIn doOut doErr =+ do inPipe <- optPipe doIn+ outPipe <- optPipe doOut+ errPipe <- optPipe doErr+-- pid <- _ccall_ fork+ pid <- fork+ case pid::Int of+ -1 -> failu "fork" -- use tryP instead+ 0 -> do -- child process+ -- Disable virtual timer, used by the GHC RTS+ disable_timers+ optDupIn 0 inPipe+ optDupOut 1 outPipe+ optDupOut 2 errPipe+ binsh <- marshallString "/bin/sh"+ sh <- marshallString "sh"+ dashc <- marshallString "-c"+ ccmd <- marshallString cmd+ execl binsh sh dashc ccmd (0::Int)+ --_ccall_ _exit 1+ failu "execl"+ _ -> do -- parent process+ inS <- optPipeIn inPipe+ outS <- optPipeOut outPipe+ errS <- optPipeOut errPipe+ return $ SocketResponse $ ProcessSockets inS outS errS+ where+ optPipe False = return Nothing+ optPipe True = Just `fmap` newPipe+ newPipe = do pa <- newArray 2+ ok <- pipe (addrOf (pa::CInt32))+ [p0,p1] <- readArray pa 2+ freePtr pa+ when (ok/=0) $ failu "pipe" -- use tryP instead+ return (p0,p1)++ optDupIn d = optDupOut d . fmap swap+ optDupOut d = maybe (return ()) (dupOut d)+ dupOut d (p0,p1) = do cclose d+ dup p1+ cclose p0+ cclose p1+ return ()++ optPipeIn = optPipeS "w" . fmap swap+ optPipeOut = optPipeS "r"+ optPipeS m = maybe (return Nothing) (fmap Just . pipeS m)+ pipeS m (p0,p1) = do cclose p1+ fmap So (getfilep p0 m)+ ++foreign import ccall "unistd.h close" cclose :: Int32 -> IO Int32
+ hsrc/ghc-dialogue/CSizes.hs view
@@ -0,0 +1,6 @@+{-# LANGUAGE CPP #-}+module CSizes where++#define CSIZE(ctype) foreign import ccall "cfuns.h" fudsizeof_/**/ctype :: Int++#include "csizes.h"
+ hsrc/ghc-dialogue/CString16.hs view
@@ -0,0 +1,16 @@+module CString16 where+import Marshall++-- A quick hack...++type CString16 = CString -- !!++marshallString16 s = marshallString16' s (length s)++marshallString16' s n = marshallString' (split s) (2*n)+ where+ split [] = []+ split (c:cs) = toEnum (i `div` 256):toEnum (i `mod` 256):split cs+ where i = fromEnum c++-- unmarshallString16 = ...
+ hsrc/ghc-dialogue/ContinuationIO.hs view
@@ -0,0 +1,169 @@+module ContinuationIO{-(module ContinuationIO, module DialogueIO)-} where+--import DialogueIO+--import XStuff+--import P_IO_data hiding (Bin)+--import Prelude hiding (IOError,appendFile,interact,print,readFile,writeFile)+{-+type SuccCont = Dialogue+type StrCont = String -> Dialogue+type BinCont = Bin -> Dialogue+type FailCont = IOError -> Dialogue+type StrListCont = [String] -> Dialogue+type Bin = ()+-}+stdin = "stdin"+stdout = "stdout"+stderr = "stderr"+{-+done :: Dialogue+readFile :: String -> FailCont -> StrCont -> Dialogue+writeFile :: String -> String -> FailCont -> SuccCont -> Dialogue+appendFile :: String -> String -> FailCont -> SuccCont -> Dialogue+--readBinFile :: String -> FailCont -> BinCont -> Dialogue+--writeBinFile :: String -> Bin -> FailCont -> SuccCont -> Dialogue+--appendBinFile :: String -> Bin -> FailCont -> SuccCont -> Dialogue+deleteFile :: String -> FailCont -> SuccCont -> Dialogue+statusFile :: String -> FailCont -> StrCont -> Dialogue+readChan :: String -> FailCont -> StrCont -> Dialogue+appendChan :: String -> String -> FailCont -> SuccCont -> Dialogue+--readBinChan :: String -> FailCont -> BinCont -> Dialogue+--appendBinChan :: String -> Bin -> FailCont -> SuccCont -> Dialogue+echo :: Bool -> FailCont -> SuccCont -> Dialogue+getArgs :: FailCont -> StrListCont -> Dialogue+getEnv :: String -> FailCont -> StrCont -> Dialogue+setEnv :: String -> String -> FailCont -> SuccCont -> Dialogue+getProgName :: FailCont -> StrCont -> Dialogue+readFileScattered :: String -> [Int] -> FailCont -> StrListCont -> Dialogue++done resps = []++readFile name fail succ resps =+ ReadFile name : strDispatch fail succ resps++readFileScattered name offs fail succ resps =+ ReadFileScattered name offs : strListDispatch fail succ resps++writeFile name contents fail succ resps =+ WriteFile name contents : succDispatch fail succ resps++appendFile name contents fail succ resps =+ AppendFile name contents : succDispatch fail succ resps++{-+readBinFile name fail succ resps =+ ReadBinFile name : binDispatch fail succ resps++writeBinFile name contents fail succ resps =+ WriteBinFile name contents : succDispatch fail succ resps++appendBinFile name contents fail succ resps =+ AppendBinFile name contents : succDispatch fail succ resps++readBinChan name fail succ resps =+ ReadBinChan name : binDispatch fail succ resps++appendBinChan name contents fail succ resps =+ AppendBinChan name contents : succDispatch fail succ resps+-}++deleteFile name fail succ resps =+ DeleteFile name : succDispatch fail succ resps++statusFile name fail succ resps =+ StatusFile name : strDispatch fail succ resps++readChan name fail succ resps =+ ReadChan name : strDispatch fail succ resps++appendChan name contents fail succ resps =+ AppendChan name contents : succDispatch fail succ resps++echo bool fail succ resps =+ Echo bool : succDispatch fail succ resps++getArgs fail succ resps =+ GetArgs : strListDispatch fail succ resps++getProgName fail succ resps =+ GetProgName : strDispatch fail succ resps++getEnv name fail succ resps =+ GetEnv name : strDispatch fail succ resps++setEnv name val fail succ resps =+ SetEnv name val : succDispatch fail succ resps+++strDispatch fail succ (resp:resps) = case resp of + Str val -> succ val resps+ Failure msg -> fail msg resps++binDispatch fail succ (resp:resps) = case resp of + Bn val -> succ val resps+ Failure msg -> fail msg resps++succDispatch fail succ (resp:resps) = case resp of+ Success -> succ resps+ Failure msg -> fail msg resps++strListDispatch fail succ (resp:resps) = case resp of+ StrList val -> succ val resps+ Failure msg -> fail msg resps+++abort :: FailCont+abort msg = done++exit :: FailCont+exit err = appendChan stderr (msg ++ "\n") abort done+ where msg = case err of ReadError s -> s+ WriteError s -> s+ SearchError s -> s+ FormatError s -> s+ OtherError s -> s++print :: (Show a) => a -> Dialogue+print x = appendChan stdout (show x) exit done+prints :: (Show a) => a -> String -> Dialogue+prints x s = appendChan stdout (shows x s) exit done++interact :: (String -> String) -> Dialogue+interact f = readChan stdin exit+ (\x -> appendChan stdout (f x) exit done)++------------------------------------ hbc bonus+type DblCont = Double -> Dialogue++sleep :: Double -> FailCont -> SuccCont -> Dialogue+changeDirectory :: String -> FailCont -> SuccCont -> Dialogue+getTime :: FailCont -> DblCont -> Dialogue+deleteDirectory :: String -> FailCont -> SuccCont -> Dialogue+readDirectory :: String -> FailCont -> StrListCont -> Dialogue+getCpuTime :: FailCont -> DblCont -> Dialogue+getLocalTime :: FailCont -> DblCont -> Dialogue+readDirectory name fail succ resps =+ ReadDirectory name : strListDispatch fail succ resps++getLocalTime fail succ resps =+ GetLocalTime : dblDispatch fail succ resps++sleep dbl fail succ resps =+ Sleep dbl : succDispatch fail succ resps++changeDirectory str fail succ resps =+ ChangeDirectory str : succDispatch fail succ resps++deleteDirectory str fail succ resps =+ DeleteDirectory str : succDispatch fail succ resps++getTime fail succ resps =+ GetTime : dblDispatch fail succ resps++getCpuTime fail succ resps =+ GetCpuTime : dblDispatch fail succ resps++dblDispatch fail succ (resp:resps) = case resp of + Dbl val -> succ val resps+ Failure msg -> fail msg resps++-}
+ hsrc/ghc-dialogue/DialogueIO.hs view
@@ -0,0 +1,21 @@+-- | Haskell 1.2 Dialogue I/O+module DialogueIO(Request(..), Response(..), IOError(..)+ , Dialogue(..), SigAct(..) , dialogueToIO+ --, module _LibDialogue+ ) where+import Prelude hiding (IOError)+import P_IO_data+import DoRequest+import Control.Concurrent.Chan++-- | Included just to illustrate that it is possible to convert a Dialogue+-- IO function to a monadic IO function. The implementation relies on+-- 'getChanContents' to construct the lazy list of responses needed by+-- the dialogue IO function.+dialogueToIO :: Dialogue -> IO ()+dialogueToIO f =+ do st <- initXCall+ respchan <- newChan+ reqs <- f `fmap` getChanContents respchan+ let doReq req = writeChan respchan =<< doRequest st req+ mapM_ doReq reqs
+ hsrc/ghc-dialogue/DoRequest.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE CPP #-}+module DoRequest(XCallState,initXCall,doRequest,getAsyncInput) where+import Control.Applicative+--import DialogueIO+import P_IO_data+import ContinuationIO(stdin,stdout,stderr)+import qualified System.IO as IO+import System.Environment as IO(getEnv,getProgName)+import System.Process as IO(system)+import System.Exit as IO+import qualified IOUtil as IO+import System.IO(openBinaryFile,withBinaryFile,IOMode(..),hPutStr,hGetContents)+import System.Directory+#ifdef VERSION_old_time+import System.Time(getClockTime,toCalendarTime)+#endif+#ifdef VERSION_time+import Data.Time(getCurrentTime,getZonedTime)+#endif++import DoXCommand+import DoXRequest+import AsyncInput(XCallState,initXCall,getAsyncInput',doSelect,doSocketRequest)+import CmdLineEnv(argFlag)++--import System+import Prelude hiding (IOError)++--import Ap++deb = argFlag "dorequest" False++doRequest =+ if not deb+ then doRequest'+ else \state req -> do+ eprint req+ resp <- doRequest' state req+ eprint resp+ return resp+ where+ eprint x = IO.hPutStrLn IO.stderr . take 239 . show $ x++doRequest' :: XCallState -> Request -> IO Response+doRequest' state req =+ case req of+ ReadFile filename -> rdCatch (readFile filename)+ WriteFile filename contents -> wrCatch (writeFile filename contents)+ ReadBinaryFile filename -> rdCatch (readBinaryFile filename)+ WriteBinaryFile filename contents ->+ wrCatch (writeBinaryFile filename contents)+ AppendFile filename contents -> wrCatch (appendFile filename contents)+ StatusFile filename -> catchIo SearchError (statusFile filename)+ where+ statusFile path =+ do f <- doesFileExist path+ if f then permissions 'f' path+ else do d <- doesDirectoryExist path+ if d then permissions 'd' path+ else fail path+ permissions t path =+ do p <- getPermissions path+ let r = if readable p then 'r' else '-'+ w = if writable p then 'w' else '-'+ return (Str [t,r,w])+ RenameFile from to -> otCatch (renameFile from to>>ok)+ GetCurrentDirectory -> Str <$> getCurrentDirectory+#ifdef VERSION_old_time+ GetModificationTime path -> catchIo SearchError (ClockTime <$> IO.getModificationTime path)+#else+ GetModificationTime path -> catchIo SearchError (UTCTime <$> IO.getModificationTime path)+#endif+ ReadDirectory dir -> rdCatch' StrList (getDirectoryContents dir)+ DeleteFile filename -> otCatch (removeFile filename>>ok)+ CreateDirectory path mask -> otCatch (createDirectory path>>ok)+ ReadXdgFile xdg path -> rdCatch $+ do dir <- getAppXdgDir xdg+ readFile (dir++"/"++path)+ WriteXdgFile xdg path s -> wrCatch $+ do dir <- getAppXdgDir xdg+ createDirectoryIfMissing True dir+ writeFile (dir++"/"++path) s+ ReadChan channelname ->+ if channelname==stdin+ then rdCatch getContents+ else rfail $ ReadError $ "ReadChan: unknown channel "++channelname+ AppendChan channelname contents+ | channelname==stdout -> wr IO.stdout+ | channelname==stderr -> wr IO.stderr+ | otherwise -> rfail $ WriteError $ "AppendChan: unknown channel "++channelname+ where wr chan = wrCatch (IO.hPutStr chan contents>>IO.hFlush chan)+ XRequest r -> otCatch $ XResponse <$> doXRequest r+ XCommand c -> otCatch $ (doXCommand c >> ok)+ GetAsyncInput -> getAsyncInput state+ SocketRequest r -> otCatch $ doSocketRequest state r+ Select dl -> otCatch $ doSelect state dl+ Exit n -> exitWith (if n==0 then ExitSuccess else ExitFailure n)+#ifdef VERSION_old_time+ GetLocalTime -> otCatch $ do+ CalendarTime <$> (toCalendarTime =<< getClockTime)+ --s <- readIO (formatCalendarTime undefined "%s" t)+ --GHC bug(?) workaround:+ --let s = ctSec t+60*(ctMin t+60*(ctHour t))+ --return (Dbl (fromIntegral s))+ GetTime -> otCatch $ ClockTime <$> getClockTime+ ToCalendarTime t -> CalendarTime <$> toCalendarTime t+#endif+ GetEnv var -> catchIo SearchError (Str <$> getEnv var)+ System cmd -> do exitcode <- system cmd+ case exitcode of+ ExitSuccess -> ok+ ExitFailure n -> rfail $ OtherError $ "System: Return code="++show n+#ifdef VERSION_time+ GetCurrentTime -> otCatch $ UTCTime <$> getCurrentTime+ GetZonedTime -> otCatch $ ZonedTime <$> getZonedTime+#endif+ _ -> do IO.hPutStrLn IO.stderr msg+ rfail $ OtherError msg+ where msg = "doRequest: unimplemented request: "++show req++ok = return Success+rfail = return . Failure++getAsyncInput state = otCatch $ getAsyncInput' state++rdCatch = rdCatch' Str+rdCatch' c io = catchIo ReadError (c <$> io)+wrCatch io = catchIo WriteError (io >> ok)+otCatch = catchIo OtherError+catchIo e io = IO.catch io (rfail . e . show)++---- Should be put elsewhere:+-- #ifndef __GLASGOW_HASKELL__+-- instance Functor IO where map f io = io >>= (return . f)+-- #endif++--+readBinaryFile path = hGetContents =<< openBinaryFile path ReadMode+writeBinaryFile path s = withBinaryFile path WriteMode (flip hPutStr s)++getAppXdgDir xdg = getXdgDirectory xdg =<< getProgName
+ hsrc/ghc-dialogue/DoXCommand.hs view
@@ -0,0 +1,366 @@+{-# LANGUAGE CPP #-}+{- unused options -optc-I/usr/X11R6/include -#include <X11/Xlib.h> -#include <X11/Xutil.h> -fvia-C -}+-- -O+module DoXCommand(doXCommand) where++import Command+import Event+import Geometry+import Xtypes+--import Font+--import ResourceIds+import DrawTypes+import HbcUtils(chopList)++import DoXRequest(getGCValues,translateCoordinates)+import XCallTypes+import StructFuns+import Xlib+import Marshall+import MyForeign+--import CCall+import CString16++import System.IO(hPutStr,hPutStrLn,stderr) -- for error reporting++import PackedString(lengthPS,unpackPS)+--import Word(Word32)+import Data.Bits++--import IO(hFlush,stdout) -- debugging++default (Int)++{-+#include "newstructfuns.h"+-}+-- For debugging only:+{-+doXCommand req@(d,_,_) =+ do r <- doXCommand' req+ --hFlush stdout+ xSync d False+ return r+--}+--doXCommand cmd@(display,_,_) = withLockedDisplay display $ doXCommand' cmd++doXCommand :: (Display, Window, XCommand) -> IO ()+doXCommand (d,w,req) =+ case req of+ CloseDisplay d -> xCloseDisplay d+ DestroyWindow -> xDestroyWindow d w+ MapRaised -> xMapRaised d w+ LowerWindow -> xLowerWindow d w+ UnmapWindow -> xUnmapWindow d w+ ClearWindow -> xClearWindow d w+ StoreName s -> xStoreName d w s+ FreeGC gc -> xFreeGC d gc+ UngrabPointer -> xUngrabPointer d currentTime+ Flush -> xFlush d+ ClearArea (Rect (Point x y) (Point wi he)) exposures ->+ xClearArea d w x y wi he exposures+ GrabButton oe button ms evm ->+ xGrabButton d (toC button) anyModifier w oe (toC evm) grabModeAsync grabModeAsync windowNone cursorNone+ UngrabButton b ms ->+ --_casm_ ``XUngrabButton(%0,%1,AnyModifier,%2);'' d (toC b) w+ xUngrabButton d (toC b) anyModifier w+ FreePixmap p -> xFreePixmap d p+ Draw drawable gc cmd -> doDrawCommand (getdr drawable) gc cmd+ DrawMany drawable gccmds -> mapM_ doDrawMany gccmds+ where+ dr = getdr drawable+ doDrawMany (gc,cmds) = mapM_ (doDrawCommand dr gc) cmds+ ChangeGC gc gcattrs -> do+ (gcvals,mask) <- getGCValues gcattrs+ xChangeGC d gc mask gcvals+ ChangeWindowAttributes was -> do+ (attrs,mask) <- getWindowAttributes was+ --putStr "CWA mask ";print mask+ xChangeWindowAttributes d w mask attrs+ ConfigureWindow wc -> do+ (chgs,mask) <- getWindowChanges wc+ xConfigureWindow d w mask chgs+ SetNormalHints (Point x y) -> do+ h <- newXSizeHints + SET(XSizeHints,Int,h,x,x)+ SET(XSizeHints,Int,h,y,y)+ SET(XSizeHints,Int,h,flags,CCONST(USPosition)::Int)+ xSetNormalHints d w h+ freePtr h+ SetWMHints i -> do+ h <- newXWMHints+ SET(XWMHints,Int,h,flags,CCONST(InputHint)::Int)+ SET(XWMHints,Int,h,input,toC i)+ xSetWMHints d w h+ freePtr h+ ShapeCombineMask kind (Point x y) p op ->+ xShapeCombineMask d w kind x y p op+ ShapeCombineRectangles kind (Point x y) rs op ord -> do+ (rsa,size) <- storeRectangles rs+ xShapeCombineRectangles d w kind x y rsa size op ord+ freePtr rsa+ ShapeCombineShape dst (Point x y) p src op ->+ xShapeCombineShape d w dst x y p src op+ --RmDestroyDatabase RmDatabase |+ --RmCombineDatabase RmDatabase RmDatabase Bool |+ --RmPutLineResource RmDatabase String |+ SetWMProtocols atoms -> xSetWMProtocols d w atoms (length atoms)+ SendEvent dst propagate evm e -> do+ xe <- getEvent dst e+ status <- xSendEvent d dst propagate (fromIntegral $ toC evm) xe+ return ()+ SetSelectionOwner getit sel ->+ xSetSelectionOwner d sel (if getit then w else windowNone) currentTime+ ConvertSelection (Selection s t p) ->+ xConvertSelection d s t p w currentTime+ ChangeProperty w p t form@8 mode s -> -- !!+ xChangeProperty d w p t form mode s (length s)+ FreeColors cm pixls planes ->+ do cmid <- dcmap d cm+ (pxarr,size) <- toArray [fromIntegral p|Pixel p<-pixls] -- hmm+ xFreeColors d cmid pxarr size planes+ ReparentWindow newParent0 ->+ do newParent <- if newParent0==rootWindow+ then xDefaultRootWindow d+ else return newParent0+ mp <- translateCoordinates d w newParent+ case mp of+ Nothing -> hPutStr stderr "XTranslateCoordinates: windows on different screens!\n"+ Just (Point x y) -> xReparentWindow d w newParent x y+ --WarpPointer Point |+ SetRegion gc r -> -- !!! modifies a GC -- cache problems!+ do (rsa,_) <- storeRectangles [r]+ r <- xCreateRegion+ xUnionRectWithRegion rsa r r+ xSetRegion d gc r+ xDestroyRegion r+ freePtr rsa+ --AddToSaveSet |+ --RemoveFromSaveSet + Bell n -> xBell d n++ _ -> hPutStr stderr (notImplemented req)+ where getdr = getdrawable w++ doDrawCommand drw gc cmd = case cmd of+ DrawLine (Line (Point x1 y1) (Point x2 y2)) -> + xDrawLine d drw gc x1 y1 x2 y2+ DrawImageString (Point x y) s ->+ xDrawImageString d drw gc x y s (length s)+ DrawString (Point x y) s ->+ xDrawString d drw gc x y s (length s)+ DrawImageString16 (Point x y) s ->+ do let n = length s+ cs <- marshallString16' s n+ xDrawImageString16 d drw gc x y cs n+ DrawString16 (Point x y) s ->+ do let n = length s+ cs <- marshallString16' s n+ xDrawString16 d drw gc x y cs n+ DrawRectangle (Rect (Point x1 y1) (Point x2 y2)) ->+ xDrawRectangle d drw gc x1 y1 x2 y2+ FillRectangle (Rect (Point x1 y1) (Point x2 y2)) ->+ xFillRectangle d drw gc x1 y1 x2 y2+ FillPolygon shape coordmode ps -> do+ (xpoints,size) <- storePoints ps+ xFillPolygon d drw gc xpoints size shape coordmode+ freePtr xpoints+ DrawLines coordmode ps -> do+ (xpoints,size) <- storePoints ps+ xDrawLines d drw gc xpoints size coordmode+ freePtr xpoints+ DrawArc (Rect (Point x y) (Point wi he)) a1 a2 ->+ xDrawArc d drw gc (f x) (f y) (f wi) (f he) (f a1) (f a2)+ where f = fromIntegral+ FillArc (Rect (Point x y) (Point wi he)) a1 a2 ->+ xFillArc d drw gc (f x) (f y) (f wi) (f he) (f a1) (f a2)+ where f = fromIntegral+ CopyArea src (Rect (Point srcx srcy) (Point wi he))+ (Point dstx dsty) ->+ xCopyArea d (getdr src) drw gc (i32 srcx) (i32 srcy) (u32 wi) (u32 he) (i32 dstx) (i32 dsty)+ CopyPlane src (Rect (Point srcx srcy) (Point wi he)) + (Point dstx dsty) plane ->+ --print (gc,drw,cmd) >>+ xCopyPlane d (getdr src)+ drw gc (f srcx) (f srcy) (f wi) (f he)+ (f dstx) (f dsty) (shiftL 1 plane)+ -- >>putStrLn "done"+ where f = fromIntegral+ DrawPoint (Point x y) -> xDrawPoint d drw gc x y+ CreatePutImage rect format pixels -> createPutImage drw gc rect format pixels+ DrawImageStringPS (Point x y) s ->+ xDrawImageString d drw gc x y (unpackPS s) (lengthPS s) -- !!+ DrawStringPS (Point x y) s ->+ xDrawString d drw gc x y (unpackPS s) (lengthPS s) -- !!+ _ -> hPutStr stderr (notImplemented cmd)++ createPutImage drw gc rect@(Rect (Point x y) (Point w h)) (ImageFormat format) pixels =+ do --hPutStrLn stderr $ "Entering createPutImage "++show rect+ screen <- xDefaultScreen d+ depth <- xDefaultDepth d screen+ bpp <- default_bpp d depth+ --hPutStrLn stderr ("bpp="++show bpp)+ let byte_depth = (depth+7) `div` 8+ bytes_pp = (bpp+7) `div` 8+ bitmap_pad = 32+ bytes_per_line = ((w*bytes_pp+3) `div` 4) * 4 -- assumes bitmap_pad == 32+ nullCount = bytes_per_line - w*bytes_pp+ size= w*h+ pxlines = chopList (splitAt w) pixels+ byteOrder <- xImageByteOrder d+#if 1+ -- High level solution, not fast enough:+ let pxlToBytes = if byteOrder==LSBFirst then lsb else msb+ msb (Pixel p) = pad ++ reverse (lsb' byte_depth (fromIntegral p))+ pad = replicate (bytes_pp-byte_depth) '\0'+ lsb (Pixel p) = lsb' byte_depth (fromIntegral p) ++ pad+ lsb' 0 _ = []+ lsb' n p = toEnum (p `mod` 256) : lsb' (n-1) (p `div` 256)+ linePad = replicate nullCount '\0'+ byteLine pxls = concatMap pxlToBytes pxls ++ linePad+ bytes = concatMap byteLine pxlines+ --imgdata = psToByteArray (packString bytes)+ --hPutStrLn stderr "Checkpoint 1 in createPutImage"+ --hPutStrLn stderr $ "nullCount="++show nullCount+#else+ -- Low level solution, faster, but still not fast enough:+ imgdata <- stToIO $ newCharArray (1,bytes_per_line*h)+ let convImage = convLines 0 pixels+ convLines y pixels | y>=h = return ()+ | otherwise =+ do pixels' <- convLine y pixels+ convLines (y+1) pixels'+ convLine y pixels = convPixels (y*bytes_per_line) 0 pixels+ convPixels i x pixels | x>=w = return pixels+ convPixels i x (Pixel p:pixels) =+ do convPixel i p+ convPixels (i+bytes_pp) (x+1) pixels+ convPixel =+ if byteOrder==(CCONST(LSBFirst)::Int)+ then convPixelLSB+ else convPixelMSB+ convPixelLSB i p =+ pixelBytes i p byte_depth+ -- pad with zeros?+ where+ pixelBytes i p 0 = return ()+ pixelBytes i p n =+ do SINDEX(char,imgdata,i::Int,p::Int)+ pixelBytes (i+1) (p `div` 256) (n-1)+ convPixelMSB i p =+ do let i' = i+bytes_pp-1+ -- pad with zeros?+ pixelBytes i' p bytes_pp+ where+ pixelBytes i p 0 = return ()+ pixelBytes i p n =+ do SINDEX(char,imgdata,i::Int,p::Int)+ pixelBytes (i-1) (p `div` 256) (n-1)+ + in convImage+#endif+ dv <- xDefaultVisual d screen+ --hPutStrLn stderr "Checkpoint 2 in createPutImage"+ --if bytes==bytes then return () else undefined+ --hPutStrLn stderr "Checkpoint 3 in createPutImage"+ cbytes <- marshallString' bytes (h*bytes_per_line)+ image <- xCreateImage d dv depth format 0 cbytes w h bitmap_pad bytes_per_line+ --hPutStrLn stderr $ "Checkpoint 4 in createPutImage "++show image+ xPutImage d drw gc image 0 0 (i32 x) (i32 y) (i32 w) (i32 h)+-- ioCmd $ _casm_ ``((XImage *)(%0))->data=NULL;XDestroyImage((XImage *)%0);'' image+ --_casm_ ``((XImage *)(%0))->data=NULL;'' image+ --hPutStrLn stderr "Checkpoint 5 in createPutImage"+ setXImage_data image nullAddr+ --hPutStrLn stderr "Checkpoint 6 in createPutImage"+ xDestroyImage image+ --hPutStrLn stderr "Checkpoint 7 in createPutImage"+ freePtr cbytes+ --hPutStrLn stderr "Returning from createPutImage"+{-+ default_bpp :: Display -> Int -> IO Int+ default_bpp (Display display) depth =+ _casm_+ ``{int i,cnt,bpp;+ XPixmapFormatValues *ps=XListPixmapFormats(%0,&cnt);+ bpp=%1; /* Hmm. Something is wrong if depth isn't found. */+ for(i=0;i<cnt;i++)+ if(ps[i].depth==%1) {+ bpp=ps[i].bits_per_pixel;+ break;+ }+ XFree(ps);+ %r=bpp;}'' display depth+-}+foreign import ccall "asyncinput.h" default_bpp :: Display -> Int -> IO Int+foreign import ccall "asyncinput.h" setXImage_data :: CXImage -> Addr -> IO ()++i32 :: Int->Int32+i32 = toEnum+u32 :: Int->Unsigned32+u32 = toEnum++getWindowAttributes = getValues newXSetWindowAttributes getWindowAttribute+ where+ getWindowAttribute swa wa =+ case wa of+ CWEventMask em -> (SETWa(swa,event_mask,toC em),CWORD32(CWEventMask))+ CWBackingStore bs -> (SETWa(swa,backing_store,toC bs),CWORD32(CWBackingStore))+ CWSaveUnder b -> (SETWa(swa,save_under,toC b),CWORD32(CWSaveUnder))+ CWDontPropagate em -> (SETWa(swa,do_not_propagate_mask,toC em),CWORD32(CWDontPropagate))+ CWOverrideRedirect b -> (SETWa(swa,override_redirect,toC b),CWORD32(CWOverrideRedirect))+ CWBackPixel p -> (SETWa(swa,background_pixel,toC p),CWORD32(CWBackPixel))+ CWCursor c -> (SETWaXID(swa,cursor,toXID c),CWORD32(CWCursor))+ CWBitGravity g -> (SETWa(swa,bit_gravity,toC g),CWORD32(CWBitGravity))+ CWWinGravity g -> (SETWa(swa,win_gravity,toC g),CWORD32(CWWinGravity))+ CWBackPixmap p -> (SETWaXID(swa,background_pixmap,toXID p),CWORD32(CWBackPixmap))+ CWBorderPixmap p -> (SETWaXID(swa,border_pixmap,toXID p),CWORD32(CWBorderPixmap))+ CWBorderPixel p -> (SETWa(swa,border_pixel,toC p),CWORD32(CWBorderPixel) :: Bitmask)+ -- _ -> (return (),0) -- to skip unimplemented fields++getWindowChanges = getValues newXWindowChanges getWindowChange where+ getWindowChange s wc = case wc of+ CWX x -> (SET(XWindowChanges,Int,s,x,x),CWORD32(CWX))+ CWY y -> (SET(XWindowChanges,Int,s,y,y),CWORD32(CWY))+ CWWidth w -> (SET(XWindowChanges,Int,s,width,w),CWORD32(CWWidth))+ CWHeight h -> (SET(XWindowChanges,Int,s,height,h),CWORD32(CWHeight))+ CWBorderWidth w -> (SET(XWindowChanges,Int,s,border_width,w),CWORD32(CWBorderWidth))+ CWStackMode sm -> (SET(XWindowChanges,Int,s,stack_mode,toC sm),CWORD32(CWStackMode) :: Bitmask) ++{- deriving toEnum & fromEnum appears broken (not anymore /TH 2000-11-28) -}++instance ToC CoordMode where toC = getEnum CoordModeOrigin+instance ToC Shape where toC = getEnum Complex+instance ToC BackingStore where toC = getEnum NotUseful+instance ToC Gravity where toC = getEnum ForgetGravity+instance ToC StackMode where toC = getEnum StackAbove+instance ToC ShapeKind where toC = getEnum ShapeBounding+instance ToC ShapeOperation where toC = getEnum ShapeSet+instance ToC Ordering' where toC = getEnum Unsorted++instance ToC Button where toC AnyButton = CCONST(AnyButton)+ toC (Button i) = i++getEvent w e = do+ xe <- newXEvent+ SET(XAnyEvent,Window,xe,window,w::Window)+ case e of+ SelectionNotify time (Selection sel target props) -> do+ SET(XSelectionEvent,Int,xe,type,CCONST(SelectionNotify)::Int)+ SET(XSelectionEvent,Atom,xe,selection, sel)+ SET(XSelectionEvent,Atom,xe,target, target)+ SET(XSelectionEvent,Atom,xe,property, props)+ SET(XSelectionEvent,Time,xe,time,time)+ return xe+++storePoints ps = getArray newXPointArray+ (\xpoints (i,Point x y) -> do SETI(XPoint,Int,xpoints,i,x,x)+ SETI(XPoint,Int,xpoints,i,y,y)) ps++storeRectangles rs =+ getArray newXRectangleArray+ (\rsa (i,Rect (Point x y) (Point w h)) -> do+ SETI(XRectangle,Int,rsa,i,x,x)+ SETI(XRectangle,Int,rsa,i,y,y)+ SETI(XRectangle,Int,rsa,i,width,w)+ SETI(XRectangle,Int,rsa,i,height,h)) rs
+ hsrc/ghc-dialogue/DoXRequest.hs view
@@ -0,0 +1,488 @@+{-# LANGUAGE CPP #-}+{- Obsolete OPTIONS -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/extensions/Xdbe.h> -fvia-C -}+-- -optc-I/usr/X11R6/include+module DoXRequest(doXRequest,getGCValues,translateCoordinates) where++--import P_IO_data(Request(..),Response(..))+import Geometry+import Command+import Event+import Xtypes+import Font+--import ResourceIds+import Visual+import HbcWord(intToWord) -- for Visual+import IOUtil(getEnvi)+--import CmdLineEnv(argFlag)++import XCallTypes+import StructFuns+import Xlib+import Marshall+import MyForeign -- debugging+import CString16++--import Ap++{-+#include "newstructfuns.h"+-}++newXID = newPtr :: IO CXID+newLong = newPtr :: IO CLong+newLongs n = sequence (replicate n newLong)+readLong = readCVar :: CLong -> IO Int+newInt32 = newPtr :: IO CInt32+newInt32s n = sequence (replicate n newInt32)+readInt32 = readCVar :: CInt32 -> IO Int32+freePtrs xs = mapM_ freePtr xs++--synchronize = argFlag "synchronize" False++{-+doXRequest req@(display,_,_) =+ do r <- doXRequest' req+ if synchronize && display/=noDisplay then xSync display False else return ()+ return r+-}+{-+doXRequest req@(display,_,_) | display/=noDisplay =+ withLockedDisplay display $ doXRequest' req+doXRequest req = doXRequest' req+-}+doXRequest (d@display,wi,req) =+ case req of+ OpenDisplay optname ->+ do name <- if null optname+ then case getEnvi "DISPLAY" of+ Just n -> return n+ Nothing -> failu "DISPLAY variable is not set"+ else return optname+ d <- xOpenDisplay name+ --xSynchronize d synchronize -- has no effect?!+ return (DisplayOpened d)+ CreateSimpleWindow p r -> WindowCreated <$> createWindow wi r+ CreateRootWindow r resname -> WindowCreated <$> do+ dr <- xDefaultRootWindow display+ this <- createWindow dr r+ setClassHint display this resname "Fudgets"+ /* This is a hack that solves a focus problem with twm.+ The twm option NoTitleFocus also solves the problem. */+ -- xSetWMHints display this InputHint True+ return this+ CreateGC dr oldgc gcattrs -> GCCreated <$> do+ wi' <- if wi == noWindow then xDefaultRootWindow display else return wi+ gcvals <- getGCValues gcattrs+ gc <- createGC display (getdrawable wi' dr)+ if oldgc == rootGC then do+ screen <- xDefaultScreen display+ xSetForeground display gc =<< xBlackPixel display screen+ xSetBackground display gc =<< xWhitePixel display screen+ else copyGC display oldgc gc+ changeGC display gc gcvals+ return gc+ LoadFont fn -> FontLoaded <$> xLoadFont display fn+ CreateFontCursor shp -> CursorCreated <$> xCreateFontCursor display shp+ GrabPointer b evm ->+ PointerGrabbed <$> xGrabPointer display wi b (toC evm)+ grabModeAsync grabModeAsync windowNone cursorNone currentTime+ AllocNamedColor cm cn ->+ ColorAllocated <$> (allocNamedColor display cn =<< dcm cm)+ AllocColor cm rgb ->+ ColorAllocated <$> (allocColor display rgb =<< dcm cm)+ CreatePixmap (Point w h) depth -> PixmapCreated <$> do+ depth' <- if depth == copyFromParent+ then xDefaultDepth display =<< xDefaultScreen display+ else return depth+ WindowId wi' <- if wi == noWindow then xDefaultRootWindow display else return wi+ xCreatePixmap display (DrawableId wi') w h depth'+ ReadBitmapFile filename -> do+ bm <- newXID+ ints@[w,h,xhot,yhot] <- newInt32s 4+ WindowId root <- xDefaultRootWindow display+ cfilename <- marshallString filename -- GHC gives faulty code for marshallM?+ --putStrLn "about to call xReadBitmapFile"+ --writeCVar xhot 0+ --putStrLn filename+ --putStrLn =<< unmarshall cfilename+ --print =<< readLong xhot+ r <- xReadBitmapFile display (DrawableId root) cfilename w h bm xhot yhot+ --putStrLn "returned from call to xReadBitmapFile"+ freePtr cfilename -- crash?!!+ --putStrLn "about to read xhot"+ x <- fromIntegral <$> readInt32 xhot+ --putStr "xhot =";print x+ ret <-+ if (r::Int) == CCONST(BitmapSuccess) then do+ hot <- if x == -1 then return Nothing + else Just . Point x . fromIntegral <$> readInt32 yhot+ BitmapReturn+ <$> (Point <$> (fromIntegral <$> readInt32 w) <*> (fromIntegral <$> readInt32 h))+ <*> return hot + <*> (PixmapId <$> readCVar bm)+ else return BitmapBad+ --putStrLn "about to free int parameters"+ freePtrs ints+ freePtr bm+ return (BitmapRead ret)+ CreateBitmapFromData (BitmapData size@(Point w h) hot bytes) ->+ do cbytes <- marshallString' (map toEnum bytes) (((w+7) `div` 8)*h)+ WindowId wi' <- if wi == noWindow then xDefaultRootWindow display else return wi+ let cw = fromIntegral w+ ch = fromIntegral h+ pm <- xCreateBitmapFromData display (DrawableId wi') cbytes cw ch+ freePtr cbytes+ return (BitmapRead (BitmapReturn size hot pm))+ --RmGetStringDatabase str ->+ --RmGetResource rmd s1 s2 ->+ TranslateCoordinates ->+ do rootwin <- xDefaultRootWindow display+ CoordinatesTranslated . maybe origin id+ <$> translateCoordinates display wi rootwin+ InternAtom str b -> GotAtom <$> xInternAtom display str b++ GetAtomName a -> + do at_ret <- xGetAtomName display a+ if (at_ret == nullStr)+ then return (GotAtomName Nothing)+ else+ do at_name <- unmarshallString at_ret+ xFree at_ret+ -- putStrLn at_name+ case (length at_name) of+ 0 -> return (GotAtomName Nothing)+ _ -> return (GotAtomName $ Just at_name)++ GetWindowProperty offset property delete req_type ->+ do let length = 1000 + actual_type <- newPtr+ actual_format <- newPtr+ nitems <- newLong+ bytes_after <- newLong+ prop_return <- newCString+ xGetWindowProperty display wi property offset+ (length `div` (4::Int)) delete req_type+ actual_type actual_format nitems bytes_after prop_return+ at <- readCVar actual_type+ af <- readCVar actual_format+ n <- readLong nitems+ ba <- readLong bytes_after+ str <- if (af::Int) == CCONST(None) then return "" else+ do let got = af*n `div` 8+ cstr <- readCVar prop_return+ str <- unmarshallString' cstr got+ xFree cstr+ return str+ freePtr actual_type+ freePtr actual_format+ freePtr nitems+ freePtr bytes_after+ freePtr prop_return+ return $ GotWindowProperty at af n ba str+ QueryPointer -> do+ ints@[root,child,root_x,root_y,win_x,win_y,mask] <- newLongs 7+ same <- xQueryPointer display wi root child root_x root_y win_x win_y mask+ ret <- PointerQueried same+ <$> mkPoint (readLong root_x) (readLong root_y)+ <*> mkPoint (readLong win_x) (readLong win_y)+ <*> (fromC <$> readLong mask)+ freePtrs ints+ return ret++ QueryFont fid -> FontQueried <$> queryFont display fid+ LoadQueryFont fn -> FontQueried <$> loadQueryFont display fn++ QueryColor cmid (Pixel px) -> do+ c <- newXColor+ SET(XColor,Word,c,pixel,px)+ cm <- dcm cmid+ xQueryColor display cm c+ r <- mkColor c+ freePtr c+ return (ColorQueried r)++ ListFonts pattern maxnames ->+ do cnt <- newLong+ fnarr <- xListFonts display pattern maxnames cnt+ fns <- unmarshallArray fnarr =<< readLong cnt+ xFreeFontNames fnarr+ freePtr cnt+ return (GotFontList fns)+ --QueryTree ->+ DefaultRootWindow -> GotDefaultRootWindow <$> xDefaultRootWindow display+ --GetGeometry ->+ --GetResource rms ->+ DefaultVisual ->+ GotVisual <$> (mkVisual =<< xDefaultVisual d =<< xDefaultScreen d)+ Sync b -> xSync display b >> return Synced+ QueryTextExtents16 fid s ->+ do let n = length s+ cs <- marshallString16' s n+ ints@[dir,ascent,descent,overall] <- newLongs 4+ overall <- newPtr+ xQueryTextExtents16 display fid cs n dir ascent descent overall+ [asc,desc] <- mapM readLong [ascent,descent]+ ov <- mkCharStruct overall+ freePtrs ints+ freePtr overall+ return $ TextExtents16Queried asc desc ov+ ListFontsWithInfo pattern maxnames ->+ GotFontListWithInfo <$> listFontsWithInfo d pattern maxnames+ DbeQueryExtension ->+ do ints@[major,minor] <- newLongs 2+ status <- xdbeQueryExtension display major minor+ ma <- readLong major+ mi <- readLong minor+ freePtrs ints+ return (DbeExtensionQueried status ma mi)+ DbeAllocateBackBufferName swapAction ->+ DbeBackBufferNameAllocated <$> xdbeAllocateBackBufferName d wi swapAction+ DbeSwapBuffers swapAction -> -- applies only to the fudget's own window.+ do (swapinfo,cnt) <- storeSwapAction [(wi,swapAction)]+ status <- xdbeSwapBuffers display swapinfo cnt+ freePtr swapinfo+ return (DbeBuffersSwapped status)+ _ -> error (notImplemented req)+ where+ createWindow parent (Rect (Point x y) (Point w h)) = do+ screen <- xDefaultScreen display+ blackP <- xBlackPixel display screen+ whiteP <- xWhitePixel display screen+ let border_width = 0 -- should agree with border_width in WindowF.hs !!+ this <- xCreateSimpleWindow display parent x y w h border_width blackP whiteP+ xStoreName display this "Fudgets"+ return this+ dcm = dcmap display++{-+type BorderWidth = Int+type FontShape = Int+-}++setClassHint :: Display -> Window -> String -> String -> IO ()+setClassHint d w resName resClass =+ do class_hints <- newPtr+ rn<-marshallString resName+ SET(XClassHint,CString,class_hints,res_name,rn)+ rc<-marshallString resClass+ SET(XClassHint,CString,class_hints,res_class,rc)+ xSetClassHint d w class_hints+ freePtr rn+ freePtr rc++createGC :: Display -> DrawableId -> IO GCId+createGC d w = xCreateGC d w 0 nullPtr+-- _casm_ ``%r=XCreateGC(%0,%1,0,NULL);'' d w++copyGC :: Display -> GCId -> GCId -> IO ()+copyGC d oldgc gc = + --xCopyGC d oldgc ``(1<<(GCLastBit+1))-1)''gc+ xCopyGC d oldgc 8388607 gc+-- _casm_ ``XCopyGC(%0,%1,(1<<(GCLastBit+1))-1,%2);'' d oldgc gc++changeGC d gc (gcvals,mask) = xChangeGC d gc mask gcvals++allocNamedColor :: Display -> String -> ColormapId -> IO (Maybe Color)+allocNamedColor d colname cm = do+ exact <- newPtr+ screen <- newPtr+ status <- xAllocNamedColor d cm colname screen exact+ r <- returnColor status screen+ freePtr exact+ freePtr screen+ return r++returnColor status c = + if status /= (0::Int)+ then Just <$> mkColor c+ else return Nothing++mkColor xcol = + Color . Pixel+ <$> GET(XColor,Word,xcol,pixel)+ <*> (RGB+ <$> GET(XColor,Int,xcol,red)+ <*> GET(XColor,Int,xcol,green)+ <*> GET(XColor,Int,xcol,blue)+ )++allocColor :: Display -> RGB -> ColormapId -> IO (Maybe Color)+allocColor d rgb cm = do+ color <- newXColor+ setRGB rgb color+ status <- xAllocColor d cm color+ r <- returnColor status color+ freePtr color+ return r++setRGB (RGB red green blue) color = do+ SET(XColor,Int,color,red,red)+ SET(XColor,Int,color,green,green)+ SET(XColor,Int,color,blue,blue)++type XGCValuesMask = (CXGCValues,Bitmask)++getGCValues :: GCAttributeList -> IO XGCValuesMask+getGCValues = getValues newPtr getGCValue where+ getGCValue gcv ga = case ga of+ GCFunction f -> (SET(XGCValues,Int,gcv,function,fromEnum f),CWORD32(GCFunction)::Bitmask)+ GCForeground p -> (SET(XGCValues,Int,gcv,foreground,toC p),CWORD32(GCForeground))+ GCBackground p -> (SET(XGCValues,Int,gcv,background,toC p),CWORD32(GCBackground))+ GCLineWidth w -> (SET(XGCValues,Int,gcv,line_width,w),CWORD32(GCLineWidth))+ GCLineStyle s -> (SET(XGCValues,Int,gcv,line_style,fromEnum s),CWORD32(GCLineStyle))+ GCFont f -> (SET(XGCValues,XID,gcv,font,toXID f),CWORD32(GCFont))+ GCCapStyle s -> (SET(XGCValues,Int,gcv,cap_style,fromEnum s),CWORD32(GCCapStyle))+ GCJoinStyle s -> (SET(XGCValues,Int,gcv,join_style,fromEnum s),CWORD32(GCJoinStyle))+ GCSubwindowMode m -> (SET(XGCValues,Int,gcv,subwindow_mode,fromEnum m),CWORD32(GCSubwindowMode))+ GCGraphicsExposures g -> (SET(XGCValues,Int,gcv,graphics_exposures, fromEnum g),CWORD32(GCGraphicsExposures))+ GCFillStyle f -> (SET(XGCValues,Int,gcv,fill_style,fromEnum f),CWORD32(GCFillStyle))+ GCTile p -> (SET(XGCValues,XID,gcv,tile,toXID p),CWORD32(GCTile))+ GCStipple p -> (SET(XGCValues,XID,gcv,stipple,toXID p),CWORD32(GCStipple) :: Bitmask)+ -- _ -> (return (),0)+++loadQueryFont :: Display -> FontName -> IO (Maybe FontStructList)+loadQueryFont d fn = mkFontStructList =<< xLoadQueryFont d fn++queryFont :: Display -> FontId -> IO (Maybe FontStructList)+queryFont d fi = mkFontStructList =<< xQueryFont d fi++listFontsWithInfo :: Display -> FontName -> Int -> IO [(FontName,FontStructList)]+listFontsWithInfo d pattern maxnames =+ do cnt <- newInt32+ fsarrp <- newCXFontStruct+ --putStrLn "About to call xListFontsWithInfo"+ fnarr <- xListFontsWithInfo d pattern (fromIntegral maxnames) cnt fsarrp+ --putStrLn "Returned from call xListFontsWithInfo"+ n <- readInt32 cnt+ --putStr "Number of fonts: " ; print n+ freePtr cnt+ fsarr <- readCVar fsarrp+ freePtr fsarrp+ --putStrLn "After free fsarrp"+ if fnarr==nullStr then return []+ else do+ --putStrLn "Non-null name array"+ fns <- unmarshallArray fnarr (fromIntegral n)+ --putStrLn "Got name list";print fns+ fss <- readArray fsarr (fromIntegral n)+ --putStrLn "Got fontstruct list"+ xFreeFontInfo fnarr fsarr n+ --putStrLn "Freed fontinfo, returning"+ return (zip fns fss)++instance CVar CXFontStruct FontStructList+instance Storable FontStructList where -- just for readArray...+--sizeOf _ = sizeOf (undefined::CXFontStruct) -- Wrong size!!!+ sizeOf _ = SIZEOF(XFontStruct)+ alignment _ = alignment (undefined::CXFontStruct)+ peek = mkFontStructList' . CXFontStruct++mkFontStructList :: CXFontStruct -> IO (Maybe FontStructList)+mkFontStructList fs =+ if fs == CXFontStruct nullAddr+ then return Nothing+ else do fsl <- mkFontStructList' fs+ --_casm_ ``XFreeFontInfo(NULL, %0, 1); '' fs+ xFreeFontInfo nullStr fs 1+ return (Just fsl)++#if 0+#define DEBUG(cmd) (putStrLn "cmd before">>(cmd)>>= \r->putStrLn "after">>return r)+#else+#define DEBUG(cmd) (cmd)+#endif++mkFontStructList' :: CXFontStruct -> IO FontStructList+mkFontStructList' fs =+ do --putStrLn "Enter mkFontStructList'"+ min_char_or_byte2 <- GET(XFontStruct,Int,fs,min_char_or_byte2)+ min_byte1 <-GET(XFontStruct,Int,fs,min_byte1)+ max_char_or_byte2 <- GET(XFontStruct,Int,fs,max_char_or_byte2)+ max_byte1 <-GET(XFontStruct,Int,fs,max_byte1)+ n_prop <-GET(XFontStruct,Int,fs,n_properties)+ -- putStrLn $ "font properties: " ++ (show n_prop)+ --putStrLn "after min max"+ let min = min_char_or_byte2 + 256*min_byte1+ max = max_char_or_byte2 + 256*max_byte1+ arrsize = (max_char_or_byte2 - min_char_or_byte2 + 1) *+ (max_byte1 - min_byte1 + 1)+ --arrsize = max - min :: Int -- This is wrong!+ --print ("min max arrsize",min,max,arrsize)+ per_char <- GET(XFontStruct,HT(XCharStruct),fs,per_char)+ --putStrLn "after per_char"+ elem9 <- if per_char /= nullPtr -- CCONST(NULL) + then Just <$> mapM (\i -> INDEX(XCharStruct) per_char i >>= mkCharStruct) [0..arrsize-1] + else return Nothing+ --putStrLn "after elem9"+ f_prop <- GET(XFontStruct,HT(XFontProp),fs,properties)+ elemprop <- if f_prop /= nullPtr+ then mapM (\i -> INDEX(XFontProp) f_prop i >>= mkFontProp) [0..n_prop-1]+ else return []+ -- putStrLn $ show elemprop+ fsl <- FontStruct . FontId+ <$> DEBUG(GET(XFontStruct,XID,fs,fid))+ <*> fmap toEnum DEBUG(GET(XFontStruct,Int,fs,direction))+ <*> return (toEnum min)+ <*> return (toEnum max)+ <*> fmap toEnum DEBUG(GET(XFontStruct,Int,fs,all_chars_exist))+ <*> DEBUG(GET(XFontStruct,Char,fs,default_char))+ <*> return elemprop+ <*> (mkCharStruct =<< DEBUG(AGET(XFontStruct,HT(XCharStruct),fs,min_bounds)))+ <*> (mkCharStruct =<< DEBUG(AGET(XFontStruct,HT(XCharStruct),fs,max_bounds)))+ <*> return elem9+ <*> DEBUG(GET(XFontStruct,Int,fs,ascent))+ <*> DEBUG(GET(XFontStruct,Int,fs,descent))+ -- putStrLn $ "Returning from mkFontStructList'" ++ (show fsl)+ return fsl++-- Intermediate data for FontProp, containing just two integers:+-- atom values will (hopefully) be retrieved lazily.++mkFontProp :: CXFontProp -> IO FontProp++mkFontProp fp = + FontProp+ <$> GET(XFontProp,Atom,fp,name)+ <*> GET(XFontProp,Int,fp,card32)++mkCharStruct :: CXCharStruct -> IO CharStruct+mkCharStruct cs = + CharStruct+ <$> GET(XCharStruct,Int,cs,lbearing)+ <*> GET(XCharStruct,Int,cs,rbearing)+ <*> GET(XCharStruct,Int,cs,width)+ <*> GET(XCharStruct,Int,cs,ascent)+ <*> GET(XCharStruct,Int,cs,descent)++mkVisual :: CVisual -> IO Visual+mkVisual cv =+ Visual+ <$> GET(Visual,VisualID,cv,visualid)+ <*> fmap toEnum GET(Visual,Int,cv,class)+ <*> fmap intToWord GET(Visual,Int,cv,red_mask)+ <*> fmap intToWord GET(Visual,Int,cv,green_mask)+ <*> fmap intToWord GET(Visual,Int,cv,blue_mask)+ <*> GET(Visual,Int,cv,bits_per_rgb)+ <*> GET(Visual,Int,cv,map_entries)++storeSwapAction :: [(WindowId,SwapAction)] -> IO (CXdbeSwapInfoArray,Int)+storeSwapAction =+ getArray newXdbeSwapInfoArray+ (\si (i,(wi,sa)) ->+ do SETI(XdbeSwapInfo,WindowId,si,i,swap_window,wi)+ SETI(XdbeSwapInfo,Int,si,i,swap_action,fromEnum sa))++translateCoordinates display window dstwindow =+ do dx <- newPtr+ dy <- newPtr+ child <- newPtr+ ok <- xTranslateCoordinates display window dstwindow 0 0 dx dy child+ p <- if ok+ then Just <$> (Point <$> (fromEnum <$> readInt32 dx)+ <*> (fromEnum <$> readInt32 dy))+ else return Nothing+ freePtrs [dx,dy]+ freePtr child+ return p+
+ hsrc/ghc-dialogue/EncodeEvent.hs view
@@ -0,0 +1,261 @@+{-# LANGUAGE CPP #-}+{- Obsolete OPTIONS -optc-I/usr/X11R6/include -#include <X11/Xlib.h> -#include <X11/Xutil.h> -fvia-C -}+module EncodeEvent(getNextEvent,motionCompress) where++import Event+import Xtypes+--import ResourceIds++import XCallTypes+import StructFuns+import Xlib+import Marshall+import MyForeign+import qualified Foreign as F++import FudUTF8(decodeUTF8)+import Data.Maybe(fromMaybe)+--import Ap++--import GlaExts hiding(Word) --(primIOToIO,CCallable,CReturnable,Addr)+--import MutableArray(MutableByteArray#)+--import PrelGHC+--import PrelBase+--import GhcWord+--import CString(unpackCStringIO)+--import Command+--import Font++#include "newstructfuns.h"++getNextEvent d = do+ ev <- newXEvent+ xNextEvent d ev+ window <- GET(XAnyEvent,WindowId,ev,window)+ fev <- encodeEvent ev+ return (window,fev) -- no freePtr?!++checkWindowEvent d w evmask = do+ ev <- newXEvent+ found <- xCheckWindowEvent d w (toC (evmask::[EventMask])) ev+ if found+ then Just <$> encodeEvent ev+ else freePtr ev >> return Nothing++motionCompress d e@(w,fev@MotionNotify{}) =+ do me <- checkWindowEvent d w [PointerMotionMask]+ case me of+ Nothing -> return e+ Just fev' -> motionCompress d (w,fev')+motionCompress _ e = return e+++encodeEvent ev = do+ evno <- GET(XAnyEvent,Int,ev,type)+ case evno :: Int of++{- ghc doesn't handle literal (``KeyPress'') patterns yet -}++#define X_KeyPress 2+#define X_KeyRelease 3+#define X_ButtonPress 4+#define X_ButtonRelease 5+#define X_MotionNotify 6+#define X_EnterNotify 7+#define X_LeaveNotify 8+#define X_FocusIn 9+#define X_FocusOut 10+#define X_KeymapNotify 11+#define X_Expose 12+#define X_GraphicsExpose 13+#define X_NoExpose 14+#define X_VisibilityNotify 15+#define X_CreateNotify 16+#define X_DestroyNotify 17+#define X_UnmapNotify 18+#define X_MapNotify 19+#define X_MapRequest 20+#define X_ReparentNotify 21+#define X_ConfigureNotify 22+#define X_ConfigureRequest 23+#define X_GravityNotify 24+#define X_ResizeRequest 25+#define X_CirculateNotify 26+#define X_CirculateRequest 27+#define X_PropertyNotify 28+#define X_SelectionClear 29+#define X_SelectionRequest 30+#define X_SelectionNotify 31+#define X_ColormapNotify 32+#define X_ClientMessage 33+#define X_MappingNotify 34+ X_KeyPress -> putKeyEvent ev Pressed+ X_KeyRelease -> putKeyEvent ev Released+ X_ButtonPress -> putButtonEvent ev Pressed+ X_ButtonRelease -> putButtonEvent ev Released+ X_MotionNotify -> putMotionEvent ev+ X_EnterNotify -> putCrossingEvent ev True+ X_LeaveNotify -> putCrossingEvent ev False+ X_FocusIn -> putFocusChangeEvent ev True+ X_FocusOut -> putFocusChangeEvent ev False+ X_KeymapNotify -> return KeymapNotify+ X_Expose -> putExposeEvent ev+ X_GraphicsExpose -> putGraphicsExposeEvent ev+ X_NoExpose -> return NoExpose+ X_VisibilityNotify -> putVisibilityEvent ev+ X_CreateNotify -> putStructEvent ev CreateNotify+ X_DestroyNotify -> putStructEvent ev DestroyNotify+ X_UnmapNotify -> putStructEvent ev UnmapNotify+ X_MapNotify -> putStructEvent ev MapNotify+ X_MapRequest -> putStructEvent ev MapRequest+ X_ReparentNotify -> return ReparentNotify+ X_ConfigureNotify -> putConfigureEvent ev+ X_ConfigureRequest -> return ConfigureRequest+ X_GravityNotify -> return GravityNotify+ X_ResizeRequest -> putResizeRequestEvent ev+ X_CirculateNotify -> return CirculateNotify+ X_CirculateRequest -> return CirculateRequest+ X_PropertyNotify -> return PropertyNotify+ X_SelectionClear -> putSelectionClearEvent ev+ X_SelectionRequest -> putSelectionRequestEvent ev+ X_SelectionNotify -> putSelectionNotifyEvent ev+ X_ColormapNotify -> return ColormapNotify+ X_ClientMessage -> putClientMessageEvent ev+ X_MappingNotify -> return MappingNotify++mkClientData ev = do+ format <- GET(XClientMessageEvent,Int,ev,format)+ d <- AGET(XClientMessageEvent,Addr,ev,data)+ case format::Int of+ 32 -> Long <$> mapM (CINDEX(long) (d::Addr)) [0..(4::Int)]+ 16 -> Short <$> mapM (CINDEX(short) d) [0..(9::Int)]+ 8 -> Byte <$> mapM (CINDEX(char) d) [0..(19::Int)]++putKeyEvent ev p = do+ (key,l) <- xLookupString ev 100+ KeyEvent+ <$> GET(XKeyEvent,Time,ev,time)+ <*> mkPoint GET(XKeyEvent,Int,ev,x) GET(XKeyEvent,Int,ev,y)+ <*> mkPoint GET(XKeyEvent,Int,ev,x_root) GET(XKeyEvent,Int,ev,y_root)+ <*> fmap fromC GET(XKeyEvent,Int,ev,state)+ <*> return p+ <*> fmap KeyCode GET(XKeyEvent,Int,ev,keycode)+ <*> return key+ <*> return (decodeUTF8 l)+ -- !! Assume that XLookupString returns a UTF-8 string+ -- https://gitlab.freedesktop.org/xorg/lib/libx11/-/issues/39++putButtonEvent ev p =+ ButtonEvent+ <$> GET(XButtonEvent,Time,ev,time)+ <*> mkPoint GET(XButtonEvent,Int,ev,x) GET(XButtonEvent,Int,ev,y)+ <*> mkPoint GET(XButtonEvent,Int,ev,x_root) GET(XButtonEvent,Int,ev,y_root)+ <*> fmap fromC GET(XButtonEvent,Int,ev,state)+ <*> return p+ <*> fmap Button GET(XButtonEvent,Int,ev,button)++putMotionEvent ev =+ MotionNotify+ <$> GET(XMotionEvent,Time,ev,time)+ <*> mkPoint GET(XMotionEvent,Int,ev,x) GET(XMotionEvent,Int,ev,y)+ <*> mkPoint GET(XMotionEvent,Int,ev,x_root) GET(XMotionEvent,Int,ev,y_root)+ <*> fmap fromC GET(XMotionEvent,Int,ev,state)++putCrossingEvent ev c =+ (if c then EnterNotify else LeaveNotify)+ <$> GET(XCrossingEvent,Time,ev,time)+ <*> mkPoint GET(XCrossingEvent,Int,ev,x) GET(XCrossingEvent,Int,ev,y)+ <*> mkPoint GET(XCrossingEvent,Int,ev,x_root) GET(XCrossingEvent,Int,ev,y_root)+ <*> fmap fromC GET(XCrossingEvent,Int,ev,detail)+ <*> fmap fromC GET(XCrossingEvent,Int,ev,mode)+ <*> fmap fromC GET(XCrossingEvent,Int,ev,focus)+++putFocusChangeEvent ev c =+ (if c then FocusIn else FocusOut)+ <$> fmap fromC GET(XFocusChangeEvent,Int,ev,detail)+ <*> fmap fromC GET(XFocusChangeEvent,Int,ev,mode)++putExposeEvent ev =+ Expose+ <$> mkRect GET(XExposeEvent,Int,ev,x) GET(XExposeEvent,Int,ev,y)+ GET(XExposeEvent,Int,ev,width) GET(XExposeEvent,Int,ev,height) + <*> GET(XExposeEvent,Int,ev,count)++putGraphicsExposeEvent ev =+ GraphicsExpose + <$> mkRect GET(XGraphicsExposeEvent,Int,ev,x) GET(XGraphicsExposeEvent,Int,ev,y)+ GET(XGraphicsExposeEvent,Int,ev,width) GET(XGraphicsExposeEvent,Int,ev,height) + <*> GET(XGraphicsExposeEvent,Int,ev,count)+ <*> GET(XGraphicsExposeEvent,Int,ev,major_code)+ <*> GET(XGraphicsExposeEvent,Int,ev,minor_code)++putVisibilityEvent ev =+ VisibilityNotify . fromC <$> GET(XVisibilityEvent,Int,ev,state)++putStructEvent ev c = c <$> GET(XMapEvent,WindowId,ev,window)++putConfigureEvent ev =+ ConfigureNotify+ <$> mkRect GET(XConfigureEvent,Int,ev,x) GET(XConfigureEvent,Int,ev,y)+ GET(XConfigureEvent,Int,ev,width) GET(XConfigureEvent,Int,ev,height)+ <*> GET(XConfigureEvent,Int,ev,border_width)++putResizeRequestEvent ev =+ ResizeRequest + <$> mkPoint GET(XResizeRequestEvent,Int,ev,width)+ GET(XResizeRequestEvent,Int,ev,height)++putSelectionClearEvent ev = SelectionClear+ <$> GET(XSelectionClearEvent,Atom,ev,selection)++putSelectionRequestEvent ev =+ SelectionRequest+ <$> GET(XSelectionRequestEvent,Time,ev,time)+ <*> GET(XSelectionRequestEvent,WindowId,ev,requestor)+ <*> (Selection <$> GET(XSelectionRequestEvent,Atom,ev,selection)+ <*> GET(XSelectionRequestEvent,Atom,ev,target)+ <*> GET(XSelectionRequestEvent,Atom,ev,property))++putSelectionNotifyEvent ev =+ SelectionNotify+ <$> GET(XSelectionEvent,Time,ev,time)+ <*> (Selection <$> GET(XSelectionEvent,Atom,ev,selection)+ <*> GET(XSelectionEvent,Atom,ev,target)+ <*> GET(XSelectionEvent,Atom,ev,property))++putClientMessageEvent ev =+ ClientMessage+ <$> GET(XClientMessageEvent,Atom,ev,message_type)+ <*> mkClientData ev++foreign import ccall "X11/Xlib.h XLookupString"+ cXLookupString :: CXKeyEvent -> Addr -> Int -> F.Ptr XlibKeySym -> Addr -> IO Int++xLookupString :: CXKeyEvent -> Int -> IO (KeySym,String)+xLookupString xev len =+ alloca len $ \ arr ->+ F.alloca $ \ keysyma ->+ do len' <- {- _casm_ ``%r=(int)XLookupString((XKeyEvent *)%0,+ (char *)%1,+ (int)%2,+ (KeySym *)%3,+ NULL);'' xev arr len keysyma -}+ cXLookupString xev arr len keysyma nullAddr+ keysym <- F.peek keysyma+ key <- xKeysymToString keysym+ let key' = fromMaybe "(undefined)" key+ str <- unmarshallString' (CString arr) len'+ return (key',str)++instance FromC Detail where fromC = toEnum' NotifyAncestor+instance FromC Mode where fromC = toEnum' NotifyNormal+instance FromC Visibility where fromC = toEnum' VisibilityUnobscured+++instance F.Storable XID where+ sizeOf (XID x) = F.sizeOf x+ alignment (XID x) = F.alignment x++ peek a = fmap XID (F.peek (F.castPtr a))+ poke a (XID x) = F.poke (F.castPtr a) x
+ hsrc/ghc-dialogue/IOUtil.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE CPP #-}+module IOUtil(-- ** Some utilities that are a little dirty, but not very+ getEnvi, progName, progArgs,+ -- ** Backward compatibility+ IOUtil.catch, try, getModificationTime) where++import qualified Control.Exception as E+import qualified System.Directory as D(getModificationTime)+import System.Environment(getEnv,getProgName,getArgs)+#ifdef VERSION_old_time+import Data.Time(UTCTime)+import Data.Time.Clock.POSIX(utcTimeToPOSIXSeconds)+import System.Time(ClockTime(..))+#endif+import UnsafePerformIO(unsafePerformIO)++getEnvi :: String -> Maybe String+getEnvi s = either (const Nothing) Just $ unsafePerformIO $ try (getEnv s)++progName :: String+progName = unsafePerformIO getProgName++progArgs :: [String]+progArgs = unsafePerformIO getArgs++-- * GHC 6.12-7.6 compatibility+catch = E.catch :: IO a -> (IOError -> IO a) -> IO a+try = E.try :: IO a -> IO (Either IOError a)++#ifdef VERSION_old_time+getModificationTime path = toClockTime `fmap` D.getModificationTime path++class ToClockTime a where toClockTime :: a -> ClockTime+instance ToClockTime ClockTime where toClockTime = id+instance ToClockTime UTCTime where + toClockTime = flip TOD 0 . floor . realToFrac . utcTimeToPOSIXSeconds+#else+getModificationTime path = D.getModificationTime path+#endif
+ hsrc/ghc-dialogue/Marshall.hs view
@@ -0,0 +1,187 @@+module Marshall where+import MyForeign+import Control.Monad(zipWithM_)+--import Ap++class HasAddr a where+ addrOf :: a -> Addr+ --atAddr :: Addr -> a++freePtr p = free (addrOf p)++class HasAddr a => IsPtr a where+ nullPtr :: a+ newPtr :: IO a+ newArray :: Int -> IO a++ newPtr = newArray 1++class (Storable h, HasAddr c) => CVar c h | c -> h where+ readCVar :: c -> IO h+ writeCVar :: c -> h -> IO ()+ indexCVar :: c -> Int -> IO h+ writeArray :: c -> [h] -> IO ()+ readArray :: c -> Int -> IO [h]++ readCVar = peek . addrOf+ writeCVar = poke . addrOf+ indexCVar = peekElemOff . addrOf+ writeArray arr = zipWithM_ (pokeElemOff (addrOf arr)) [0..]+ readArray arr n = mapM (indexCVar arr) [0..(n-1)]++toArray xs =+ do let n = length xs+ a <- newArray n+ writeArray a xs+ return (a,n)++{-+instance (Storable a,Storable b) => (Storable (a,b)) where+ sizeOf (a,b) = sizeOf a+sizeOf b+ alignment (a,b) = max (alignment a) (alignment b)+ poke p (a,b) = poke p a >> poke (p `plusAddr` sizeOf a) b+ peek p = do a <- peek p+ b <- peek (p `plusAddr` sizeOf a) p+ return (a,b)+-}++-------------------+class PrimArg ha pa r | ha->pa where+ --marshall :: haskell -> IO (prim,IO ())+ marshall :: (pa->r)->ha->r++-- marshallM x = marshall return x -- GHC generates buggy code, it seems++instance PrimArg Int Int c where marshall = id+instance PrimArg Int32 Int32 c where marshall = id+--instance PrimArg Char Char c where marshall = id+instance PrimArg Bool Bool c where marshall = id+--instance PrimArg () Int c where marshall f () = f 0+instance PrimArg Addr Addr c where marshall = id+instance PrimArg CLong CLong c where marshall = id+instance PrimArg CInt32 CInt32 c where marshall = id+instance PrimArg CString CString c where marshall = id++class Bind f where bind :: IO o->(o->f)->f+ thn :: f->IO ()-> f+instance Bind (IO a) where bind = (>>=)+ thn f io = do r<-f;io;return r+instance Bind f => Bind (a->f) where bind ioo oaf = bind ioo . flip oaf+ thn f io a = f a `thn` io++instance Bind f => PrimArg String CString f where+ marshall f str =+ marshallString str `bind` \ cstr ->+ f cstr `thn`+ freePtr cstr++class PrimResult prim haskell where+ unmarshall :: prim -> haskell++instance PrimResult () () where unmarshall = id+instance PrimResult Bool Bool where unmarshall = id+instance PrimResult Char Char where unmarshall = id+instance PrimResult Int Int where unmarshall = id+instance PrimResult Int32 Int32 where unmarshall = id++--instance PrimResult Int (IO Int) where unmarshall = return++instance PrimResult (IO ()) (IO ()) where unmarshall = id+instance PrimResult (IO Int) (IO Int) where unmarshall = id+instance PrimResult (IO Int32) (IO Int32) where unmarshall = id+instance PrimResult (IO Bool) (IO Bool) where unmarshall = id+instance PrimResult (IO CString) (IO CString) where unmarshall = id++unmarshallM m = unmarshall =<< m+unmarshallArray a n = mapM unmarshall =<< readArray a n++instance PrimResult (IO CString) (IO (Maybe String)) where+ unmarshall addrIO =+ do cstr <- addrIO+ if addrOf cstr==nullAddr+ then return Nothing+ else Just <$> unmarshall cstr++instance PrimResult CString (IO String) where unmarshall = unmarshallString+instance PrimResult (IO CString) (IO String) where unmarshall = unmarshallM++instance (PrimArg ha pa pb,PrimResult pb hb) => PrimResult (pa->pb) (ha->hb) where+ -- have: marshall :: (pa->pb)->(ha->pb)+ -- have: unmarshall :: pb->hb+ -- produce: unmarshall :: (pa->pb)->(ha->hb)+ unmarshall papb ha = unmarshall (marshall papb ha)++--- Primitive marshalling++newtype CString = CString Addr deriving (Eq)+instance HasAddr CString where addrOf (CString a) = a --; atAddr = CString+instance CVar CString CString+instance Storable CString where+ sizeOf (CString a) = sizeOf a+ alignment (CString a) = alignment a+ peek p = CString <$> peek p+ poke p (CString a) = poke p a++nullStr = CString nullAddr++marshallString :: String -> IO CString+marshallString s = marshallString' s (length s)++marshallString' :: String -> Int -> IO CString+marshallString' s n = + do a <- mallocElems (head s) (n+1)+ zipWithM_ (pokeElemOff a) [0..n-1] s+ pokeElemOff a n '\0'+ return (CString a)+++unmarshallString :: CString -> IO String+unmarshallString (CString addr) = get 0+ where + get i =+ do c <- peekElemOff addr i+ if c=='\0'+ then return []+ else (c:) <$> get (i+1)+ +unmarshallString' :: CString -> Int -> IO String+unmarshallString' (CString addr) n = get 0+ where+ get i =+ if i<n+ then (:) <$> peekElemOff addr i <*> get (i+1)+ else return []+ ++---++-- | Pointer to long int (same size as pointers, 64 bits on 64-bit systems)+newtype CLong = CLong Addr+newtype CXID = CXID Addr++instance HasAddr CLong where addrOf (CLong a) = a --;atAddr = CLong+instance HasAddr CXID where addrOf (CXID a) = a --;atAddr = CLong++instance IsPtr CLong where+ nullPtr = CLong nullAddr+ newPtr = CLong <$> mallocElem (0::Int)+ newArray n = CLong <$> mallocElems (0::Int) n++instance IsPtr CXID where+ nullPtr = CXID nullAddr+ newPtr = CXID <$> mallocElem (0::Int)+ newArray n = CXID <$> mallocElems (0::Int) n++instance CVar CLong Int++-- | Pointer to C int (32 bits even on 64-bit system)+newtype CInt32 = CInt32 Addr++instance HasAddr CInt32 where addrOf (CInt32 a) = a --;atAddr = CInt++instance IsPtr CInt32 where+ nullPtr = CInt32 nullAddr+ newPtr = CInt32 <$> mallocElem (0::Int32)+ newArray n = CInt32 <$> mallocElems (0::Int32) n++instance CVar CInt32 Int32
+ hsrc/ghc-dialogue/MyForeign.hs view
@@ -0,0 +1,93 @@+module MyForeign(module MyForeign,(<$>),(<*>),F.Int32,F.CSize(..)) where+import Control.Applicative+import qualified Foreign as F+import qualified Foreign.C as F+import Foreign.C.String(castCCharToChar,castCharToCChar)+--import CCall+import Control.Exception(bracket)+--import Ap+-- Emulate GHC 4.08 libraries on top of GHC 5.00 libraries...++newtype Addr = Addr (F.Ptr F.Word8) deriving (Eq,Show)+type AddrOff = Int++--instance CCallable Addr+--instance CReturnable Addr++class Storable a where+ sizeOf :: a -> Int+ alignment :: a -> Int++ peekElemOff :: Addr -> Int -> IO a+ pokeElemOff :: Addr -> Int -> a -> IO ()++ peekByteOff :: Addr -> AddrOff -> IO a+ pokeByteOff :: Addr -> AddrOff -> a -> IO ()++ peek :: Addr -> IO a+ poke :: Addr -> a -> IO ()++ peek a = peekByteOff a 0+ poke a = pokeByteOff a 0++ peekElemOff a i =+ let iox = peekByteOff a (i*sizeOf (u iox))+ u :: IO a -> a+ u = undefined+ in iox+ pokeElemOff a i x = pokeByteOff a (i*sizeOf x) x++ peekByteOff a i = peek (a `plusAddr` i)+ pokeByteOff a i = poke (a `plusAddr` i)++malloc n = Addr <$> F.mallocBytes n+mallocElem x = malloc (sizeOf x)+mallocElems x n = malloc (n*sizeOf x)+free (Addr p) = F.free p+alloca n = bracket (malloc n) free+allocaElem x = bracket (mallocElem x) free+allocaElems x n = bracket (mallocElems x n) free++nullAddr = Addr F.nullPtr+plusAddr (Addr p) n = Addr (F.plusPtr p n)+minusAddr (Addr p1) (Addr p2) = F.minusPtr p1 p2++instance Storable Addr where+ sizeOf (Addr a) = F.sizeOf a+ alignment (Addr a) = F.alignment a++ peek a = Addr <$> fpeek a+ poke a (Addr x) = fpoke a x++instance Storable Char where+ sizeOf _ = 1+ alignment _ = 1++ peek a = castCCharToChar <$> fpeek a+ poke a c = fpoke a (castCharToCChar c)++fpeek (Addr p) = F.peek (F.castPtr p)+fpoke (Addr p) = F.poke (F.castPtr p)++instance Storable Int where+ sizeOf x = F.sizeOf x+ alignment x = F.alignment x++ peek = fpeek+ poke = fpoke+++instance Storable F.Int32 where+ sizeOf x = F.sizeOf x+ alignment x = F.alignment x++ peek = fpeek+ poke = fpoke+++instance Storable F.Word32 where+ sizeOf x = F.sizeOf x+ alignment x = F.alignment x++ peek = fpeek+ poke = fpoke
+ hsrc/ghc-dialogue/PQueue.hs view
@@ -0,0 +1,16 @@+module PQueue where++newtype PQueue a b = PQueue [(a,b)] deriving Show++empty = PQueue []++insert (PQueue q) v@(p,a) = PQueue $ insert' q where+ insert' [] = [v]+ insert' q@(v'@(p',_):q') | p < p' = v : q+ | otherwise = v' : insert' q'++inspect (PQueue q) = case q of+ [] -> Nothing+ (x:xs) -> Just (x,PQueue xs)++remove (PQueue q) i = PQueue $ filter (\((_,(_,i')))->i'/=i) q
+ hsrc/ghc-dialogue/P_IO_data.hs view
@@ -0,0 +1,172 @@+{-# LANGUAGE CPP #-}+-- | Types for Haskell 1.2 dialogue I/O+module P_IO_data {-(module XStuff, module P_IO_data)-} where+import XStuff+import ShowFun()+import Prelude hiding (IOError)+import System.Directory(XdgDirectory)+#ifdef VERSION_old_time+import System.Time(ClockTime,CalendarTime)+#endif+#ifdef VERSION_time+import Data.Time(UTCTime,ZonedTime)+#endif++data Request = -- file system requests:+ ReadFile String + | WriteFile String String+ | AppendFile String String+ | ReadBinFile String + | WriteBinFile String Bin+ | AppendBinFile String Bin+ | DeleteFile String+ | StatusFile String+ -- useful for IO with GHC >=6.12+ | ReadBinaryFile String + | WriteBinaryFile String String+ -- Files at standard locations for application data+ | ReadXdgFile XdgDirectory String+ | WriteXdgFile XdgDirectory String String+ -- channel system requests:+ | ReadChan String + | AppendChan String String+ | ReadBinChan String + | AppendBinChan String Bin+ | StatusChan String+ -- environment requests:+ | Echo Bool+ | GetArgs+ | GetEnv String+ | SetEnv String String+ -- optional+ | ReadChannels [String]+ | ReadBinChannels [String]+ | CreateProcess Dialogue+ | CreateDirectory String String+ | OpenFile String Bool+ | OpenBinFile String Bool+ | CloseFile File+ | ReadVal File+ | ReadBinVal File+ | WriteVal File Char+ | WriteBinVal File Bin+ -- hbc bonus+ | Sleep Double+ | ChangeDirectory String+ | GetTime -- returns ClockTime -- /TH 2002-04-14+ | DeleteDirectory String+ | System String+ | ReadDirectory String+ | XCommand (XDisplay,XWId,XCommand)+ | GetAsyncInput+ | GetCpuTime+ | GetProgName+ | GetLocalTime -- return CalendarTime+#ifdef VERSION_old_time+ | ToCalendarTime ClockTime -- returns CalendarTime+#endif+ | SigAction Int SigAct+ | Exit Int+ | ReadFileScattered String [Int]+ | Select [Descriptor]+ | SocketRequest SocketRequest+ | XRequest (XDisplay,XWId,XRequest)+ | ReadFileFast String + | RenameFile String String+ | GetCurrentDirectory++ | GetModificationTime FilePath -- returns ClockTime+ | GetCurrentTime -- returns UTCTime+ | GetZonedTime -- returns ZonedTime+{-+ -- Haskell 1.3 I/O+ | H_OpenFile String Int -- return Fil+ | H_Close File -- return Success+ | H_FileSize File -- return IntResp+ | H_IsEOF File -- return IntResp+ | H_SetBuffering File Int -- return Success+ | H_GetBuffering File -- return IntResp+ | H_Flush File -- return Success+ | H_Seek File Int Int -- return IntResp+ | H_GetFlags File -- return IntResp+ | H_GetChar File -- return IntResp+ | H_UnGetChar File Int -- return Success+ | H_PutChar File Int -- return Success+ | H_PutString File String -- return Success+ | H_GetFile File -- return Str+ | H_Select ([File], [File], [Double]) -- return SelectResp, last list is a Maybe+ | H_CCall _CPointer [_CUnion] _CUnion -- return CCallResp+ | __RunAnswer __Answer -- never returns+ | H_GetTime -- returns GetTimeResp+ | H_GetErrno -- returns IntResp+-}+ deriving (Show,Read)++{-+data __Answer = __Answer EXISTVAR++instance Text __Answer where+ showsType _ = showString "__Answer"+++data _CUnion = _CUInt Int+ | _CUDouble Double + | _CUString String + | _CUPointer _CPointer+#ifdef P_IO_data+ | _CUByteVector _ByteVector._ByteVector+#endif+ deriving (Eq, Text)++ISO(_CPointer , _CPointer , Int) deriving (Eq, Text)+-}+data SigAct = SAIgnore+ | SADefault+ | SACatch (String -> Dialogue)+ deriving (Show,Read)++data Response = Success+ | Str String + | Bn Bin+ | Failure IOError+ | Tag [(String, Char)]+ | BinTag [(String, Bin)]+ | StrList [String]+ | Fil File+ | Dbl Double+ | AsyncInput AsyncInput+ | SocketResponse SocketResponse+ | XResponse XResponse+ | IntResp Int+ | SelectResp [([File], [File], [Double])]+ | SigActResp SigAct+-- | CCallResp _CUnion+-- | GetTimeResp Double Bool String Int+#ifdef VERSION_old_time+ | ClockTime ClockTime -- response to GetTime --+ | CalendarTime CalendarTime -- response to GetLocalTime+#endif+#ifdef VERSION_time+ | UTCTime UTCTime -- response to GetCurrentTime+ | ZonedTime ZonedTime -- response to GetZonedTime+#endif+ deriving (Show,Read)++data IOError = WriteError String+ | ReadError String+ | SearchError String+ | FormatError String+ | OtherError String+ deriving (Show,Read)+++type Bin = Unused+type Dialogue = [Response] -> [Request] -- not useful anymore+--type _CUnion = Unused+type File = Unused++type Unused = ()++#ifdef VERSION_old_time+instance Read ClockTime -- !!!+#endif
+ hsrc/ghc-dialogue/StructFuns.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE CPP #-}+{- Obsolete OPTIONS -fvia-C -}+module StructFuns(module StructFuns,module CSizes) where+import MyForeign+import Marshall+import Xlib+import CSizes+import Xtypes(XID(..),Atom(..),Time,WindowId(..),Window)+import Visual(VisualID(..))+import HbcWord(Word)+import Data.Word(Word32)++--import GlaExts hiding (Word,(<#),Addr)++{-+#include "structs.h"+#include "cimports.h"+-}+#include "ccalls.h"++H_STRUCTTYPE(timeVal)+H_STRUCTTYPE(sockAddr)++type Cchar = Char+type Clong = Int+type Cshort = Int
+ hsrc/ghc-dialogue/XCallTypes.hs view
@@ -0,0 +1,116 @@+{- unused options -#include <X11/Xlib.h> -#include <X11/Xutil.h> -fvia-C -}+-- -optc-I/usr/X11R6/include+module XCallTypes+ --(module XCallTypes,newCharArray,MutableByteArray(..))+ where++import Data.Bits+import Data.Word(Word32)+import Control.Applicative+import Control.Monad(foldM)+--import MyForeign(Int32)++import Utils(number)+import Xtypes+import Geometry+--import Ap(foldR)+--import PackedString(unpackPS,byteArrayToPS{-,packCString-})++-- #include "structs.h"++getEnum bla = fromEnum+toEnum' bla = toEnum+{-+toEnum' s = (a!)+ where a = listArray (0,length l - 1) l+ l = [s..]++getEnum s = (a!)+ where a = listArray (s,last [s..]) [(0::Int)..]+-}++class ToC a where toC :: a -> Int+class ToCl a where toCl :: [a] -> Int+class FromC a where fromC :: Int -> a++class ToXID a where toXID :: a -> XID+--class FromXID a where fromXID :: XID -> a++instance (ToCl a) => ToC [a] where toC = toCl++instance ToCl EventMask where + toCl = fromIntegral . foldr getE (0::Word32)+ where+ getE e m = setBit m (fromEnum e)++instance ToC Bool where toC False = 0+ toC True = 1++instance FromC Bool where fromC 0 = False+ fromC _ = True+++instance ToXID PixmapId where toXID (PixmapId p) = p+instance ToC Pixel where toC (Pixel p) = fromIntegral p+instance ToXID ColormapId where toXID (ColormapId p) = p+instance ToXID CursorId where toXID (CursorId p) = p+instance ToXID FontId where toXID (FontId p) = p+--instance ToC WindowId where toC (WindowId p) = p+--instance ToC Display where toC (Display p) = p+--instance ToC Width where toC (Width p) = p+--instance ToC Atom where toC (Atom p) = p+--instance ToC PropertyMode where toC (PropertyMode p) = p++--pIoCmd x = primIOToIO x :: IO ()+--pIoCmd x = stToIO x :: IO ()+ioCmd x = x :: IO ()++getValues new getValue vl = do+ vs <- new+ let maskf mask val = do set; return (mask .|. m)+ where (set,m) = getValue vs val+ mask <- foldM maskf 0 vl+ return (vs,mask)++failu :: String -> IO a+failu = ioError . userError++--unpackCharArray len a = fmap (take len . unpackPS . byteArrayToPS) $+-- stToIO $ unsafeFreezeByteArray a++--cstring :: Addr -> String -- This type looks a bit suspicious... /TH 990211+--cstring = unpackCString++getArray new mod l = do+ arr <- new size+ mapM_ (mod arr) (number 0 l)+ return (arr,size)+ where size = length l+++{-+H_ARRAY(int)+newInt = newintArray 1+readInt i = CINDEX(int) (i::Cint) (0::Int) :: IO Int+writeInt i v = SINDEX(int,i::Cint,0::Int,v::Int)+-}++mkPoint x y = Point <$> x <*> y+mkRect x y w h = Rect <$> mkPoint x y <*> mkPoint w h++--mkAtom a = fmap Atom a+--mkSelection s t p = Selection <$> mkAtom s <*> mkAtom t <*> mkAtom p+--mkSelection s t p = Selection <$> s <*> t <*> p++instance FromC ModState where + fromC ni = [toEnum i|i<-[15,14..0],testBit ni i]+{-+ concatMap toModifier [15,14..0]+ where+ toModifier i = [toEnum i|testBit ni i]+-- toe = toEnum' Shift -- . fromIntegral+-- n = fromIntegral ni :: Word32+-}++notImplemented x = take 79 ("Not implemented: "++show x)++"\n"+
+ hsrc/ghc-dialogue/Xlib.hs view
@@ -0,0 +1,344 @@+{-# LANGUAGE CPP #-}+{- Obsolete OPTIONS -optc-I/usr/X11R6/include -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/extensions/shape.h> -#include <X11/extensions/Xdbe.h> -fvia-C -}+module Xlib where+import Marshall+import MyForeign+import CSizes+import Xtypes+import Visual+import Font(FontDirection)+import CString16(CString16)++import DrawTypes++import Control.Monad(zipWithM_)+--import Ap+import Data.Word(Word,Word32)+--import CCall+default(Int)++#include "structs.h"++type Unsigned = Int -- hmm+type Unsigned32 = Int32 -- hmm+type Status = Int+type Screen = Int+type Bitmask = Word32+type XlibKeySym = XID -- KeySym in Xlib, defined as String in Fudgets+type ClipOrdering = Ordering'+type CPixelArray = CLong+type CStringArray = CString+type CXFontStructArray = CXFontStruct+type CDisplay = Addr+type CGCId = Addr+newtype Region = Region Addr++#define FI(f) foreign import ccall unsafe "f" prim/**/f+#define PXlib(f,p,h) FI(X/**/f) :: p ; x/**/f :: h ; x/**/f = call primX/**/f+#define Xlib(f,h) PXlib(f,h,h)++#define PReq0(f,pr,r) PXlib(f,CDisplay -> IO pr, Display -> IO r)+#define Req0(f,r) PReq0(f,r,r)+#define Req(f,t,r) PReq(f,t,r,t,r)+#define PReq(f,p,pr,t,r) PXlib(f,CDisplay -> p -> IO pr, Display-> t ->IO r)+#define WindowReq(f,t,r) Req(f,Window->t,r)+#define PWindowReq(f,pt,pr,t,r) PReq(f,Window->pt,pr,Window->t,r)+#define WindowReqP(f,t,pr,r) PReq(f,Window->t,pr,Window->t,r)+#define DrawReq(f,t,r) Req(f,DrawableId->t,r)+#define DrawReqP(f,t,pr,r) PReq(f,DrawableId->t,pr,DrawableId->t,r)++#define Cmd0(f) PXlib(f,CDisplay -> IO (), Display-> IO ())+#define Cmd(f,t) Req(f,t,())+#define PCmd(f,p,t) PXlib(f,CDisplay -> p -> IO (), Display-> t ->IO ())+#define WindowCmd0(f) Cmd(f,Window)+#define WindowCmd(f,t) Cmd(f,Window->t)+#define PWindowCmd(f,p,t) PCmd(f,Window->p,Window->t)+#define DrawCmd(f,t) PCmd(f,DrawableId->CGCId->t,DrawableId->GCId->t)+#define DrawPCmd(f,p,t) PCmd(f,DrawableId->CGCId->p,DrawableId->GCId->t)++--- Calls ---------------------------------------------------------------------+PXlib(OpenDisplay, CString -> IO CDisplay, String -> IO Display)+Cmd0(CloseDisplay)+Req0(ConnectionNumber,Int32)+Cmd0(Flush)+Cmd(NextEvent,CXEvent)+WindowReq(CheckWindowEvent,Int->CXEvent,Bool)+Req0(Pending,Int)+Cmd(FreePixmap,PixmapId)+Cmd(Synchronize,Bool) -- result is ignored.+Cmd(Sync,Bool)+Cmd(Bell,Int)++FI(XInitThreads) :: IO Int+xInitThreads = fmap (/=0) primXInitThreads+Cmd0(LockDisplay)+Cmd0(UnlockDisplay)++FI(XFree) :: Addr -> IO ()+xFree p = primXFree (addrOf p)++Req0(DefaultScreen,Screen)+Req0(DefaultRootWindow,Window)+PReq0(ImageByteOrder,Int,ByteOrder)+Req(DefaultDepth,Screen,Int)+Req(BlackPixel,Int,Unsigned)+Req(WhitePixel,Int,Unsigned)+Req(DefaultColormap,Int,ColormapId)+Req(DefaultVisual,Screen,CVisual)++PReq(LoadFont,CString,FontId,String,FontId)+Req(QueryFont,FontId,CXFontStruct)+PReq(LoadQueryFont,CString,CXFontStruct,String,CXFontStruct)+PReq(ListFonts,CString->Int->CLong,CStringArray,String->Int->CLong,CStringArray)+Xlib(FreeFontNames,CStringArray->IO())+PReq(ListFontsWithInfo,CString->Int->CInt32->CCXFontStruct,CStringArray,String->Int->CInt32->CCXFontStruct,CStringArray)+Xlib(FreeFontInfo,CStringArray->CXFontStructArray->Int32->IO ())+Cmd(QueryTextExtents16,FontId->CString16->Int->CLong->CLong->CLong->CXCharStruct)++Req(CreateFontCursor,Int,CursorId)+Req(CreatePixmap,DrawableId->Unsigned->Unsigned->Unsigned,PixmapId)+PReq(InternAtom,CString->Bool,Atom,String->Bool,Atom)+Req(GetAtomName,Atom,CString)+Req(AllocColor,ColormapId->CXColor,Status)+PReq(AllocNamedColor,ColormapId->CString->CXColor->CXColor,Status,ColormapId->String->CXColor->CXColor,Status)+Cmd(QueryColor,ColormapId->CXColor)+Cmd(FreeColors,ColormapId->CPixelArray->Int->Pixel)+{- -- This creates a dangling reference to the image data!+PReq(CreateImage,CVisual->Int->Int->Int->CString->Int->Int->Int->Int,CXImage,+ CVisual->Int->Int->Int->String->Int->Int->Int->Int,CXImage)+-}+Req(CreateImage,CVisual->Int->Int->Int->CString->Int->Int->Int->Int,CXImage)++DrawCmd(PutImage,CXImage->Int32->Int32->Int32->Int32->Int32->Int32)++-- Xlib(DestroyImage,CXImage->IO ()) -- XDestroyImage is a macro in X11/Xutil.h+foreign import ccall "asyncinput.h" xDestroyImage :: CXImage -> IO ()+++WindowCmd0(DestroyWindow)+WindowCmd0(MapRaised)+WindowCmd0(LowerWindow)+WindowCmd0(UnmapWindow)+WindowCmd0(ClearWindow)+WindowCmd(ClearArea,Int->Int->Int->Int->Bool)+WindowReq(CreateSimpleWindow,Int->Int->Unsigned->Unsigned->Unsigned->Unsigned->Unsigned,Window)+PWindowCmd(StoreName,CString,String)+WindowCmd(SetClassHint,CXClassHint)+WindowCmd(ConfigureWindow,Bitmask->CXWindowChanges)+WindowCmd(ChangeWindowAttributes,Bitmask->CXSetWindowAttributes)+WindowCmd(ReparentWindow,Window->Int->Int)+PWindowCmd(SetWMProtocols,CAtomArray->Int,[Atom]->Int)+WindowCmd(SetNormalHints,CXSizeHints)+WindowCmd(SetWMHints,CXWMHints)+WindowReq(SendEvent,Bool->Bitmask->CXEvent,Status)+PWindowCmd(ChangeProperty,Atom->Atom->Int->PropertyMode->CString->Int,Atom->Atom->Int->PropertyMode->String->Int)+WindowReq(GetWindowProperty,Atom->Int->Int->Bool->Atom->CAtom->CLong->CLong->CLong->CCString,Int)+WindowReq(QueryPointer,CLong->CLong->CLong->CLong->CLong->CLong->CLong,Bool)+WindowReq(TranslateCoordinates,Window->Int->Int->CInt32->CInt32->CLong,Bool)+PWindowCmd(ShapeCombineMask,Int->Int->Int->PixmapId->Int,ShapeKind->Int->Int->PixmapId->ShapeOperation)+PWindowCmd(ShapeCombineRectangles,Int->Int->Int->CXRectangleArray->Int->Int->Int,ShapeKind->Int->Int->CXRectangleArray->Int->ShapeOperation->ClipOrdering)+PWindowCmd(ShapeCombineShape,Int->Int->Int->PixmapId->Int->Int,ShapeKind->Int->Int->PixmapId->ShapeKind->ShapeOperation)++Cmd(GrabButton,Int->Int->Window->Bool->Unsigned->Int->Int->Window->CursorId)+Cmd(UngrabButton,Int->Int->Window)+WindowReqP(GrabPointer,Bool->Unsigned->Int->Int->Window->CursorId->Time,Int,GrabPointerResult)+Cmd(UngrabPointer,Time)+Cmd(SetSelectionOwner,Atom->Window->Time)+Cmd(ConvertSelection,Atom->Atom->Atom->Window->Time)++DrawCmd(DrawPoint,Int->Int)+DrawCmd(DrawLine,Int->Int->Int->Int)+DrawPCmd(DrawLines,CXPointArray->Int->Int,CXPointArray->Int->CoordMode)+DrawPCmd(DrawImageString,Int->Int->CString->Int,Int->Int->String->Int)+DrawPCmd(DrawString,Int->Int->CString->Int,Int->Int->String->Int)+DrawPCmd(DrawImageString16,Int->Int->CString16->Int,Int->Int->CString16->Int)+DrawPCmd(DrawString16,Int->Int->CString16->Int,Int->Int->CString16->Int)+DrawCmd(DrawRectangle,Int->Int->Int->Int)+DrawCmd(FillRectangle,Int->Int->Int->Int)+DrawCmd(DrawArc,Int32->Int32->Unsigned32->Unsigned32->Int32->Int32)+DrawCmd(FillArc,Int32->Int32->Unsigned32->Unsigned32->Int32->Int32)+DrawPCmd(FillPolygon,CXPointArray->Int->Int->Int,CXPointArray->Int->Shape->CoordMode)+PCmd(CopyArea,DrawableId->DrawableId->CGCId->Int32->Int32->Unsigned32->Unsigned32->Int32->Int32,DrawableId->DrawableId->GCId->Int32->Int32->Unsigned32->Unsigned32->Int32->Int32)+PCmd(CopyPlane,DrawableId->DrawableId->CGCId->Int32->Int32->Unsigned32->Unsigned32->Int32->Int32->Word,DrawableId->DrawableId->GCId->Int32->Int32->Unsigned32->Unsigned32->Int32->Int32->Word)++#define GCCmd(f,t) PCmd(f,CGCId->t,GCId->t)++DrawReqP(CreateGC,Bitmask->CXGCValues,CGCId,GCId)+PCmd(CopyGC,CGCId->Bitmask->CGCId,GCId->Bitmask->GCId)+GCCmd(ChangeGC,Bitmask->CXGCValues)+PCmd(FreeGC,CGCId,GCId)++GCCmd(SetForeground,Unsigned)+GCCmd(SetBackground,Unsigned)+GCCmd(SetPlaneMask,Bitmask)+PCmd(SetFunction,CGCId->Int,GCId->GCFunction)+PCmd(SetState,CGCId->Unsigned->Unsigned->Int->Unsigned,GCId->Unsigned->Unsigned->GCFunction->Unsigned)++PXlib(KeysymToString,XlibKeySym->IO CString,XlibKeySym->IO (Maybe String))++Req(ReadBitmapFile,DrawableId->CString->CInt32->CInt32->CXID->CInt32->CInt32,Int)+Req(CreateBitmapFromData,DrawableId->CString->Int32->Int32,PixmapId)++--- Regions -------------------------------------------------------------------+Xlib(CreateRegion,IO Region)+PCmd(SetRegion,CGCId->Region,GCId->Region)+Xlib(DestroyRegion,Region->IO ())+Xlib(UnionRectWithRegion,CXRectangle->Region->Region->IO ())+IDAR(Region)++--- Double buffer extension ---------------------------------------------------+Req(dbeQueryExtension,CLong->CLong,Int)+PWindowReq(dbeAllocateBackBufferName,Int,DbeBackBufferId,SwapAction,DbeBackBufferId)+Req(dbeSwapBuffers,CXdbeSwapInfoArray->Int,Status)++H_ARRAY(XdbeSwapInfo)+ENUMAR(SwapAction)+IDAR(DbeBackBufferId)+--- Types ---------------------------------------------------------------------++IORC(CDisplay,Display,fmap (Display . a2i))+instance PrimArg Display CDisplay c where marshall c (Display d) = c (i2a d)++IORC(CGCId,GCId,fmap (GCId . a2i))++instance PrimArg GCId CGCId c where marshall c (GCId d) = c (i2a d)+++-- Instances for resource identifiers and simple values+IDAR(Atom)+IDAR(ColormapId)+IDAR(CursorId)+IDAR(DrawableId)+IDAR(FontId)+IDAR(Pixel)+IDAR(PixmapId)+IDAR(PropertyMode)+IDAR(VisualID)+IDAR(Window)+IDAR0(Word32)+IDAR0(Word)+IDAR0(XID)+ENUMAR(ByteOrder)+ENUMAR(CoordMode)+ENUMAR(DisplayClass)+ENUMAR(FontDirection)+ENUMAR(GrabPointerResult)+ENUMAR(GCFunction)+ENUMAR(GCLineStyle)+ENUMAR(GCCapStyle)+ENUMAR(GCJoinStyle)+ENUMAR(GCSubwindowMode)+ENUMAR(GCFillStyle)+ENUMAR(ClipOrdering)+ENUMAR(Shape)+ENUMAR(ShapeKind)+ENUMAR(ShapeOperation)++IDAR0(CXID)+ISTORE(XID)++instance CVar CXID XID++--- Structured types ----------------------------------------------------------+H_STRUCTTYPE(XColor)+H_STRUCTTYPE(XClassHint)+H_STRUCTTYPE(XGCValues)+H_STRUCTTYPE(XSetWindowAttributes)+H_STRUCTTYPE(XSizeHints)+H_STRUCTTYPE(XWMHints)+H_STRUCTTYPE(XWindowChanges)++H_ARRAY(Atom)+ISTORE(Atom)+instance CVar CAtom Atom+instance PrimArg [Atom] CAtom (Int->IO a) where+ marshall pf as n =+ do aa <- newArray n+ zipWithM_ (pokeElemOff (addrOf aa)) [0..(n-1)] [a|Atom a<-as]+ r<-pf aa n+ freePtr aa+ return r++H_STRUCTTYPE(XEvent)+type CXAnyEvent = CXEvent+type CXKeyEvent = CXEvent+type CXButtonEvent = CXEvent+type CXMotionEvent = CXEvent+type CXCrossingEvent = CXEvent+type CXFocusChangeEvent = CXEvent+type CXExposeEvent = CXEvent+type CXGraphicsExposeEvent = CXEvent+type CXNoExposeEvent = CXEvent+type CXVisibilityEvent = CXEvent+type CXCreateWindowEvent = CXEvent+type CXDestroyWindowEvent = CXEvent+type CXUnmapEvent = CXEvent+type CXMapEvent = CXEvent+type CXMapRequestEvent = CXEvent+type CXReparentEvent = CXEvent+type CXConfigureEvent = CXEvent+type CXGravityEvent = CXEvent+type CXResizeRequestEvent = CXEvent+type CXConfigureRequestEvent = CXEvent+type CXCirculateEvent = CXEvent+type CXClientMessageEvent = CXEvent+type CXSelectionClearEvent = CXEvent+type CXSelectionRequestEvent = CXEvent+type CXSelectionEvent = CXEvent++H_ARRAY(XPoint)+H_ARRAY(XRectangle)+C_STRUCTTYPE(XFontStruct);IDAR0(CXFontStruct)++--C_STRUCTTYPE(XCharStruct);IDAR0(CXCharStruct)+NEWTYPE(HT(XCharStruct));IPTR(XCharStruct);ISTORE(HT(XCharStruct));+INSTCCALL(HT(XCharStruct));IDAR0(CXCharStruct)++C_STRUCTTYPE(Visual);IDAR0(CVisual)+C_STRUCTTYPE(XImage);IDAR0(CXImage)+INSTCCALL(CString)++NEWTYPE(HT(XFontProp));IPTR(XFontProp);ISTORE(HT(XFontProp));+INSTCCALL(HT(XFontProp));IDAR0(CXFontProp)++C_STRUCTTYPE(CXFontStruct);IDAR0(CCXFontStruct)+newCXFontStruct = CCXFontStruct <$> mallocElem nullAddr+instance CVar CCXFontStruct CXFontStruct++C_STRUCTTYPE(CString);IDAR0(CCString)+newCString = CCString <$> mallocElem nullAddr+instance CVar CCString CString+--- Constants -----------------------------------------------------------------+anyModifier = 2^(15 :: Int)+grabModeAsync = 1 :: Int+--- Auxiliary functions/types -------------------------------------------------+call f = unmarshall f+uio f = fmap f++a2i :: Addr -> Int+a2i a = minusAddr a nullAddr++{-# NOINLINE i2a #-} -- Workaround a GHC bug on 64-bit systems /TH 2016-12-29+i2a :: Int -> Addr+i2a = plusAddr nullAddr++newtype DrawableId = DrawableId XID deriving Show+getdrawable _ (Pixmap (PixmapId i)) = DrawableId i+getdrawable (WindowId w) MyWindow = DrawableId w+getdrawable _ (DbeBackBuffer (DbeBackBufferId b)) = DrawableId b++dcmap display cmap =+ if cmap == defaultColormap+ then xDefaultScreen display >>= xDefaultColormap display+ else return cmap++data ByteOrder = LSBFirst | MSBFirst deriving (Eq,Enum)++--withLockedDisplay display cmd = cmd+{-+withLockedDisplay display cmd =+ do xLockDisplay display+ result <- cmd+ xUnlockDisplay display+ return result+-}
+ hsrc/ghc-dialogue/asyncinput.h view
@@ -0,0 +1,41 @@+/*#ifndef ASYNCINPUT_H*/+/* This file seems to be incldued twice for some strange reason... */+#define ASYNCINPUT_H++#undef _POSIX_SOURCE++#include <sys/types.h>+#include <sys/time.h>+#include <unistd.h>++#include <sys/socket.h>+#define XLIB_ILLEGAL_ACCESS+#include <X11/Xlib.h>+#include <X11/Xutil.h>++typedef struct timeval timeVal;++typedef struct sockaddr sockAddr;++/* Things from socketlib, doesn't really belong here: */+int in_connect(char *host,short port,int type);+int in_bind(short port, int type) ;+void fdzero(fd_set *s);+void fdset(int fd,fd_set *s);+int fdisset(int fd,fd_set *s);+void bcopy_fdset(fd_set *,fd_set *);+int get_errno(void);+long get_stdin(void);+int get_fileno(long); /* The true argument type is FILE * */++void xDestoryImage(XImage *ximage);+int default_bpp(Display *,int depth);+void setXImage_data(XImage *ximage,char *data);++void disable_timers(void);++/* Quick hack to work around typing problem: */+/* #define GETSOCKNAME(s,a,len) getsockname(s,(struct sockaddr *)a,len) */+/* #define ACCEPT(s,a,len) accept(s,(struct sockaddr *)a,len) */++/*#endif*/
+ hsrc/ghc-dialogue/ccalls.h view
@@ -0,0 +1,208 @@+AGET(XClientMessageEvent,Addr,ev,data)+AGET(XFontStruct,HT(XCharStruct),fs,max_bounds)+AGET(XFontStruct,HT(XCharStruct),fs,min_bounds)+CCONST(AF_INET)+CCONST(AnyButton)+CCONST(BitmapSuccess)+CCONST(EAGAIN)+CCONST(EINTR)+CCONST(InputHint)+CCONST(LSBFirst)+CCONST(None)+CCONST(SOCK_STREAM)+CCONST(SelectionNotify)+CCONST(USPosition)+CINDEX(char)+CINDEX(long)+CINDEX(short)+CWORD32(CWBackPixel)+CWORD32(CWBackPixmap)+CWORD32(CWBackingStore)+CWORD32(CWBitGravity)+CWORD32(CWBorderPixel)+CWORD32(CWBorderPixmap)+CWORD32(CWBorderWidth)+CWORD32(CWCursor)+CWORD32(CWDontPropagate)+CWORD32(CWEventMask)+CWORD32(CWHeight)+CWORD32(CWOverrideRedirect)+CWORD32(CWSaveUnder)+CWORD32(CWStackMode)+CWORD32(CWWidth)+CWORD32(CWWinGravity)+CWORD32(CWX)+CWORD32(CWY)+CWORD32(GCBackground)+CWORD32(GCCapStyle)+CWORD32(GCJoinStyle)+CWORD32(GCFillStyle)+CWORD32(GCFont)+CWORD32(GCForeground)+CWORD32(GCFunction)+CWORD32(GCGraphicsExposures)+CWORD32(GCLineStyle)+CWORD32(GCLineWidth)+CWORD32(GCStipple)+CWORD32(GCSubwindowMode)+CWORD32(GCTile)+GET(Visual,Int,cv,bits_per_rgb)+GET(Visual,Int,cv,blue_mask)+GET(Visual,Int,cv,class)+GET(Visual,Int,cv,green_mask)+GET(Visual,Int,cv,map_entries)+GET(Visual,Int,cv,red_mask)+GET(Visual,VisualID,cv,visualid)+GET(XAnyEvent,Int,ev,type)+GET(XAnyEvent,WindowId,ev,window)+GET(XButtonEvent,Int,ev,button)+GET(XButtonEvent,Int,ev,state)+GET(XButtonEvent,Int,ev,x)+GET(XButtonEvent,Int,ev,x_root)+GET(XButtonEvent,Int,ev,y)+GET(XButtonEvent,Int,ev,y_root)+GET(XButtonEvent,Time,ev,time)+GET(XCharStruct,Int,cs,ascent)+GET(XCharStruct,Int,cs,descent)+GET(XCharStruct,Int,cs,lbearing)+GET(XCharStruct,Int,cs,rbearing)+GET(XCharStruct,Int,cs,width)+GET(XFontProp,Atom,fp,name)+GET(XFontProp,Int,fp,card32)+GET(XClientMessageEvent,Atom,ev,message_type)+GET(XClientMessageEvent,Int,ev,format)+GET(XColor,Int,xcol,blue)+GET(XColor,Int,xcol,green)+GET(XColor,Int,xcol,red)+GET(XColor,Word,xcol,pixel)+GET(XConfigureEvent,Int,ev,border_width)+GET(XConfigureEvent,Int,ev,height)+GET(XConfigureEvent,Int,ev,width)+GET(XConfigureEvent,Int,ev,x)+GET(XConfigureEvent,Int,ev,y)+GET(XCrossingEvent,Int,ev,detail)+GET(XCrossingEvent,Int,ev,focus)+GET(XCrossingEvent,Int,ev,mode)+GET(XCrossingEvent,Int,ev,x)+GET(XCrossingEvent,Int,ev,x_root)+GET(XCrossingEvent,Int,ev,y)+GET(XCrossingEvent,Int,ev,y_root)+GET(XCrossingEvent,Time,ev,time)+GET(XExposeEvent,Int,ev,count)+GET(XExposeEvent,Int,ev,height)+GET(XExposeEvent,Int,ev,width)+GET(XExposeEvent,Int,ev,x)+GET(XExposeEvent,Int,ev,y)+GET(XFocusChangeEvent,Int,ev,detail)+GET(XFocusChangeEvent,Int,ev,mode)+GET(XFontStruct,Char,fs,default_char)+GET(XFontStruct,HT(XCharStruct),fs,per_char)+GET(XFontStruct,HT(XFontProp),fs,properties)+GET(XFontStruct,Int,fs,all_chars_exist)+GET(XFontStruct,Int,fs,ascent)+GET(XFontStruct,Int,fs,descent)+GET(XFontStruct,Int,fs,direction)+GET(XFontStruct,XID,fs,fid)+GET(XFontStruct,Int,fs,max_byte1)+GET(XFontStruct,Int,fs,max_char_or_byte2)+GET(XFontStruct,Int,fs,min_byte1)+GET(XFontStruct,Int,fs,min_char_or_byte2)+GET(XFontStruct,Int,fs,n_properties)+GET(XGraphicsExposeEvent,Int,ev,count)+GET(XGraphicsExposeEvent,Int,ev,height)+GET(XGraphicsExposeEvent,Int,ev,major_code)+GET(XGraphicsExposeEvent,Int,ev,minor_code)+GET(XGraphicsExposeEvent,Int,ev,width)+GET(XGraphicsExposeEvent,Int,ev,x)+GET(XGraphicsExposeEvent,Int,ev,y)+GET(XKeyEvent,Int,ev,keycode)+GET(XKeyEvent,Int,ev,state)+GET(XKeyEvent,Int,ev,x)+GET(XKeyEvent,Int,ev,x_root)+GET(XKeyEvent,Int,ev,y)+GET(XKeyEvent,Int,ev,y_root)+GET(XKeyEvent,Time,ev,time)+GET(XMapEvent,WindowId,ev,window)+GET(XMotionEvent,Int,ev,state)+GET(XMotionEvent,Int,ev,x)+GET(XMotionEvent,Int,ev,x_root)+GET(XMotionEvent,Int,ev,y)+GET(XMotionEvent,Int,ev,y_root)+GET(XMotionEvent,Time,ev,time)+GET(XResizeRequestEvent,Int,ev,height)+GET(XResizeRequestEvent,Int,ev,width)+GET(XSelectionClearEvent,Atom,ev,selection)+GET(XSelectionEvent,Atom,ev,property)+GET(XSelectionEvent,Atom,ev,selection)+GET(XSelectionEvent,Atom,ev,target)+GET(XSelectionEvent,Time,ev,time)+GET(XSelectionRequestEvent,Atom,ev,property)+GET(XSelectionRequestEvent,Atom,ev,selection)+GET(XSelectionRequestEvent,Atom,ev,target)+GET(XSelectionRequestEvent,Time,ev,time)+GET(XSelectionRequestEvent,WindowId,ev,requestor)+GET(XVisibilityEvent,Int,ev,state)+GET(timeVal,Int,now,tv_sec)+GET(timeVal,Int,now,tv_usec)+GETC(sockAddr,char *,CString,sa,sa_data)+INDEX(XCharStruct)+INDEX(XFontProp)+SET(XAnyEvent,Window,xe,window,w::Window)+SET(XClassHint,CString,class_hints,res_class,rc)+SET(XClassHint,CString,class_hints,res_name,rn)+SET(XColor,Int,color,blue,blue)+SET(XColor,Int,color,green,green)+SET(XColor,Int,color,red,red)+SET(XColor,Word,c,pixel,px)+SET(XGCValues,Int,gcv,background,toC p)+SET(XGCValues,Int,gcv,cap_style,fromEnum s)+SET(XGCValues,Int,gcv,join_style,fromEnum s)+SET(XGCValues,Int,gcv,fill_style,fromEnum f)+SET(XGCValues,XID,gcv,font,toXID f)+SET(XGCValues,Int,gcv,foreground,toC p)+SET(XGCValues,Int,gcv,function,fromEnum f)+SET(XGCValues,Int,gcv,graphics_exposures, fromEnum g)+SET(XGCValues,Int,gcv,line_style,fromEnum s)+SET(XGCValues,Int,gcv,line_width,w)+SET(XGCValues,XID,gcv,stipple,toXID p)+SET(XGCValues,Int,gcv,subwindow_mode,fromEnum m)+SET(XGCValues,XID,gcv,tile,toXID p)+SET(XSelectionEvent,Atom,xe,property, props)+SET(XSelectionEvent,Atom,xe,selection, sel)+SET(XSelectionEvent,Atom,xe,target, target)+SET(XSelectionEvent,Int,xe,type,CCONST(SelectionNotify)::Int)+SET(XSelectionEvent,Time,xe,time,time)+SET(XSizeHints,Int,h,flags,CCONST(USPosition)::Int)+SET(XSizeHints,Int,h,x,x)+SET(XSizeHints,Int,h,y,y)+SET(XWMHints,Int,h,flags,CCONST(InputHint)::Int)+SET(XWMHints,Int,h,input,toC i)+SET(XWindowChanges,Int,s,border_width,w)+SET(XWindowChanges,Int,s,height,h)+SET(XWindowChanges,Int,s,stack_mode,toC sm)+SET(XWindowChanges,Int,s,width,w)+SET(XWindowChanges,Int,s,x,x)+SET(XWindowChanges,Int,s,y,y)+SET(timeVal,Int,timeout,tv_sec,(tleft `div` 1000))+SET(timeVal,Int,timeout,tv_usec,(tleft `mod` 1000) * 1000)+SETI(XPoint,Int,xpoints,i,x,x)+SETI(XPoint,Int,xpoints,i,y,y)+SETI(XRectangle,Int,rsa,i,height,h)+SETI(XRectangle,Int,rsa,i,width,w)+SETI(XRectangle,Int,rsa,i,x,x)+SETI(XRectangle,Int,rsa,i,y,y)+SETI(XdbeSwapInfo,Int,si,i,swap_action,fromEnum sa)+SETI(XdbeSwapInfo,WindowId,si,i,swap_window,wi)+SETWa(swa,background_pixel,toC p)+SETWaXID(swa,background_pixmap,toXID p)+SETWa(swa,backing_store,toC bs)+SETWa(swa,bit_gravity,toC g)+SETWa(swa,border_pixel,toC p)+SETWaXID(swa,border_pixmap,toC p)+SETWaXID(swa,cursor,toXID c)+SETWa(swa,do_not_propagate_mask,toC em)+SETWa(swa,event_mask,toC em)+SETWa(swa,override_redirect,toC b)+SETWa(swa,save_under,toC b)+SETWa(swa,win_gravity,toC g)+SINDEX(char,imgdata,i::Int,p::Int)
+ hsrc/ghc-dialogue/cfundefs.h view
@@ -0,0 +1,50 @@++#define SETI(ctype,fhtype,p1,i1,field,v1) \+ void seti_##ctype##_##field(ctype p[],int i,typeof(p[i].field) v) \+ BODY({ p[i].field=v; })++#define SINDEX(ctype,p1,i1,v1) \+ void sindex_##ctype(ctype p[],int i,typeof(p[i]) v) \+ BODY({ p[i]=v; })++/*(_casm_ ``((ctype *)%0)[%1]=%2;'' (p) (i) (v) :: IO ())*/++#define SET(ctype,fhtype,p1,field,v1) \+ void set_##ctype##_##field(ctype *p,typeof(p->field) v) \+ BODY({ p->field=v; })++#define SETWa(swa,field,v) SET(XSetWindowAttributes,Int,swa,field,v)+#define SETWaXID(swa,field,v) SET(XSetWindowAttributes,XID,swa,field,v)++/* (_casm_ ``((ctype *)%0)->field=%1;'' (addrOf (p)) (v) :: IO ())*/++#define GET(ctype,rhtype,p1,field) \+ typeof(((ctype *)0)->field) get_##ctype##_##field(ctype *p) \+ BODY({ return p->field; })++#define GETC(ctype,crtype,rhtype,p1,field) \+ crtype get_##ctype##_##field(ctype *p) \+ BODY({ return p->field; })++/* (_casm_ `` %r = ((ctype *)%0)->field; '' (addrOf (p))) */++#define AGET(ctype,rhtype,p1,field) \+ typeof(&(((ctype *)0)->field)) aget_##ctype##_##field(ctype *p) \+ BODY({ return &(((ctype *)p)->field); })++/* (_casm_ `` %r = &(((ctype *)%0)->field); '' ((p)::HT(ctype))) */++#define INDEX(ctype) \+ ctype *index_##ctype(ctype *p,int i) \+ BODY({ return p+i; })++/* (\pP iI -> _casm_ ``%r = (ctype *)%0 + (int)%1;'' ((pP) :: HT(ctype)) iI) */++#define CINDEX(t) \+ t cindex_##t(t p[],int i) \+ BODY({ return p[i]; })++/* (\pP iI -> _casm_ ``%r = ((t *)%0)[(int)%1];'' pP iI) */++#define CCONST(c) int const_##c(void) BODY({ return (c);})+#define CWORD32(c) int const_##c(void) BODY({ return (c);})
+ hsrc/ghc-dialogue/cfuns.c view
@@ -0,0 +1,4 @@+#include <errno.h>++#define BODY(b) b+#include "cfuns.h"
+ hsrc/ghc-dialogue/cfuns.h view
@@ -0,0 +1,11 @@+#include "asyncinput.h"+#include <X11/extensions/Xdbe.h>++#ifndef BODY+#define BODY(b) ;+#endif+#include "cfundefs.h"+#include "ccalls.h"++#define CSIZE(ctype) int fudsizeof_##ctype(void) BODY({ return sizeof(ctype); })+#include "csizes.h"
+ hsrc/ghc-dialogue/cimports.h view
@@ -0,0 +1,41 @@+#define FI foreign import ccall unsafe "cfuns.h"++#define SETI(ctype,fhtype,p1,i1,field,v1) \+ FI seti_/**/ctype/**/_/**/field :: HTA(ctype) -> Int -> (fhtype) -> IO ()++/* (_casm_ ``((ctype *)%0)[%1].field=%2;'' ((p)::HT(ctype)) (i) (v) :: IO ()) */+#define SINDEX(ctype,p1,i1,v1) \+ FI sindex_/**/ctype :: Addr -> Int -> HT(ctype) -> IO ()++/*(_casm_ ``((ctype *)%0)[%1]=%2;'' (p) (i) (v) :: IO ())*/++#define SET(ctype,fhtype,p1,field,v1) \+ FI set_/**/ctype/**/_/**/field :: HT(ctype) -> fhtype -> IO ()++/* (_casm_ ``((ctype *)%0)->field=%1;'' (addrOf (p)) (v) :: IO ())*/++#define SETWa(swa,field,v) SET(XSetWindowAttributes,Int,swa,field,v)+#define SETWaXID(swa,field,v) SET(XSetWindowAttributes,XID,swa,field,v)+++#define GET(ctype,rhtype,p1,field) \+ FI get_/**/ctype/**/_/**/field :: HT(ctype) -> IO rhtype++#define GETC(ctype,rctype,rhtype,p1,field) GET(ctype,rhtype,p1,field)++/* (_casm_ `` %r = ((ctype *)%0)->field; '' (addrOf (p))) */++#define AGET(ctype,rhtype,p1,field) FI aget_/**/ctype/**/_/**/field :: HT(ctype) -> IO (rhtype)++/* (_casm_ `` %r = &(((ctype *)%0)->field); '' ((p)::HT(ctype))) */++#define INDEX(ctype) FI index_/**/ctype :: HT(ctype) -> Int -> IO HT(ctype)++/* (\pP iI -> _casm_ ``%r = (ctype *)%0 + (int)%1;'' ((pP) :: HT(ctype)) iI) */++#define CINDEX(t) FI cindex_/**/t :: Addr -> Int -> IO (HT(t))++/* (\pP iI -> _casm_ ``%r = ((t *)%0)[(int)%1];'' pP iI) */++#define CCONST(c) FI const_/**/c :: Int+#define CWORD32(c) FI const_/**/c :: Word32
+ hsrc/ghc-dialogue/csizes.h view
@@ -0,0 +1,19 @@++CSIZE(Atom)+CSIZE(XEvent)+CSIZE(XPoint)+CSIZE(XColor)+CSIZE(XGCValues)+CSIZE(XWMHints)+CSIZE(XdbeSwapInfo)+CSIZE(XClassHint)+CSIZE(XSetWindowAttributes)+CSIZE(XSizeHints)+CSIZE(XWindowChanges)+CSIZE(XRectangle)+CSIZE(XCharStruct)+CSIZE(XFontStruct)+CSIZE(XFontProp)+CSIZE(timeVal)+CSIZE(sockAddr)+CSIZE(fd_set)
+ hsrc/ghc-dialogue/newstructfuns.h view
@@ -0,0 +1,17 @@+#include "structs.h"++#define SETI(ctype,fhtype,p,i,field,v) (seti_/**/ctype/**/_/**/field (p) (i) (v))+#define SINDEX(ctype,p,i,v) (sindex_/**/ctype (p) (i) (v))+#define SET(ctype,fhtype,p,field,v) (set_/**/ctype/**/_/**/field (p) (v))+#define GET(ctype,rhtype,p,field) (get_/**/ctype/**/_/**/field (p))+#define GETC(ctype,rctype,rhtype,p,field) GET(ctype,rhtype,p,field)+#define INDEX(ctype) index_/**/ctype+#define CINDEX(t) cindex_/**/t++#define SETWa(swa,field,v) SET(XSetWindowAttributes,Int,swa,field,v)+#define SETWaXID(swa,field,v) SET(XSetWindowAttributes,XID,swa,field,v)++#define AGET(ctype,rhtype,p,field) (aget_/**/ctype/**/_/**/field (p))++#define CCONST(c) const_/**/c+#define CWORD32(c) CCONST(c)
+ hsrc/ghc-dialogue/structs.h view
@@ -0,0 +1,57 @@+--- New stuff for GHC 4.08.1, 2000-11-25 /TH++#define IORC(p,t,c) instance PrimResult (IO (p)) (IO (t)) where{unmarshall=(c)}+#define CA(t,p,c) instance PrimArg (t) (p) r where {marshall f = f .(c)}++#define IDR(t) instance PrimResult (IO (t)) (IO (t)) where {unmarshall=id}+#define IDA(t) CA(t,t,id)+#define IDAR(t) IDR(t);IDA(t);INSTCCALL(t)+#define IDAR0(t) IDR(t);IDA(t)++#define ENUMR(t) IORC(Int,t,fmap toEnum)+#define ENUMA(t) CA(t,Int,fromEnum)+#define ENUMAR(t) ENUMR(t);ENUMA(t)++--- Old stuff, modified to fit with the new stuff, 2000-11-25 /TH++#define HT(ctype) C/**/ctype+#define HTA(ctype) HT(ctype)Array++#define NEWTYPE(t) newtype t = t Addr deriving (Eq,Show)+#define HASADDR(t) instance HasAddr t where {addrOf (t addr) = addr}+#if 0+#define INSTCCALL(t) instance CCallable t;instance CReturnable t+#else+#define INSTCCALL(t)+#endif++#define ISTORE(t) \+ instance Storable t where { \+ sizeOf (t a) = sizeOf a; \+ alignment (t a) = alignment a; \+ peek p = t <$> peek p; \+ poke p (t a) = poke p a }++#define SIZEOF(ctype) (fudsizeof_/**/ctype)++#define IPTR(ctype) \+ new/**/ctype/**/Array n = HT(ctype) `fmap` malloc (n*SIZEOF(ctype)); \+ new/**/ctype = new/**/ctype/**/Array 1; \+ HASADDR(HT(ctype)); \+ instance IsPtr HT(ctype) where { \+ nullPtr = HT(ctype) nullAddr;\+ newPtr = new/**/ctype ;\+ newArray = new/**/ctype/**/Array}++-- freePtr (HT(ctype) addr) = free addr++#define H_STRUCTTYPE(ctype) \+ NEWTYPE(HT(ctype));IPTR(ctype);IDAR(HT(ctype))++#define H_ARRAY(ctype) H_STRUCTTYPE(ctype); ISTORE(HT(ctype)) ; type HTA(ctype) = HT(ctype)++#define C_STRUCTTYPE(ctype) \+ NEWTYPE(HT(ctype)); \+ HASADDR(HT(ctype)); \+ ISTORE(HT(ctype)); \+ INSTCCALL(HT(ctype))
+ hsrc/ghc/DFudIO.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE CPP #-}+module DFudIO(Fudlogue,fudlogue,fudlogue'{-,fudIO,fudIO'-},HasCache(..)) where++import FDefaults+import FudIO(fudIO1)+--import FudIO2(fudIO2)+import Fudget+--import Xtypes+--import Cache(allcacheF)+import NewCache(allcacheF)+import CmdLineEnv(argFlag)++#include "defaults.h"++data Fudlogue = Pars [Pars]+data Pars = Cache Bool++parameter_class(Cache,Bool)+parameter_instance(Cache,Fudlogue)++fudlogue = fudlogue' standard+fudlogue' :: Customiser Fudlogue -> F a b -> IO ()+fudlogue' pmod f = fudIO1 (cache pmod f)+{-+fudIO = fudIO' standard+--fudIO' :: Customiser Fudlogue -> F a b -> IO ()+fudIO' pmod inCh outCh f = fudIO2 inCh outCh (cache pmod f)+-}++cache pmod = if getCache ps then allcacheF else id+ where ps = pmod (Pars [Cache usecache])++usecache = argFlag "cache" True
+ hsrc/ghc/DialogueSpIO.hs view
@@ -0,0 +1,55 @@+module DialogueSpIO where+import System.IO(hFlush,stdout)+import SP+import DoRequest(initXCall,doRequest,getAsyncInput)+import DialogueIO(Request(XCommand,GetAsyncInput))+import Queue+import CmdLineEnv(argFlag)++--dialogueSpIO :: SP FResponse FRequest -> IO ()+{-+--Old, simple implementation:+dialogueSpIO sp =+ case sp of+ PutSP req sp' ->+ do resp <- doRequest req+ dialogueSpIO (startupSP [resp] sp')+ GetSP xsp ->+ do resp <- doRequest GetAsyncInput+ dialogueSpIO (xsp resp)+ NullSP -> return ()+-}++dialogueSpIO = if argFlag "dialogue-to-stdio" False+ then stdioDialogueSpIO+ else normalDialogueSpIO++normalDialogueSpIO = dialogueSpIO' initXCall doRequest getAsyncInput++stdioDialogueSpIO = dialogueSpIO' initXCall doRequest getAsyncInput+ where+ initXCall = return ()+ doRequest _ req = do print req+ hFlush stdout+ readLn+ getAsyncInput state = doRequest state GetAsyncInput++-- More efficient queueing of responses+dialogueSpIO' initXCall doRequest getAsyncInput sp = do+ iostate <- initXCall+ let doIO sp respq =+ case sp of+ PutSP req sp' ->+ do resp <- doRequest iostate req+ case req of+ -- The response to an XCommand is always Success+ -- and is not propagated to the originating fudget.+ XCommand {} -> doIO sp' respq+ _ -> doIO sp' (enter respq resp)+ GetSP xsp ->+ case qremove respq of+ Just (resp,respq') -> doIO (xsp resp) respq'+ Nothing -> do resp <- getAsyncInput iostate+ doIO (xsp resp) respq+ NullSP -> return ()+ doIO sp empty
+ hsrc/ghc/FudIO.hs view
@@ -0,0 +1,16 @@+module FudIO(fudIO1) where+import CmdLineEnv(argFlag)+--import Fudget+import SpIO+import TagEvents+import FudVersion++--fudIO1 :: F a b -> IO ()+fudIO1 mainF =+ if argFlag "version" False+ then showVersion+ else spIO mainSP+ where+ mainSP = tagEventsSP mainF++ showVersion = putStrLn ("Fudget library " ++ version)
+ hsrc/ghc/GetModificationTime.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE CPP #-}+module GetModificationTime where+import HaskellIO+import DialogueIO++#ifdef VERSION_old_time+getModificationTime path err cont =+ hIOerr (GetModificationTime path) err $ \ (ClockTime t) ->+ cont t+#else+getModificationTime path err cont =+ hIOerr (GetModificationTime path) err $ \ (UTCTime t) ->+ cont t+#endif
+ hsrc/ghc/GetTime.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE CPP #-}+module GetTime where+import HaskellIO(hIO)+import DialogueIO++#ifdef VERSION_old_time+getTime cont = hIO GetTime $ \ (ClockTime t) -> cont t+getLocalTime cont = hIO GetLocalTime $ \ (CalendarTime t) -> cont t+#endif++#ifdef VERSION_time+getCurrentTime cont = hIO GetCurrentTime $ \ (UTCTime t) -> cont t+getZonedTime cont = hIO GetZonedTime $ \ (ZonedTime t) -> cont t+#endif
+ hsrc/ghc/HbcWord.hs view
@@ -0,0 +1,15 @@+module HbcWord(module HbcWord,Word) where+import Data.Word+import Data.Bits++--type Word=Word.Word32+--type Short=Word16++bitAnd x y = x .&. y+bitOr x y = x .|. y+bitXor x y = xor x y+bitRsh x y = shiftR x y+bitLsh x y = shiftL x y++intToWord = fromIntegral :: Int->Word+wordToInt = fromIntegral :: Word->Int
+ hsrc/ghc/List2.hs view
@@ -0,0 +1,3 @@+module List2(sort) where+-- List(sort) seem to be missing in ghc 2.01+import Data.List(sort)
+ hsrc/ghc/LowLevel.hs view
@@ -0,0 +1,12 @@+module LowLevel (-- * Low level+ module Cont,module Display,module SpIO,module TagEvents,module WindowF,module Xrequest,module Xcommand,module Srequest,module DFudIO, module FudgetIO) where+import Cont+import Display+import SpIO+import TagEvents+import WindowF+import Xrequest+import Xcommand+import Srequest+import DFudIO+import FudgetIO
+ hsrc/ghc/PackedString.hs view
@@ -0,0 +1,22 @@+-- | Fake PackedString type+module PackedString{-(module PS)-} where+--import Data.PackedString as PS++newtype PackedString = PS String deriving (Eq,Ord)++instance Show PackedString where+ showsPrec n (PS s) r = s++r++instance Read PackedString where+ readsPrec n s0 = [(PS s,r)|(s,r)<-readsPrec n s0]++packString = PS+unpackPS (PS s) = s++nullPS (PS s) = null s+lengthPS (PS s) = length s++appendPS (PS s1) (PS s2) = PS (s1++s2)+mapPS f (PS s) = PS (map f s)+nilPS = PS ""+reversePS (PS s) = PS (reverse s)
+ hsrc/ghc/ShowFun.hs view
@@ -0,0 +1,9 @@+module ShowFun where+import Text.Show.Functions()++{-+In Haskell 98, the function type is no longer an instance of the Show class.+This means that you can't derive Show for data types containing functions...+-}++instance Read (a->b)
+ hsrc/ghc/SpIO.hs view
@@ -0,0 +1,50 @@+module SpIO(spIO) where+--import Command+--import Event+import Loopthrough+import Path(Path(..))+import Cont(getRightSP)+import ShowFailure+--import Sockets+import Spops+import SP(SP)+import Tables2+--import Xtypes+import DialogueSpIO+import DialogueIO hiding (IOError)+--import Table(Table) -- nhc bug workaround++spIO :: (SP (Path, Response) (Path, Request)) -> IO ()+spIO mainSP = dialogueSpIO (loopThroughRightSP tagRequestsSP mainSP)++tagRequestsSP = tagRequests dtable0+tagRequests dtable =+ getSP $ \msg ->+ case msg of+ Left (path', cmd) ->+ case cmd of+ Select ds -> let dtable' = updateDe path' ds dtable+ in doReqSP (Select (listDe dtable')) $ \ resp ->+ checkErr resp (tagRequests dtable')+ XCommand _ -> putReqSP cmd $ -- \ resp ->+ -- The response to an XCommand is always Success+ -- and is not propagated to the originating fudget.+ tagRequests dtable+ _ -> doReqSP cmd $ \ resp ->+ putSP (Left (path', resp)) $+ tagRequests dtable+ Right ai@(AsyncInput (d, i)) ->+ putSP (Left (lookupDe dtable d, ai)) $+ tagRequests dtable+ _ -> error ("tagRequests: " ++ show msg ++ "\n")++checkErr resp cont =+ case resp of+ Success -> cont+ Failure ioerr -> error ("IOerror: " ++ showFailure ioerr)++doReqSP req = putReqSP req . getRespSP+ where+ getRespSP = getRightSP++putReqSP = putSP . Right
+ hsrc/ghc/UnsafePerformIO.hs view
@@ -0,0 +1,3 @@+module UnsafePerformIO(unsafePerformIO) where+import System.IO.Unsafe(unsafePerformIO)+
+ hsrc/hbc_library/FudUTF8.hs view
@@ -0,0 +1,34 @@+-- | From the Char module supplied with HBC.+module FudUTF8 where+++decodeUTF8 :: String -> String+decodeUTF8 "" = ""+decodeUTF8 (c:cs) | c < '\x80' = c : decodeUTF8 cs+decodeUTF8 (c:c':cs) | '\xc0' <= c && c <= '\xdf' && + '\x80' <= c' && c' <= '\xbf' =+ toEnum ((fromEnum c `mod` 0x20) * 0x40 + fromEnum c' `mod` 0x40) : decodeUTF8 cs+decodeUTF8 (c:c':c'':cs) | '\xe0' <= c && c <= '\xef' && + '\x80' <= c' && c' <= '\xbf' &&+ '\x80' <= c'' && c'' <= '\xbf' =+ toEnum ((fromEnum c `mod` 0x10 * 0x1000) + (fromEnum c' `mod` 0x40) * 0x40 + fromEnum c'' `mod` 0x40) : decodeUTF8 cs+decodeUTF8 _ = error "UniChar.decodeUTF8: bad data"++-- | Take a Unicode string and encode it as a string+-- with the UTF8 method.+encodeUTF8 :: String -> String+encodeUTF8 "" = ""+encodeUTF8 (c:cs) =+ if c > '\x0000' && c < '\x0080' then+ c : encodeUTF8 cs+ else if c < toEnum 0x0800 then+ let i = fromEnum c+ in toEnum (0xc0 + i `div` 0x40) : + toEnum (0x80 + i `mod` 0x40) : + encodeUTF8 cs+ else+ let i = fromEnum c+ in toEnum (0xe0 + i `div` 0x1000) : + toEnum (0x80 + (i `mod` 0x1000) `div` 0x40) : + toEnum (0x80 + i `mod` 0x40) : + encodeUTF8 cs
+ hsrc/infix/CompOps.hs view
@@ -0,0 +1,48 @@+module CompOps where+import CompF(compF)+import ParF(parF)+import CompFfun+import Fudget+import SerCompF(serCompF)+import CompSP(serCompSP,compEitherSP)+import ParSP(parSP)++-- Change priority??+infixl 5 >+<+infixl 5 >*<+infixr 4 >==<+infixr 8 -==-, -+-, -*-+infixr 7 >^^=<+infixr 5 >..=<+infixl 6 >=^^<+infixl 6 >=..<+infixr 7 >^=<+infixr 6 >.=<+infixl 6 >=^<+infixl 6 >=.<++-- Infix operators for common stream processor combinators.++sp1 -==- sp2 = serCompSP sp1 sp2+sp1 -+- sp2 = compEitherSP sp1 sp2+sp1 -*- sp2 = parSP sp1 sp2++-- Infix operators for common fudget combinators.++w1 >+< w2 = compF w1 w2+w1 >*< w2 = parF w1 w2+w1 >==< w2 = serCompF w1 w2++(>^^=<) :: (SP a b) -> (F e a) -> F e b+f >^^=< w = postProcessHigh f w+(>=^^<) :: (F c d) -> (SP e c) -> F e d+w >=^^< f = preProcessHigh w f+(>^=<) :: (a -> b) -> (F e a) -> F e b+f >^=< w = postMapHigh f w+(>=^<) :: (F c d) -> (e -> c) -> F e d+w >=^< f = preMapHigh w f++f >..=< w = postProcessLow f w+w >=..< f = preProcessLow w f+f >.=< w = postMapLow f w+w >=.< f = preMapLow w f
+ hsrc/infix/InfixOps.hs view
@@ -0,0 +1,8 @@+module InfixOps (-- * InfixOps+ module CompOps,module LayoutOps,module OldLayoutOps) where+import CompOps+import LayoutOps+import OldLayoutOps++--import Fudget+--import LayoutDir(Orientation)
+ hsrc/infix/LayoutOps.hs view
@@ -0,0 +1,11 @@+module LayoutOps((>#==<), (>#+<)) where+--import Fudget+--import LayoutDir(Orientation)+import LayoutF(compLF,serCompLF)++infixl >#+<, >#==<++-- Infix operators for common layout combinators.++f1o >#+< f2 = compLF f1o f2+f1o >#==< f2 = serCompLF f1o f2
+ hsrc/infix/OldLayoutOps.hs view
@@ -0,0 +1,27 @@+module OldLayoutOps((>==#<), (>+#<)) where+--import Fudget+import LayoutDir(Orientation(..))+import Placers(horizontalP',verticalP')+import Placer(placerF)+import AlignP(revP)+--import LayoutRequest+--import Geometry+import CompF(compF)+import SerCompF(serCompF)++infixl >+#<, >==#<++-- Old version of infix operators for common layout combinators.+-- Provided for backwards compatibility only.++f1 >+#< of2 = cLF compF f1 of2+f1 >==#< of2 = cLF serCompF f1 of2++cLF cF f1 (dist,ori,f2) =+ let placer =+ case ori of+ Above -> verticalP'+ Below -> revP . verticalP'+ LeftOf -> horizontalP'+ RightOf -> revP . horizontalP'+ in placerF (placer dist) (cF f1 f2)
+ hsrc/internals/CompiledGraphics.hs view
@@ -0,0 +1,145 @@+module CompiledGraphics where+import Geometry(Rect(..))+import Utils(number)+import DrawTypes(DrawCommand)+import ResourceIds(GCId,rootGC)+import Rects(overlaps,boundingRect)+import Maptrace(ctrace)++{-+--Version 1:+data CompiledGraphics = CGraphics Rect GCtx [DrawCommand] [CompiledGraphics]+-}++{-+--Version 2:+data CompiledGraphics = CGraphics Rect [XCommand] [CompiledGraphics]+ -- The only XCommand used is Draw MyWindow some_GC some_DrawCommand+-}++{-+--Version 3:+data CompiledGraphics = CGraphics Rect Cursor [XCommand] [CompiledGraphics]+ -- The only XCommand used is Draw MyWindow some_GC some_DrawCommand+-}++{-+--Version 4:+data CompiledGraphics+ = CGraphics Rect Cursor [XCommand] [CompiledGraphics]+ -- The only XCommand used is Draw MyWindow some_GC some_DrawCommand+ | CGMark CompiledGraphics -- path preserving dummy nodes+-}++--Version 5:+data CompiledGraphics+ = CGraphics Rect Cursor [(GCId,[DrawCommand])] [CompiledGraphics]+ | CGMark CompiledGraphics -- path preserving dummy nodes+ deriving (Show)++type Cursor = Bool++cgLeaf r rcmds =+ --ctrace "gctrace" cmds $+ cg+ where+ cg = CGraphics r False cmds []+ --cmds = (map (Draw MyWindow gc) (f r))+ cmds = rcmds r++cgMark = CGMark++cgCompose r cgs = CGraphics r False cmds cgs+ where+ cmds = if anyOverlap cgs+ then ctrace "cgoverlap" (map cgrect cgs) $+ [(rootGC,[])] --trick coding to force all subtrees to be redrawn+ else []++ -- This is O(n^2) in general, but the bounding rect makes it O(n) for+ -- linear placers. It may also help somewhat for tables...+ -- Sorting the rectangles can cut down the complexity too...+ -- Better to let the placers tell if they produce overlapping parts...+ anyOverlap [] = False+ anyOverlap (cg:cgs) = anyOverlaps' [r] r cgs+ where r = cgrect cg++ anyOverlaps' rs bounding [] = False+ anyOverlaps' rs bounding (cg:cgs) =+ r `overlaps` bounding && any (overlaps r) rs ||+ anyOverlaps' (r:rs) (boundingRect bounding r) cgs+ where r = cgrect cg++cgrect (CGMark cg) = cgrect cg+cgrect (CGraphics r _ _ _) = r+cgsize = rectsize.cgrect++addcursor (CGMark cg) = CGMark (addcursor cg) -- hmm!!+addcursor (CGraphics r _ cmds cgs) = CGraphics r True cmds cgs+removecursor (CGMark cg) = CGMark (removecursor cg) -- hmm!!+removecursor (CGraphics r _ cmds cgs) = CGraphics r False cmds cgs+hascursor (CGMark cg) = hascursor cg -- hmm!!+hascursor (CGraphics _ cur _ _) = cur++cgpart cg [] = cg+cgpart (CGMark cg) (0:ps) = cgpart cg ps+cgpart (CGraphics _ _ _ parts) (p:ps) =+ if p<1||p>length parts then error "bad path in CompiledGraphics.cgpart " else+ cgpart (parts !! ((p::Int)-1)) ps++cgreplace cg path new = cgupdate cg path (const new)++{-+cgupdate cg ps f =+ (if any (<1) ps+ then ctrace "cgupdate" ps+ else id) $ cgupdate' cg ps f+-}++cgupdate cg [] f = f cg+cgupdate (CGMark cg) (0:ps) f = CGMark (cgupdate cg ps f)+cgupdate (CGMark cg) ps f =+ ctrace "badpath" ("(CGMark _) "++show ps) $+ CGMark (cgupdate cg ps f)+cgupdate cg (0:ps) f =+ ctrace "badpath" (cg,0:ps) $+ CGMark (cgupdate cg ps f)+cgupdate (CGraphics r cur dcmds parts) (p:ps) f =+ CGraphics r cur dcmds (pre++cgupdate cg' ps f:post)+ where pre = take (p-1) parts+ cg':post = drop ((p-1)::Int) parts++cgcursors :: CompiledGraphics -> [[Int]]+cgcursors (CGMark cg) = map (0:) (cgcursors cg)+cgcursors (CGraphics _ cur _ parts) =+ if cur+ then []:partcursors+ else partcursors+ where+ partcursors =+ concatMap (\(n,ps) -> map (n:) (cgcursors ps)) (number 1 parts)++cgGroup pos len (CGMark cg) = CGMark (cgGroup pos len cg) -- hmm!!+cgGroup pos len (CGraphics r cur dcmds parts) =+ CGraphics r cur dcmds (ds1++cgCompose r2 ds2:ds3)+ where+ (ds1,ds2a) = splitAt (pos-1) parts+ (ds2,ds3) = splitAt len ds2a+ r2 = foldr (boundingRect.cgrect) (Rect 0 0) ds2++cgUngroup pos (CGMark cg) = CGMark (cgUngroup pos cg) -- hmm!!+cgUngroup pos cg@(CGraphics r cur dcmds parts) =+ case splitAt (pos-1) parts of+ (ds1,d2:ds3) ->+ case unmark 0 d2 of+ (m,CGraphics r2 cur2 dcmds2 ds2) ->+ CGraphics r cur (dcmds++dcmds2) (ds1++map (mark m) ds2++ds3)+ _ -> cg -- hmm!!++ _ -> cg -- hmm!!+ where+ unmark n (CGMark cg) = unmark (n+1) cg+ unmark n cg = (n,cg)++ mark 0 cg = cg+ mark n cg = mark (n-1) (CGMark cg)
+ hsrc/internals/DLValue.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE CPP #-}+module DLValue where++#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)+data DLValue = DLValue (forall a. a)+#elif defined(__NHC__) || defined(__PFE__)+-- not supported+data DLValue = DLValue+#else+data DLValue = DLValue a +#endif++instance Show DLValue where+ showsPrec i d = ("DLValue"++)++instance Read DLValue
+ hsrc/internals/DrawCompiledGraphics.hs view
@@ -0,0 +1,24 @@+module DrawCompiledGraphics(drawK,drawK',drawChangesK,drawChangesK') where+import qualified DrawCompiledGraphics1 as D1+--import qualified DrawCompiledGraphics2 as D2+--import qualified DrawCompiledGraphics3 as D3+import DrawTypes(Drawable(MyWindow))+import CmdLineEnv(argReadKey)++drawK x = D1.drawK' MyWindow x+drawChangesK x = D1.drawChangesK' Nothing x++drawK' x = D1.drawK' x+drawChangesK' x = D1.drawChangesK' x+--drawK' = drawChoice D1.drawK' D2.drawK' D3.drawK'+--drawChangesK' = drawChoice D1.drawChangesK' D2.drawChangesK' D3.drawChangesK'+++drawChoice =+ case choice of+ 1 -> \ d1 d2 d3 -> d1+-- 2 -> \ d1 d2 d3 -> d2+-- 3 -> \ d1 d2 d3 -> d3+ _ -> error "unkown version of DrawCompiledGraphics"+ where+ choice = argReadKey "draw" (1::Int)
+ hsrc/internals/DrawCompiledGraphics1.hs view
@@ -0,0 +1,94 @@+module DrawCompiledGraphics1(drawK',drawChangesK',GCId) where+--import Fudget+import Xtypes+import XDraw(DrawCommand(FillRectangle),clearArea,draw,drawMany,Drawable(..))+import Geometry(growrect,(=.>),Rect(rectsize))+--import Message+--import NullF(putsK,putK)+import Utils(number)+--import EitherUtils(mapfilter)+import Data.Maybe(mapMaybe)+import CompiledGraphics+--import Rects+--import Maptrace(ctrace) -- debug+--import Io(echoK) -- debug+import FudgetIO(putLow)++--tr x = seq x $ ctrace "drawtrace" x x+--trLow = Low . tr+--trLow = tr . Low+--maptrLow = map trLow+--debugK = echoK++--drawK = drawK' MyWindow+drawK' d (higc,hiR) clip cg =+ case draw cg [] of+ [] -> id+ cmds -> putLow $ drawMany d cmds+ where+ draw (CGMark cg) = draw cg+ draw (CGraphics r cur cmds gs) =+ (if cur+ then ((higc,[FillRectangle cr | hr<-hiR r,cr<-clip hr]):)+ else id).+ (cmds++) .+ draws gs+ draws [] = id+ draws (g:gs) = draw g . draws gs++drawChangesK' d beQuick higc (CGMark cg) (CGMark ocg) changes =+ --debugK (show [ ps | ps<-changes, take 1 ps/=[0]]) .+ drawChangesK' d beQuick higc cg ocg (mapMaybe drop0 changes)+ where drop0 [] = Just []+ drop0 (0:ps) = Just ps+ drop0 _ = Nothing++drawChangesK' d beQuick higc cg@(CGraphics r _ cmds cgs )+ ocg@(CGraphics or _ ocmds ocgs) changes =+ --debugK (unwords ["Changes:",show changes,"or",show or,"nr",show r]) .+ if r/=or || [] `elem` changes+ -- Hack for overlapping parts:+ || not (null changes || null cmds && null ocmds)+ then --debugK "Drawing" .+ -- !! test if scrolling is enough+ eraseOldK d r or .+ reDrawK' d beQuick higc cg+ else if null changes+ then --debugK "Pruning" .+ id+ else --debugK "Descending" .+ let changes' i= [ p | i':p <- changes, i'==i]+ in foldr (.) id [drawChangesK' d beQuick higc cg ocg (changes' i) |+ (i,(cg,ocg))<-number 1 (zip cgs ocgs)]+drawChangesK' d beQuick higc cg ogc _ =+ --debugK "drawNewK" .+ drawNewK cg+ where+ drawNewK (CGMark cg) = drawNewK cg+ drawNewK cg@(CGraphics r _ _ _) =+ eraseOldK d r (cgrect ogc) .+ reDrawK' d beQuick higc cg++eraseOldK Nothing newrect oldrect =+ -- It's enough to clear the part of oldrect that is outside newrect.+ ifK (newrect/=oldrect)+ (putLow $ clearArea (growrect oldrect 1) False)+eraseOldK (Just (d,cleargc)) newrect oldrect =+ ifK (newrect/=oldrect)+ (putLow $ draw d cleargc (FillRectangle (growrect oldrect 1)))++reDrawK' d beQuick higc (CGMark cg) = reDrawK' d beQuick higc cg+reDrawK' Nothing beQuick higc cg@(CGraphics r _ _ _) =+ -- When drawing directly in a window:+ if (not beQuick || rectsize r =.> 400) -- heuristic+ then -- for big areas: wait for exposure event and draw only the+ -- visible part+ putLow (clearArea r True)+ else -- for small areas: draw everything immediately (reduced flicker)+ putLow (clearArea r False) . drawK' MyWindow higc (:[]) cg+reDrawK' (Just (d,cleargc)) beQuick higc cg@(CGraphics r _ _ _) =+ -- For drawing in a back buffer or a pixmap (assumes d/=MyWindow):+ putLow (draw d cleargc (FillRectangle r)) .+ drawK' d higc (:[]) cg++ifK b k = if b then k else id
+ hsrc/internals/Editfield.hs view
@@ -0,0 +1,84 @@+module Editfield(EditField, moveField, replaceField, setFieldDir, getField,getField',+ deselectField, getSelection, getLastLineNo, getAft, getBef, getLnoEdge,+ createField, dirint, splitnl, nlines) where+import HbcUtils(breakAt)+import Edtypes++--export EditField,newline,nlines,splitnl,+data EditField = F EDirection String String String Int Int + deriving (Eq, Ord)++-- bef sel aft ^ lastlineno+-- lno for selection edge++nlines s = length (filter (== newline) s)++splitnl = breakAt newline++dirint ERight = 1+dirint ELeft = -1++befaft dir bef sel aft =+ if dir == ELeft then (bef, sel ++ aft) else (sel ++ bef, aft)++createField s = F ERight [] [] s 0 (nlines s)+getLnoEdge (F dir bef sel aft elno lno) =+ (elno, befaft dir bef sel aft)+getBef (F dir bef sel aft elno lno) = bef+getAft (F dir bef sel aft elno lno) = aft+getLastLineNo (F dir bef sel aft elno lno) = lno+getSelection (F dir bef sel aft elno lno) =+ if dir == ELeft then sel else reverse sel++deselectField (F dir bef sel aft elno lno) =+ let (bef', aft') = befaft dir bef sel aft+ in F dir bef' [] aft' elno lno++getField f = reverse (getBef f) ++ getSelection f ++ getAft f+getField' f = (reverse (getBef f),getSelection f,getAft f)++setFieldDir ndir field@(F dir bef sel aft elno lno) =+ if ndir == dir then+ field+ else+ let elno' = elno + dirint ndir * nlines sel+ in F ndir bef (reverse sel) aft elno' lno++replaceField (F dir bef sel aft elno lno) s =+ let linessel = nlines sel+ liness = nlines s+ elno' = elno + liness - (if dir == ERight then linessel else 0)+ lno' = lno + (liness - linessel)+ in F ERight (reverse s ++ bef) [] aft elno' lno'++moveField :: IsSelect -> EditField -> EditStopFn -> (EditField,String)+moveField issel (F dir bef sel aft elno lno) sf =+ let mo dir' bef' sel' aft' elno' acc sf =+ let stop = (F dir' bef' sel' aft' elno' lno, acc)+ (b, a) = befaft dir' bef' sel' aft'+ in case sf b a of + EdStop -> stop+ EdGo wdir sf' -> + let next c dir'' bef'' sel'' aft'' =+ let elno'' =+ if c == newline then+ dirint wdir + elno'+ else+ elno'+ in mo dir'' bef'' sel'' aft'' elno'' (c:acc) sf'+ in if wdir == dir' || null sel' then+ case wdir of+ ELeft -> case bef' of+ [] -> stop+ c:bef'' -> next c wdir bef'' (c:sel') aft'+ ERight -> case aft' of+ [] -> stop+ c:aft'' -> next c wdir bef' (c:sel') aft''+ else+ let c:sel'' = sel'+ in case dir' of+ ELeft -> next c dir' (c:bef') sel'' aft'+ ERight -> next c dir' bef' sel'' (c:aft')+ (field, acc) = mo dir bef sel aft elno [] sf+ in if issel then (field, acc) else (deselectField field, [])+
+ hsrc/internals/IntMemo.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE CPP #-}+module IntMemo(memoInt) where+import Prelude hiding (lookup)+import CmdLineEnv(argFlag)++#ifndef __NHC__+#define STRICTARG(x) (x){-#STRICT#-}+#else+#define STRICTARG(x) (x)+#endif++data IntMemo a+ = Tip+ | Node a (IntMemo a) (IntMemo a)++lookup :: Int -> IntMemo a -> Maybe a+lookup n m =+ case m of+ Tip -> Nothing+ Node x l r ->+ case n of+ 0 -> Just x+ _ -> lookup (n `div` 2) (STRICTARG(if n `mod` 2==0 then l else r))++memoInt :: (Int->a)->(Int->a)+memoInt f = if memoOn then g else f+ where+ g n = if n<0+ then case lookup (-n) negtable of Just x -> x+ else case lookup n table of Just x -> x+ table = tabulate 0 1+ negtable = tabulate 0 (-1)+ tabulate n b = Node (f n) (tabulate n (STRICTARG(2*b)))+ (tabulate (STRICTARG(n+b)) (STRICTARG(2*b)))++memoOn = argFlag "memoint" True
+ hsrc/internals/IsRequest.hs view
@@ -0,0 +1,18 @@+module IsRequest where++import FRequest+import DialogueIO hiding (IOError)++isRequest c =+ case c of+ DReq (Select _) -> False+ DReq _ -> True+ XReq _ -> True+ SReq _ -> True+ _ -> False++isResponse e =+ case e of+ XEvt _ -> False+ LEvt _ -> False+ _ -> True
+ hsrc/internals/MGOps.hs view
@@ -0,0 +1,101 @@+module MGOps where+import MeasuredGraphics(MeasuredGraphics(..))+import Maptrace(ctrace)+import Utils(anth)++{-+mgPart drawing path =+ case path of+ [] -> drawing+ p:ps -> part drawing+ where+ part drawing =+ case drawing of+ LeafM _ _ _ -> error "bad path in mgPart"+ SpacedM _ d -> part d+ PlacedM _ d -> part d+ ComposedM ds -> mgPart (ds !! ((p::Int)-1)) ps+-}++{- +replaceMGPart drawing path new =+ (if any (<1) path+ then ctrace "replaceMGPart" path+ else id) $ replaceMGPart' drawing path new+-}++replaceMGPart drawing path new = updateMGPart drawing path (const new)++-- Replacing a part without changing the structure+updateMGPart drawing path f =+ case path of+ [] -> f drawing+ p:ps -> repl drawing+ where+ err = error ("bad path in replaceMGPart: "++show path)+ repl0 d = if p==0+ then updateMGPart d ps f+ else err+ repl drawing =+ case drawing of+ LeafM _ _ -> err+ MarkM gctx d -> MarkM gctx (repl0 d)+ SpacedM spacer d -> SpacedM spacer (repl0 d)+ PlacedM placer d -> PlacedM placer (repl0 d)+ ComposedM ds -> ComposedM ds'+ where ds' = anth p (\d->updateMGPart d ps f) ds++-- Changing the structure but not the appearance+groupMGParts pos len drawing =+ case drawing of+ ComposedM ds -> ComposedM (ds1++ComposedM ds2:ds3)+ where+ (ds1,ds2a) = splitAt (pos-1) ds+ (ds2,ds3) = splitAt len ds2a+ _ -> drawing++-- Changing the structure but not the appearance+ungroupMGParts pos drawing =+ case drawing of+ ComposedM ds ->+ case splitAt (pos-1) ds of+ (ds1,ComposedM ds2:ds3) -> ComposedM (ds1++ds2++ds3)+ _ -> drawing+ _ -> drawing++parentGctx gctx mg path =+ case path of+ [] -> gctx+ 0:ps ->+ case mg of+ MarkM gctx' mg' -> parentGctx gctx' mg' ps+ SpacedM _ mg' -> parentGctx gctx mg' ps+ PlacedM _ mg' -> parentGctx gctx mg' ps+ _ -> ctrace "badpath" path gctx -- This is actually an error+ p:ps ->+ case mg of+ ComposedM mgs ->+ --{-+ if p>length mgs+ then ctrace "badpath" path gctx -- This is actually an error+ else --}+ parentGctx gctx (mgs!!(p-1)) ps+ _ -> ctrace "badpath" path gctx -- This is actually an error+{-+seqMG mg k =+ case mg of+ LeafM _ _ -> k+ SpacedM _ mg -> seqMG mg k+ PlacedM _ mg -> seqMG mg k+ MarkM _ mg -> seqMG mg k+ ComposedM mgs -> foldr seqMG k mgs+++sizeMG mg =+ case mg of+ LeafM _ _ -> 1::Int+ SpacedM _ mg -> 1+sizeMG mg+ PlacedM _ mg -> 1+sizeMG mg+ MarkM _ mg -> 1+sizeMG mg+ ComposedM mgs -> 1+sum (map sizeMG mgs)+-}
+ hsrc/internals/MeasuredGraphics.hs view
@@ -0,0 +1,123 @@+module MeasuredGraphics(DPath,up,MeasuredGraphics(..),compileMG,emptyMG,emptyMG',measureString,measureImageString,measurePackedString) where+import Geometry+import LayoutRequest+--import Placers2(overlayP)+import AutoPlacer(autoP)+import XDraw+import ResourceIds(GCId)+import Font+import TextExtents(queryTextExtents16K)+import Rects(boundingRect)+import CompiledGraphics+import GCtx(GCtx(..))+import GCAttrs(FontData(..))+import PackedString(unpackPS)+import Utils(lunconcat)+--import CmdLineEnv(argFlag)+import Debug.Trace(trace)++tr x y = y++type DPath = [Int] -- path to a part of a drawing++up :: DPath -> DPath+up [] = []+up path = init path++data MeasuredGraphics+-- = LeafM LayoutRequest GCtx (Rect->[DrawCommand])+ -- GCtx should be replaced by GCId !+ = LeafM LayoutRequest (Rect->[(GCId,[DrawCommand])])+ | SpacedM Spacer MeasuredGraphics+ | PlacedM Placer MeasuredGraphics+ | MarkM GCtx MeasuredGraphics -- path & Gctx preserving nodes+ | ComposedM [MeasuredGraphics]++emptyMG size = emptyMG' (plainLayout size False False)+emptyMG' layout = LeafM layout (const [])++compileMG f mg = (cg,req)+ where+ (reqs,cg) = tr "layoutMG" $ layoutMG mg places+ (req0,placer2) = unP autoP reqs+ req = mapLayoutSize f req0+ place = tr "Rect" $ Rect origin (minsize req)+ places = placer2 place++ layoutMG :: MeasuredGraphics -> [Rect] -> ([LayoutRequest],CompiledGraphics)+ layoutMG mg rs =+ case mg of+ MarkM _ mg' -> (lls,cgMark cg)+ where (lls,cg) = layoutMG mg' rs+ LeafM ll rcmds -> (tr "LeafM" [ll],cgLeaf r rcmds)+ where [r] = rs -- bug if length rs/=1 !!+ SpacedM (S spacer1) mg' -> (tr "SpaceM" lls',cgMark cg)+ where (lls,cg) = layoutMG mg' rs'+ (lls',spacer2s) = unzip (map spacer1 lls)+ rs' = map2' id spacer2s rs+ PlacedM (P placer1) mg -> (tr "PlacedM" [ll'],cgMark cg)+ where (lls,cg) = layoutMG mg rs'+ (ll',placer2) = placer1 lls+ rs' = placer2 r+ [r] = tr ("#rs="++show (length rs)) rs+ ComposedM [] -> (tr "ComposedM []" [],cgCompose (Rect origin origin) [])+ ComposedM mgs -> (tr "ComposedM" lls',cgCompose r cgs)+ where (llss,cgs) = unzip (map2' layoutMG mgs rss)+ lls' = concat llss+ r = case rs of+ [] -> trace ("ComposedM, rs=[], length mgs="++show (length mgs)) (rR 0 0 1 1)+ _ -> foldr1 boundingRect rs -- !!+ rss = lunconcat llss rs++measureString'' unpack draw s (GC gc fd) k =+ measure $ \ a d next size ->+ let p1 = Point 0 a+ p2 = Point next a+ drawit (Rect p (Point _ h)) = [(gc,[draw (p+(Point 0 (h-d))) s])]+ size' = Point (xcoord p2) (ycoord size) -- paragraphP bug workaround+ in --trace (unwords ["measureString ",unpack s,"rect",show r]) $+ k (LeafM (refpLayout size' True True [p1,p2]) drawit)+ where+ us = unpack s+ measure k =+ case fd of+ FS fs -> k a d next size+ where+ Rect _ size = string_rect fs us+ a = font_ascent fs+ d = font_descent fs+ next = next_pos fs us+ FID fs ->+ let fid = font_id fs+ in if null us+ then queryTextExtents16K fid " " $ \ a d cs ->+ k a d 0 (Point 0 (a+d))+ else queryTextExtents16K fid us $ \ a d cs ->+ k a d (char_width cs) (Point (char_rbearing cs) (a+d))++measureString' draw8 draw16 s gctx@(GC _ fd) k =+ measureString'' id draw s gctx k+ where+ draw =+ case fd of+ FS fs | snd (font_range fs) <= '\xff' -> draw8+ _ -> draw16++measureString s = measureString' DrawString DrawString16 s+measureImageString s = measureString' DrawImageString DrawImageString16 s++{- old:+measureString =+ if argFlag "string16bit" False+ then measureString' id DrawString16+ else measureString' id DrawString+-}++measurePackedString ps = measureString'' unpackPS DrawStringPS ps+++-- map2' is a lazier version of map2 (aka zipWith)+-- length (map2' f xs ys) = length xs,+-- map2' f xs ys = map2' f xs (ys++repeat undefined)+map2' f [] _ = []+map2' f (x:xs) ~(y:ys) = f x y:map2' f xs ys
+ hsrc/internals/PathTree.hs view
@@ -0,0 +1,182 @@+module PathTree+ (+ PathTree(..),DynTree(..),+ -- PathTree should be abstract...+ emptyPathTree,updateNode,mapPathTree,node,subTree,listNodes,+ attrMapPathTree,+ pruneTree,+ pos,unpos,spineVals+ ) where+import Direction+--import Path+import HbcUtils(apSnd)+import Maptrace(ctrace)++data PathTree n+ = Node n (PathTree n) (PathTree n)+ | Dynamic (DynTree (PathTree n))+ | Tip+ deriving (Eq, Ord, Show)++data DynTree n+ = DynNode n (DynTree n) (DynTree n)+ | DynTip + deriving (Eq, Ord, Show)++emptyPathTree = Tip+lookupPath f z = subTree (\(Node w _ _) -> f w) z+subNodes x = subTree (listNodes []) [] x++listNodes ns t =+ case t of+ Tip -> ns+ Node n l r -> listNodes (listNodes (n : ns) l) r+ Dynamic dt -> listDynNodes ns dt++listDynNodes ns dt =+ case dt of+ DynTip -> ns+ DynNode t l r -> listNodes (listDynNodes (listDynNodes ns r) l) t++subTree f z Tip _ = z+subTree f z (Dynamic dt) p = dynSelect (subTree f z) z dt p+subTree f z n [] = f n+subTree f z (Node _ l _) (L : path') = subTree f z l path'+subTree f z (Node _ _ r) (R : path') = subTree f z r path'+--subTree _ _ t p = error ("subTree _ _ "++show t++" "++show p)+-- Other cases of ill matching trees/paths return z, so why shouldn't this one?+subTree _ z t p = ctrace "subTree" ("subTree _ _ "++show t++" "++show p) z++{-+dynSubTree f z DynTip _ _ = z+dynSubTree f z (DynNode t _ _) 0 path' = subTree f z t path'+dynSubTree f z (DynNode _ l r) n path' =+ dynSubTree f z (if n `rem` 2 == 0 then l else r) (n `quot` 2) path'+-}+dynSelect f z dn (Dno n:p) = dynSelect' dn (pos n) where+ dynSelect' DynTip _ = z+ dynSelect' (DynNode t l r) n = if n == 0 then f t p else+ dynSelect' (if n `rem` 2 == 0 then l else r) (n `quot` 2)+dynSelect f z dn _ = z++pruneNode e = insertTree e Tip+insertTree n = updTree id n . const+pruneTree i e t path = updTree i e (const Tip) t path++updateNode i e t path f = updTree i e g t path+ where g Tip = Node (f e) Tip Tip+ g (Node n l r) = Node (f n) l r++updTree i e f t path' =+ case path' of+ [] -> f t+ L : path'' -> updLeft i e f t path''+ R : path'' -> updRight i e f t path''+ Dno n : path'' -> updateDyn i e f t (pos n) path''++updLeft i e f t path' =+ case t of+ Tip -> Node e (updTree i e f Tip path') Tip+ Node n l r -> Node (i n) (updTree i e f l path') r+ -- !!! space leak danger if i n is never used+ -- need stingy evaluation!!+ Dynamic _ -> error "PathTree.hs: updLeft (Dynamic _)"++updRight i e f t path' =+ case t of+ Tip -> Node e Tip (updTree i e f Tip path')+ Node n l r -> Node (i n) l (updTree i e f r path')+ -- !!! space leak danger if i n is never used+ -- need stingy evaluation!!+ Dynamic _ -> error "PathTree.hs: updRight (Dynamic _)"++updateDyn i e f t n path' =+ case t of+ Tip -> Dynamic (updateDyn' i e f DynTip n path')+ Node _ _ _ -> Dynamic (updateDyn' i e f DynTip n path') -- throwing away part of the tree !!!+ Dynamic t' -> Dynamic (updateDyn' i e f t' n path')++updateDyn' i e f DynTip 0 path' =+ DynNode (updTree i e f Tip path') DynTip DynTip+updateDyn' i e f (DynNode t l r) 0 path' = DynNode (updTree i e f t path') l r+updateDyn' i e f t n path' =+ (if n `rem` 2 == 0 then updDynLeft else updDynRight) i e f+ t+ (n `quot` 2)+ path'++updDynLeft i e f t n path' =+ case t of+ DynTip -> DynNode Tip (updateDyn' i e f DynTip n path') DynTip+ DynNode t' l r -> DynNode t' (updateDyn' i e f l n path') r++updDynRight i e f t n path' =+ case t of+ DynTip -> DynNode Tip DynTip (updateDyn' i e f DynTip n path')+ DynNode t' l r -> DynNode t' l (updateDyn' i e f r n path')++pos :: Int->Int+pos 0 = 0+pos n = if n < 0 then (-2) * n else 2 * n + 1++unpos :: Int->Int+unpos n =+ if even n+ then -(n `quot` 2)+ else n `quot` 2++mapPathTree f t =+ case t of+ Node n lt rt -> Node (f n) (mapPathTree f lt) (mapPathTree f rt)+ Dynamic dt -> Dynamic (mapDyn (mapPathTree f) dt)+ Tip -> Tip++mapDyn f dt =+ case dt of+ DynNode n lt rt -> DynNode (f n) (mapDyn f lt) (mapDyn f rt)+ DynTip -> DynTip++attrMapPathTree :: (i -> [s] -> a -> (i,s,b)) -> i -> PathTree a -> + ([s],PathTree b)+attrMapPathTree f i t = case t of+ Node n lt rt -> ([s],Node n' lt' rt') where+ (sl,lt') = attrMapPathTree f i' lt+ (sr,rt') = attrMapPathTree f i' rt+ (i',s,n') = f i (sl++sr) n+ -- should perhaps extract ++ and []+ Tip -> ([],Tip)+ Dynamic dt -> apSnd Dynamic (attrMapDyn f i dt)++attrMapDyn f i dt = case dt of+ DynTip -> ([],DynTip)+ DynNode t lt rt -> (s++sl++sr,DynNode t' lt' rt') where+ -- order?+ (sl,lt') = attrMapDyn f i lt+ (sr,rt') = attrMapDyn f i rt+ (s,t') = attrMapPathTree f i t++spineVals t p = case t of+ Tip -> []+ Node v l r -> v : case p of+ L:p' -> spineVals l p'+ R:p' -> spineVals r p'+ _ -> []+ Dynamic dt -> dynSelect spineVals [] dt p++node t =+ case t of+ Node i lt rt -> (Just i,children lt (children rt []))+ Tip -> (Nothing,[])+ Dynamic dt -> (Nothing,dynChildren dt [])++children t ts =+ case t of+ Tip -> ts+ Node _ _ _ -> t:ts+ Dynamic dt -> dynChildren dt ts++dynChildren dt ts =+ case dt of+ DynTip -> ts+ DynNode t lt rt -> (children t . dynChildren lt . dynChildren rt) ts+ -- !! order??
+ hsrc/internals/Queue.hs view
@@ -0,0 +1,17 @@+module Queue(QUEUE, qmember, isempty, qremove, enter, empty) where++data QUEUE a = Queue [a] [a] deriving (Eq, Ord)++empty = Queue [] []++enter (Queue outl' inl) x = Queue outl' (x : inl)++isempty (Queue [] []) = True+isempty _ = False++qremove (Queue (a : outl') inl) = Just (a, Queue outl' inl)+qremove (Queue [] []) = Nothing --error "qremove from empty queue"+qremove (Queue [] inl) = qremove (Queue (reverse inl) [])++qmember (Queue outl' inl) x = x `elem` outl' || x `elem` inl+
+ hsrc/internals/StringEdit.hs view
@@ -0,0 +1,51 @@+module StringEdit(+ moveCursorHome,moveCursorEnd,extendCursorHome,extendCursorEnd,+ moveCursorRight, moveCursorLeft, extendCursorLeft,extendCursorRight,+ deleteItemRight, deleteItemLeft, deleteToEnd, deleteToHome,+ insertItem, insertItemsSelected, showField, getField,+ createField2, createField, Field) where++data Field a = F [a] [a] [a] deriving (Eq, Ord)++createField s = F [] s []++createField2 (before, after) = F (reverse before) [] after++getField (F l c r) = reverse l ++ c ++ r++showField show' show_cursor (F l c r) =+ show' r . show_cursor c . show' (reverse l)++insertItem (F l c r) i = F (i : l) [] r+insertItemsSelected (F l c r) i = F l i r++deleteItemLeft f@(F [] [] _) = f+deleteItemLeft (F (i : l) [] r) = F l [] r+deleteItemLeft (F l c r) = F l [] r++deleteItemRight f@(F _ [] []) = f+deleteItemRight (F l [] (i : r)) = F l [] r+deleteItemRight (F l c r) = F l [] r++deleteToEnd (F l c r) = F l [] []+deleteToHome (F l c r) = F [] [] r++extendCursorRight (F l c (i : r)) = F l (c ++ [i]) r+extendCursorRight f@(F _ _ []) = f++extendCursorLeft (F (i : l) c r) = F l (i : c) r+extendCursorLeft f@(F [] _ _) = f++moveCursorLeft f@(F [] [] _) = f+moveCursorLeft (F (i : l) [] r) = F l [] (i : r)+moveCursorLeft (F l c r) = F l [] (c ++ r)++moveCursorRight f@(F _ [] []) = f+moveCursorRight (F l [] (i : r)) = F (i : l) [] r+moveCursorRight (F l c r) = F (reverse c ++ l) [] r++moveCursorHome f = F [] [] (getField f)+moveCursorEnd f = F (reverse (getField f)) [] []++extendCursorHome (F l c r) = F [] (reverse l++c) r+extendCursorEnd (F l c r) = F l (c++r) []
+ hsrc/internals/Table.hs view
@@ -0,0 +1,23 @@+module Table(table, mapTable, listTable, tableUpdate, tableLookup, emptyTable,+ Table) where+import Tree234++newtype Table a = T (Tree234 a) deriving (Eq, Ord,Show)++emptyTable = T initTree234++tableLookup n j x (T t) = treeSearch n j (keyCmp x) t++tableUpdate x (T t) = T (update' x t)++update' x = treeAdd const keyCmp x++mapTable f (T t) = T (treeMap f t)++listTable (T t) = treeList t++table xs = T (treeFromList const keyCmp xs)++keyCmp (a, _) (b, _) lt eq gt =+ if a == b then eq else if a < b then lt else gt+
+ hsrc/internals/Tables.hs view
@@ -0,0 +1,99 @@+module Tables(PathTable(..), WidTable(..), updatePath, lookupPath, wid2path0,+ pruneWid, updateWid, subWids, lookupWid, path2wid0, PathTree,+ moveWids,movePaths, prunePath) where+import Direction+--import Fudget+import Path+import Table+import PathTree+import Utils(oo)+import Xtypes++-- Most functions here should be imported from PathTree instead !!!++type WidTable = PathTree WindowId++path2wid0 = Tip++lookupWid = subTree (\(Node w _ _) -> w) noWindow++moveWids path2wid opath npath = insertTree st pt npath where+ st = subTree id Tip path2wid opath + pt = pruneWid path2wid opath++subWids = oo (filter (/= noWindow)) (subTree (listWids []) [])++listWids = listNodes++updateWid t path' wid = insertTree (Node wid Tip Tip) t path'++pruneWid t path' = insertTree Tip t path'++insertTree = updTree . const+updTree f t path' =+ case path' of+ [] -> f t+ L : path'' -> updLeft f t path''+ R : path'' -> updRight f t path''+ Dno n : path'' -> updateDyn f t (pos n) path''++updLeft f t path' =+ case t of+ Tip -> Node nowid (updTree f Tip path') Tip+ Node w l r -> Node w (updTree f l path') r+ Dynamic _ -> error "tables.m: updLeft (Dynamic _)"++updRight f t path' =+ case t of+ Tip -> Node nowid Tip (updTree f Tip path')+ Node w l r -> Node w l (updTree f r path')+ Dynamic _ -> error "tables.m: updRight (Dynamic _)"++updateDyn f t n path' =+ case t of+ Tip -> Dynamic (updateDyn' f DynTip n path')+ Dynamic t' -> Dynamic (updateDyn' f t' n path')++updateDyn' f DynTip 0 path' =+ DynNode (updTree f Tip path') DynTip DynTip+updateDyn' f (DynNode t l r) 0 path' = DynNode (updTree f t path') l r+updateDyn' f t n path' =+ (if n `rem` 2 == 0 then updDynLeft else updDynRight) f+ t+ (n `quot` 2)+ path'++updDynLeft f t n path' =+ case t of+ DynTip -> DynNode Tip (updateDyn' f DynTip n path') DynTip+ DynNode t' l r -> DynNode t' (updateDyn' f l n path') r++updDynRight f t n path' =+ case t of+ DynTip -> DynNode Tip DynTip (updateDyn' f DynTip n path')+ DynNode t' l r -> DynNode t' l (updateDyn' f r n path')++nowid = noWindow++-------+type PathTable = Table (WindowId, Path)++nopath = here -- error "window not associated with a path"++wid2path0 = emptyTable++-- This part should be replaced with something more efficient!!+lookupPath wid2path wid =+ tableLookup nopath snd (wid, nopath) wid2path++-- normal code+updatePath wid2path wid path' = tableUpdate (wid, path') wid2path++movePaths wid2path opath npath = mapTable move wid2path where+ move (wid,path) = (wid,repath opath path) where+ repath [] rest = absPath npath rest+ repath (x:xs) (y:ys) | x == y = repath xs ys+ repath _ _ = path++-- should be implemented in Tree234+prunePath wid2path w = table $ filter ((/=w).fst) $ listTable wid2path
+ hsrc/internals/Tables2.hs view
@@ -0,0 +1,24 @@+module Tables2(DTable(..), dtable0, lookupDe, listDe, updateDe) where+import Utils(pair)+import Direction() -- instances+import Path(here,Path(..))+import Sockets(Descriptor)+import Table++type DTable = Table (Descriptor, Path)++updateDe :: Path -> [Descriptor] -> DTable -> DTable+updateDe path' ds dtable =+ table (map (`pair` path') ds +++ filter ((/= path') . snd) (listTable dtable))++listDe :: DTable -> [Descriptor]+listDe dtable = map fst (listTable dtable)++lookupDe :: DTable -> Descriptor -> Path+lookupDe dtable de =+ tableLookup (error ("Descriptor without path: "++show de)) snd (de, here) dtable++dtable0 :: DTable+dtable0 = table []+
+ hsrc/internals/Tree234.hs view
@@ -0,0 +1,239 @@+module Tree234(treeMap, treeCombine, treeRebuild, treeFromList, treeMapList,+ treeList, treeUpdate, treeSearch, treeAdd, initTree234, Tree234) where++data Tree234 a = Leaf |+ Leaf2 a |+ Leaf3 a a |+ Leaf4 a a a |+ Node2 a (Tree234 a) (Tree234 a) |+ Node3 a a (Tree234 a) (Tree234 a) (Tree234 a) |+ Node4 a a a (Tree234 a) (Tree234 a) (Tree234 a) (Tree234 a) + deriving (Eq, Ord,Show)++initTree234 = Leaf++treeAdd comb cmp a t = treeAdd' comb cmp a id Node2 t++treeSearch fail cont p Leaf = fail+treeSearch fail cont p (Leaf2 a1) = p a1 fail (cont a1) fail+treeSearch fail cont p (Leaf3 a1 a2) =+ p a1 fail (cont a1) (p a2 fail (cont a2) fail)+treeSearch fail cont p (Leaf4 a1 a2 a3) =+ p a2 (p a1 fail (cont a1) fail) (cont a2) (p a3 fail (cont a3) fail)+treeSearch fail cont p (Node2 a1 t1 t2) =+ p a1 (treeSearch fail cont p t1) (cont a1) (treeSearch fail cont p t2)+treeSearch fail cont p (Node3 a1 a2 t1 t2 t3) =+ p a1+ (treeSearch fail cont p t1)+ (cont a1)+ (p a2+ (treeSearch fail cont p t2)+ (cont a2)+ (treeSearch fail cont p t3))+treeSearch fail cont p (Node4 a1 a2 a3 t1 t2 t3 t4) =+ p a2+ (p a1+ (treeSearch fail cont p t1)+ (cont a1)+ (treeSearch fail cont p t2))+ (cont a2)+ (p a3+ (treeSearch fail cont p t3)+ (cont a3)+ (treeSearch fail cont p t4))++treeUpdateFailed = error "treeUpdate couldn't find the node"++treeUpdate update p Leaf = Leaf+treeUpdate update p (Leaf2 a1) =+ p a1 treeUpdateFailed (Leaf2 (update a1)) treeUpdateFailed+treeUpdate update p (Leaf3 a1 a2) =+ p a1+ treeUpdateFailed+ (Leaf3 (update a1) a2)+ (p a2 treeUpdateFailed (Leaf3 a1 (update a2)) treeUpdateFailed)+treeUpdate update p (Leaf4 a1 a2 a3) =+ p a2+ (p a1 treeUpdateFailed (Leaf4 (update a1) a2 a3) treeUpdateFailed)+ (Leaf4 a1 (update a2) a3)+ (p a3 treeUpdateFailed (Leaf4 a1 a2 (update a3)) treeUpdateFailed)+treeUpdate update p (Node2 a1 t1 t2) =+ p a1+ (Node2 a1 (treeUpdate update p t1) t2)+ (Node2 (update a1) t1 t2)+ (Node2 a1 t1 (treeUpdate update p t2))+treeUpdate update p (Node3 a1 a2 t1 t2 t3) =+ p a1+ (Node3 a1 a2 (treeUpdate update p t1) t2 t3)+ (Node3 (update a1) a2 t1 t2 t3)+ (p a2+ (Node3 a1 a2 t1 (treeUpdate update p t2) t3)+ (Node3 a1 (update a2) t1 t2 t3)+ (Node3 a1 a2 t1 t2 (treeUpdate update p t3)))+treeUpdate update p (Node4 a1 a2 a3 t1 t2 t3 t4) =+ p a2+ (p a1+ (Node4 a1 a2 a3 (treeUpdate update p t1) t2 t3 t4)+ (Node4 (update a1) a2 a3 t1 t2 t3 t4)+ (Node4 a1 a2 a3 t1 (treeUpdate update p t2) t3 t4))+ (Node4 a1 (update a2) a3 t1 t2 t3 t4)+ (p a3+ (Node4 a1 a2 a3 t1 t2 (treeUpdate update p t3) t4)+ (Node4 a1 a2 (update a3) t1 t2 t3 t4)+ (Node4 a1 a2 a3 t1 t2 t3 (treeUpdate update p t4)))++treeMapList f Leaf = []+treeMapList f (Leaf2 a1) = f a1+treeMapList f (Leaf3 a1 a2) = f a1 ++ f a2+treeMapList f (Leaf4 a1 a2 a3) = f a1 ++ f a2 ++ f a3+treeMapList f (Node2 a1 t1 t2) =+ treeMapList f t1 ++ f a1 ++ treeMapList f t2+treeMapList f (Node3 a1 a2 t1 t2 t3) =+ treeMapList f t1 +++ f a1 ++ treeMapList f t2 ++ f a2 ++ treeMapList f t3+treeMapList f (Node4 a1 a2 a3 t1 t2 t3 t4) =+ treeMapList f t1 +++ f a1 +++ treeMapList f t2 +++ f a2 ++ treeMapList f t3 ++ f a3 ++ treeMapList f t4++treeMap f Leaf = Leaf+treeMap f (Leaf2 a1) = Leaf2 (f a1)+treeMap f (Leaf3 a1 a2) = Leaf3 (f a1) (f a2)+treeMap f (Leaf4 a1 a2 a3) = Leaf4 (f a1) (f a2) (f a3)+treeMap f (Node2 a1 t1 t2) =+ Node2 (f a1) (treeMap f t1) (treeMap f t2)+treeMap f (Node3 a1 a2 t1 t2 t3) =+ Node3 (f a1) (f a2) (treeMap f t1) (treeMap f t2) (treeMap f t3)+treeMap f (Node4 a1 a2 a3 t1 t2 t3 t4) =+ Node4 (f a1)+ (f a2)+ (f a3)+ (treeMap f t1)+ (treeMap f t2)+ (treeMap f t3)+ (treeMap f t4)++treeFromList comb cmp l = treeAddList comb cmp l Leaf++treeAddList comb cmp [] t = t+treeAddList comb cmp (x : xs) t =+ treeAddList comb cmp xs (treeAdd comb cmp x t)++treeRebuild comb cmp t = treeFromList comb cmp (treeMapList (: []) t)++treeCombine comb cmp t1 t2 =+ treeAddList comb cmp (treeMapList (: []) t2) t1++treeAdd' comb cmp a keep split Leaf = keep (Leaf2 a)+treeAdd' comb cmp a keep split (Leaf2 a1) =+ keep (cmp a a1 (Leaf3 a a1) (Leaf2 (comb a a1)) (Leaf3 a1 a))+treeAdd' comb cmp a keep split (Leaf3 a1 a2) =+ keep (cmp a+ a1+ (Leaf4 a a1 a2)+ (Leaf3 (comb a a1) a2)+ (cmp a a2 (Leaf4 a1 a a2) (Leaf3 a1 (comb a a2)) (Leaf4 a1 a2 a)))+treeAdd' comb cmp a keep split (Leaf4 a1 a2 a3) =+ cmp a+ a2+ (cmp a+ a1+ (split a2 (Leaf3 a a1) (Leaf2 a3))+ (keep (Leaf4 (comb a a1) a2 a3))+ (split a2 (Leaf3 a1 a) (Leaf2 a3)))+ (keep (Leaf4 a1 (comb a a2) a3))+ (cmp a+ a3+ (split a2 (Leaf2 a1) (Leaf3 a a3))+ (keep (Leaf4 a1 a2 (comb a a3)))+ (split a2 (Leaf2 a1) (Leaf3 a3 a)))+treeAdd' comb cmp a keep split (Node2 a1 t1 t2) =+ keep (cmp a+ a1+ (treeAdd' comb+ cmp+ a+ (\t1' -> Node2 a1 t1' t2)+ (\a0' -> \t0' -> \t1' -> Node3 a0' a1 t0' t1' t2)+ t1)+ (Node2 (comb a a1) t1 t2)+ (treeAdd' comb+ cmp+ a+ (\t2' -> Node2 a1 t1 t2')+ (\a2' -> \t2' -> \t3' -> Node3 a1 a2' t1 t2' t3')+ t2))+treeAdd' comb cmp a keep split (Node3 a1 a2 t1 t2 t3) =+ keep (cmp a+ a1+ (treeAdd' comb+ cmp+ a+ (\t1' -> Node3 a1 a2 t1' t2 t3)+ (\a0' -> \t0' -> \t1' -> Node4 a0' a1 a2 t0' t1' t2 t3)+ t1)+ (Node3 (comb a a1) a2 t1 t2 t3)+ (cmp a+ a2+ (treeAdd' comb+ cmp+ a+ (\t2' -> Node3 a1 a2 t1 t2' t3)+ (\a1_5' ->+ \t1_5' ->+ \t2' -> Node4 a1 a1_5' a2 t1 t1_5' t2' t3)+ t2)+ (Node3 a1 (comb a a2) t1 t2 t3)+ (treeAdd' comb+ cmp+ a+ (\t3' -> Node3 a1 a2 t1 t2 t3')+ (\a3' ->+ \t3' -> \t4' -> Node4 a1 a2 a3' t1 t2 t3' t4')+ t3)))+treeAdd' comb cmp a keep split (Node4 a1 a2 a3 t1 t2 t3 t4) =+ cmp a+ a2+ (cmp a+ a1+ (split a2+ (treeAdd' comb+ cmp+ a+ (\t1' -> Node2 a1 t1' t2)+ (\a0' -> \t0' -> \t1' -> Node3 a0' a1 t0' t1' t2)+ t1)+ (Node2 a3 t3 t4))+ (keep (Node4 (comb a a1) a2 a3 t1 t2 t3 t4))+ (split a2+ (treeAdd' comb+ cmp+ a+ (\t2' -> Node2 a1 t1 t2')+ (\a2' -> \t2' -> \t3' -> Node3 a1 a2' t1 t2' t3')+ t2)+ (Node2 a3 t3 t4)))+ (keep (Node4 a1 (comb a a2) a3 t1 t2 t3 t4))+ (cmp a+ a3+ (split a2+ (Node2 a1 t1 t2)+ (treeAdd' comb+ cmp+ a+ (\t3' -> Node2 a3 t3' t4)+ (\a2' -> \t2' -> \t3' -> Node3 a2' a3 t2' t3' t4)+ t3))+ (keep (Node4 a1 a2 (comb a a3) t1 t2 t3 t4))+ (split a2+ (Node2 a1 t1 t2)+ (treeAdd' comb+ cmp+ a+ (\t4' -> Node2 a3 t3 t4')+ (\a4' -> \t4' -> \t5' -> Node3 a3 a4' t3 t4' t5')+ t4)))++treeList t = treeMapList (: []) t+
+ hsrc/internals/UndoStack.hs view
@@ -0,0 +1,27 @@+module UndoStack(UndoStack,undoStack,doit,undo,redo) where+--import EitherUtils(mapMaybe)++data UndoStack a = U (Maybe Int) [a] [a] [a]+-- depth limit undos temp-undos temp-redos+undoStack:: Maybe Int -> UndoStack a+undoStack on = U (fmap (\n -> max 0 n + 1) on) [] [] []++otake on l = case on of+ Nothing -> l+ Just n -> take n l++doit :: UndoStack a -> a -> (UndoStack a -> c) -> c+doit (U on u tu tr) a c = seq (length u') $ c (U on u' (tail u') [])+ where u' = otake on (a:take 1 tr++u)++undo :: UndoStack a -> Maybe (a,UndoStack a)+undo (U on u tu tr) = case tu of+ a:tu' -> Just (a,U on u tu' (a:tr))+ [] -> Nothing++redo :: UndoStack a -> Maybe (a,UndoStack a)+redo (U on u tu tr) = + case tr of+ a:b:tr' -> Just (b,U on u (a:tu) (b:tr'))+ [a] -> Just (head u,U on u (a:tu) [])+ [] -> Nothing
+ hsrc/io/AppStorage.hs view
@@ -0,0 +1,20 @@+module AppStorage where+import System.Directory(XdgDirectory(..))+import ReadFileF+import WriteFile+import HbcUtils(apSnd)+import CompOps+import NullF+import Spops++appStorageF :: (Read a,Show a) => String -> a -> F a a+appStorageF key d =+ either (const d) (maybe d id . readM) . snd+ >^=< startupF [key] (readXdgFileF XdgData)+ >=^^< nullSP+ >==< writeXdgFileF XdgData+ >=^< (,) key . show++readM x = case reads x of+ [(x,s)] | lex s == [("","")] -> Just x+ _ -> Nothing
+ hsrc/io/AsyncTransmitter.hs view
@@ -0,0 +1,117 @@+{-# LANGUAGE CPP #-}+module AsyncTransmitter(asyncTransmitterF,asyncTransmitterF',closerF) where+import Sockets+import Srequest+import FRequest+import Message(message)+import NullF(getK,nullK,nullF)+import Fudget()+import FudgetIO+import CompOps((>==<))+import IoF(ioF)+import DialogueIO hiding (IOError)+import qualified PackedString as PS+import Queue(QUEUE,empty,enter,qremove)++{- asyncTransmitterF has two states:++ - Idle state: we have nothing to send and don't want to be notified when+ the socket becomes writable.++ - Blocked state: we have something to send and want to be notified when+ the socket becomes writable.++ idleK handles the idle state. Transistion to the idleState is done+ with goIdleK. idleK should only be called when in the idle state.++ blockedK handles the blocked state. Transition to the blocked state is done+ with goBlockedK. blockedK should only be called when in the blocked state.++ writeK is called in blocked mode when the socket become writable. If there+ is something left in the buffer to write, writeK writes a chunk to the+ socket and continues in blocked mode, otherwise writeK switches to+ idle mode.+-}++asyncTransmitterF socket = closerF socket >==< asyncTransmitterF' socket++asyncTransmitterF' socket =+ -- Start in idle mode+ ioF idleK+ where+ -- To be called while in idle mode only:+ idleK = getMsg (const idleK) high+ where+ high "" = closeK+ high str = goBlockedK (buf1 str)++ -- To swich from blocked to idle mode:+ goIdleK = select [] $ idleK++ -- To switch from idle mode to blocked mode:+ goBlockedK buf =+ select [OutputSocketDe socket] $+ blockedK buf initblocksize++ -- To be called while in blocked mode only:+ blockedK buf n = getMsg low high+ where+ low (DResp (AsyncInput (_,SocketWritable))) = writeK buf n+ high str = blockedK (putbuf buf str) n++ -- To be called while in blocked mode, when socket becomes writable:+ writeK buf n =+ case getbuf buf n of+ Empty -> goIdleK+ EoS -> closeK+ More ps buf' -> sIOerr (WriteSocketPS socket ps) errK okK+ where+ okK (Wrote n') = blockedK buf' n+ errK _ = blockedK buf' n -- Ignore errors?!++ closeK =+ select [] $+ --sIOsucc (CloseSocket socket) $+ -- Can't close the socket until the receiver (if any) has deselected it!+ putHigh () $+ nullK++closerF socket =+ getHigh $ \ _ ->+ sIOsucc (CloseSocket socket) $+ nullF++getMsg l h = getK $ message l h++data Buffer = Buf String (QUEUE String)+data GetBuf = More PS.PackedString Buffer | Empty | EoS++--buf0 = Buf "" empty+buf1 str = Buf str empty -- pre: str/=""++putbuf (Buf s q) str = Buf s (enter q str) -- str=="" to indicate eos++getbuf (Buf s q) n = getbuf' s q+ where+ getbuf' "" q =+ case qremove q of+ Nothing -> Empty+ Just (s,q') ->+ if null s+ then EoS+ else getbuf'' s q'++ getbuf' s q = getbuf'' s q++ getbuf'' s q =+ case splitAt n s of+ (s1,s2) -> More (PS.packString s1) (Buf s2 q)+++initblocksize = 512 :: Int++#if defined(__GLASGOW_HASKELL__) || defined(__PFE__)+nullPS = PS.nullPS+#else+nullPS = PS.null+#endif
+ hsrc/io/HaskellIO.hs view
@@ -0,0 +1,63 @@+module HaskellIO{-(hIOSucc, hIOSuccK, hIOSuccF,+ hIO, hIOK, hIOF,+ hIOerr, hIOerrK, hIOerrF,+ haskellIO, haskellIOK, haskellIOF)-} where+import Prelude hiding (IOError)+--import Command+--import Cont(cmdContF)+import FudgetIO+import NullF(F)+import FRequest+--import Event+--import Fudget+--import Message(Message(..))+import ShowFailure+--import Sockets+--import Xtypes+import DialogueIO++hIOSucc req = hIO req . const++hIOerr req fcont scont =+ haskellIO req $ \ resp ->+ case resp of+ Failure f -> fcont f+ _ -> scont resp++haskellIO request = cmdContLow (DReq request) expected+ where+ expected (DResp response) = Just response+-- expected (SResp sresp) = Just (SocketResponse sresp) -- for backward compat+ expected _ = Nothing++hIO req = hIOerr req (\e -> error ("IOError: " ++ showFailure e))++------++haskellIOF :: Request -> (Response -> F a b) -> F a b+haskellIOF = haskellIO++hIOerrF :: Request -> (IOError -> F a b) -> (Response -> F a b) -> F a b+hIOerrF = hIOerr++hIOF :: Request -> (Response -> F a b) -> F a b+hIOF = hIO++hIOSuccF :: Request -> (F a b) -> F a b+hIOSuccF = hIOSucc++{---++haskellIOK :: Request -> (Response -> K a b) -> K a b+haskellIOK = haskellIO++hIOerrK :: Request -> (IOError -> K a b) -> (Response -> K a b) -> K a b+hIOerrK = hIOerr++hIOK :: Request -> (Response -> K a b) -> K a b+hIOK = hIO++hIOSuccK :: Request -> (K a b) -> K a b+hIOSuccK = hIOSucc++---}
+ hsrc/io/InOut.hs view
@@ -0,0 +1,17 @@+module InOut (-- * IO+ module HaskellIO,module StdIoUtil,module IoF,module Socketio,module OpenSocket,module Transceivers,module AsyncTransmitter,module TimerF,module ReadFileF,module WriteFile,module AppStorage,module Process,module UnsafeGetDLValue,module GetTime,module GetModificationTime) where+import HaskellIO+import StdIoUtil+import IoF+import Socketio+import OpenSocket+import Transceivers+import AsyncTransmitter+import TimerF+import ReadFileF+import WriteFile+import AppStorage+import Process+import UnsafeGetDLValue+import GetTime -- compiler dependent!+import GetModificationTime -- compiler dependent!
+ hsrc/io/IoF.hs view
@@ -0,0 +1,14 @@+module IoF(ioF) where+--import Command(Command(..), XCommand)+--import Direction+--import Event(Event(..))+--import Fudget+--import Geometry(Line(..), Point(..), Rect(..), Size(..))+--import Message(Message)+--import Path(Path(..))+--import SP+import WindowF(kernelF)+--import Xtypes(WindowAttributes)++ioF = kernelF+
+ hsrc/io/OpenSocket.hs view
@@ -0,0 +1,28 @@+module OpenSocket(+ openSocketF,openSocketErrF,+ openLSocketF,openLSocketErrF,+ openFileAsSocketF,openFileAsSocketErrF+ ) where+import Srequest+import Sockets++-- All eta expanstion are due to the monomorphism restriction++openSocketF h = openSocketF' sIO h+openLSocketF p = openLSocketF' sIO p+openFileAsSocketF h = openFileAsSocketF' sIO h++openSocketErrF h p e = openSocketF' (sIOerr' e) h p+openLSocketErrF p e = openLSocketF' (sIOerr' e) p+openFileAsSocketErrF n m e = openFileAsSocketF' (sIOerr' e) n m++openSocketF' sio host port cont =+ sio (OpenSocket host port) $ \ (Socket socket) -> cont socket++openLSocketF' sio port cont =+ sio (OpenLSocket port) $ \(LSocket lsocket) -> cont lsocket++openFileAsSocketF' sio name mode cont =+ sio (OpenFileAsSocket name mode) $ \ (Socket socket) -> cont socket++sIOerr' e r = sIOerr r e
+ hsrc/io/Process.hs view
@@ -0,0 +1,15 @@+module Process where+--import Fudget+--import Xtypes+import Srequest+import NullF()+--import FudgetIO+import Sockets+import Transceivers+import CompOps+--import DialogueIO hiding (IOError)++subProcessF cmd =+ sIO (StartProcess cmd True True True) $+ \ (ProcessSockets (Just sin) (Just sout) (Just serr)) ->+ (receiverF sout>+<receiverF serr)>==<transmitterF sin
+ hsrc/io/ReadFileF.hs view
@@ -0,0 +1,40 @@+module ReadFileF(readFileF,readBinaryFileF,readXdgFileF,readDirF) where+import Fudget() -- synonym KEvent, for hbc+import NullF+import FudgetIO+import IoF(ioF)+import HaskellIO(haskellIO)+import Message(Message(..))+import DialogueIO hiding (IOError)++readFileF = ioF readFileK+readBinaryFileF = ioF readBinaryFileK+readXdgFileF = ioF . readXdgFileK++readFileK = readFileK' ReadFile+readBinaryFileK = readFileK' ReadBinaryFile+readXdgFileK = readFileK' . ReadXdgFile++readFileK' req =+ getK $ \ msg ->+ case msg of+ High filename ->+ haskellIO (req filename) $ \ resp ->+ putHigh (filename,case resp of+ Str s -> Right s+ Failure err -> Left err)+ readFileK+ _ -> readFileK++readDirF = ioF readDirK++readDirK =+ getK $ \ msg ->+ case msg of+ High dirname ->+ haskellIO (ReadDirectory dirname) $ \ resp ->+ putHigh (dirname,case resp of+ StrList filenames -> Right filenames+ Failure err -> Left err)+ readDirK+ _ -> readDirK
+ hsrc/io/Socketio.hs view
@@ -0,0 +1,34 @@+module Socketio where+import Fudget+import FudgetIO+import FRequest+import Srequest+--import Message(Message(..))+import NullF+import Sockets+import Utils(loop)+--import Xtypes+import DialogueIO hiding (IOError)++transmitterF' s =+ loop $ \l -> getF $ \str ->+ if null str+ then putHigh () nullF+ else sIOsucc (WriteSocket s str) l++receiverF' s =+ select [SocketDe s] $+ loop $ \l ->+ getMessageFu $ \e ->+ case e of+ Low (DResp (AsyncInput (_, SocketRead str))) ->+ if null str+ then closeDown+ else putF str l+ High _ -> closeDown+ where+ closeDown =+ select [] $+ putHigh "" $+ sIOsucc (CloseSocket s) $+ nullF
+ hsrc/io/StdIoUtil.hs view
@@ -0,0 +1,60 @@+module StdIoUtil(linesSP, inputLinesSP, echoK, echoStderrK,+ appendChanK, appendStdoutK, appendStderrK,+ outputF, stdioF, stderrF, stdoutF, stdinF) where+--import Command+import CompOps((>==<))+import CompSP(serCompSP)+--import Event+import HaskellIO(hIOSucc)+import Srequest+import IoF+import Message(message)+import Transceivers(receiverF)+import Sockets+import Spops+--import Xtypes+import Fudget+--import FudgetIO+import NullF(getK{-,F,K-})+import ContinuationIO(stdout,stderr)+import DialogueIO hiding (IOError)++stdoutF = outputF stdout+stderrF = outputF stderr+stdioF = stdinF >==< stdoutF++outputF :: String -> F String a+outputF = ioF . outputK++stdinF = sIO GetStdinSocket $ \ (Socket s) -> receiverF s++{-+outputK chan =+ let f msg =+ case msg of+ High s -> [Low (DoIO (AppendChan chan s))]+ _ -> []+ in concmapSP f+-}++outputK chan =+ getK $ message (const $ outputK chan) $ \ s ->+ appendChanK chan s $+ outputK chan++appendChanK chan s = hIOSucc (AppendChan chan s)++appendStdoutK s = appendChanK stdout s+appendStderrK s = appendChanK stderr s+echoK s = appendStdoutK (s ++ "\n")+echoStderrK s = appendStderrK (s ++ "\n")++linesSP = lnSP []+ where+ lnSP acc =+ getSP $ \msg ->+ case msg of+ '\n' -> putSP (reverse acc) (lnSP [])+ c -> lnSP (c : acc)++inputLinesSP = linesSP `serCompSP` concatSP -- inefficient!!!
+ hsrc/io/TimerF.hs view
@@ -0,0 +1,37 @@+module TimerF(timerF,Tick(..)) where+import Fudget+import FudgetIO+import FRequest+import Srequest(sIO,sIOsucc,select)+--import Message(Message(..))+import NullF+import Sockets+--import Xtypes+import DialogueIO hiding (IOError)++data Tick = Tick deriving (Show,Eq)++--timerF :: F (Maybe (Int,Int)) Tick+timerF = f Nothing+ where+ f oTno =+ getMessageFu $ \ msg ->+ let same = f oTno+ settimer int first = case oTno of+ Just _ -> same+ Nothing ->+ sIO (CreateTimer int first) $ \ (Timer tno) ->+ -- error handling?!+ select [TimerDe tno] $+ f (Just tno)+ removetimer = case oTno of+ Just tno -> sIOsucc (DestroyTimer tno) $+ select [] $+ f Nothing+ Nothing -> same+ in case msg of+ High (Just (interval, first)) -> settimer interval first+ High Nothing -> removetimer+ Low (DResp (AsyncInput (_, TimerAlarm))) ->+ putHigh Tick $+ same
+ hsrc/io/Transceivers.hs view
@@ -0,0 +1,13 @@+module Transceivers where+import Socketio+import AsyncTransmitter+import CompOps((>==<),(>=^^<))+import Spops(nullSP)++transmitterF s = closerF s >==< transmitterF' s++receiverF s = receiverF' s >=^^< nullSP++transceiverF s = receiverF' s >==< transmitterF' s++asyncTransceiverF s = receiverF' s >==< asyncTransmitterF' s
+ hsrc/io/UnsafeGetDLValue.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE CPP #-}+module UnsafeGetDLValue where+import DLValue++--unsafeDLValue :: DLValue -> anytype+#if defined(__NHC__) || defined(__PFE__)+unsafeGetDLValue DLValue = error "unsafeGetDLValue not implemented yet"+#else+unsafeGetDLValue (DLValue v) = v+#endif++-- This is unsafe, because the response from DLSym contains a DLValue of+-- a particular type. unsafeGetDLValue allows it to be used at any type.
+ hsrc/io/WriteFile.hs view
@@ -0,0 +1,18 @@+module WriteFile where+import HaskellIO(haskellIOF)+--import CompOps((>^=<))+import Cont(contMap)+--import NullF+import DialogueIO hiding (IOError)++writeFileF = writeFileF' WriteFile+writeXdgFileF = writeFileF' . WriteXdgFile++writeFileF' write = contMap wr+ where+ wr (file,contents) cont =+ haskellIOF (write file contents) $ \ resp ->+ cont (file,post resp)++ post (Failure e) = Left e+ post Success = Right ()
+ hsrc/kernelutils/BgF.hs view
@@ -0,0 +1,21 @@+module BgF(changeBackPixel, changeGetBackPixel) where+--import Color+import Command+--import Fudget+--import FudgetIO+--import Message(Message(..))+import Xcommand+--import NullF+import Xtypes+--import HaskellIO+import GCAttrs++--changeGetBackPixel :: ColorName -> Cont (K a b) Pixel+changeGetBackPixel bgcol f =+ --allocNamedColorDefPixel defaultColormap bgcol "white" $ \bgp ->+ convColorK [colorSpec bgcol,colorSpec "white"] $ \ bgp ->+ xcommandK (ChangeWindowAttributes [CWBackPixel bgp]) $+ xcommandK clearWindowExpose $+ f bgp++changeBackPixel bgcol = changeGetBackPixel bgcol . const
+ hsrc/kernelutils/GetVisual.hs view
@@ -0,0 +1,9 @@+module GetVisual where+import Command(XRequest(..))+import Event(XResponse(..))+import Xrequest(xrequest)++defaultVisual cont = xrequest DefaultVisual gotit cont+ where gotit (GotVisual v) = Just v+ gotit _ = Nothing+
+ hsrc/kernelutils/GetWindowProperty.hs view
@@ -0,0 +1,19 @@+module GetWindowProperty(getWindowPropertyK,getGeometryK) where+import Command+import Event+--import Font(FontStruct)+--import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import LayoutRequest(LayoutRequest)+--import Path(Path(..))+import Xrequest+--import Xtypes++getWindowPropertyK offset prop delete req_type =+ let gotit (GotWindowProperty typ format nitems after str) =+ Just (typ, format, nitems, after, str)+ gotit _ = Nothing+ in xrequestK (GetWindowProperty offset prop delete req_type) gotit++getGeometryK = xrequestK GetGeometry+ (\r -> case r of GotGeometry r bw d -> Just (r,bw,d); _ -> Nothing)
+ hsrc/kernelutils/GreyBgF.hs view
@@ -0,0 +1,85 @@+module GreyBgF(changeBg, darkGreyBgK, lightGreyBgK, greyBgK, knobBgK, changeBackPixmap) where+import BgF(changeBackPixel)+import Color+import Command+import XDraw+--import Event(XEvent,BitmapReturn)+import Fudget+--import FudgetIO+import Xcommand+import Gc+import Geometry(Rect(..), lL, pP)+--import LayoutRequest(LayoutRequest)+--import Message(Message(..))+--import NullF+import Pixmap+import Cont(tryM)+import Xtypes+import GCAttrs(convColorK) -- + instances++--changeBackPixmap :: ColorName -> ColorName -> Size -> [DrawCommand] -> (K a b) -> K a b+changeBackPixmap fgcol bgcol size draw f =+ convColorK fgcol $ \fg ->+ convColorK bgcol $ \bg ->+ changeBackPixmapCol fg bg size draw f++changeBackPixmapCol fg bg size draw f =+ createPixmap size copyFromParent $ \pm ->+ wCreateGC rootGC [{-GCFunction GXcopy,-}+ GCForeground fg, GCBackground bg,+ GCGraphicsExposures False] $ \gc ->+ wCreateGC gc [GCForeground bg] $ \gcbg ->+ xcommandsK [DrawMany (Pixmap pm)+ [(gcbg,[FillRectangle (Rect (pP 0 0) size)]),+ (gc, draw)],+ ChangeWindowAttributes [CWBackPixmap pm],+ clearWindowExpose,+ FreePixmap pm]+ f++knobBgK cont =+ try2 "grey33" "black" $ \ (Color fg _) ->+ try2 "grey" "white" $ \ (Color bg _) ->+ changeBackPixmapCol fg bg (pP 8 8)+ [DrawLine (lL 0 0 2 2), DrawLine (lL 4 6 6 4)] cont++dithered50BgK fg bg =+ changeBackPixmapCol fg bg (pP 2 2) [DrawLine (lL 0 0 1 1)]++dithered25BgK fg bg =+ changeBackPixmapCol fg bg (pP 2 2) [DrawLine (lL 0 0 0 0)]++dithered75BgK fg bg = dithered25BgK bg fg++trySolidGreyBgK cname dithK cont =+ alloc3 cname $ \ (Color black b) (Color white w) (Color gray g) ->+ if g==b || g==w+ then dithK white black cont+ else xcommandsK [ChangeWindowAttributes [CWBackPixel gray],+ clearWindowExpose] $+ cont++greyBgK = trySolidGreyBgK "grey" dithered50BgK+darkGreyBgK = trySolidGreyBgK "dark grey" dithered25BgK+lightGreyBgK = trySolidGreyBgK "light grey" dithered75BgK++changeBg :: ColorName -> (K a b) -> K a b+changeBg bg =+ case bg of+ "Nothing" -> id+ "grey" -> greyBgK+ _ -> changeBackPixel bg++alloc3 colorname cont =+ allocNamedColor defaultColormap "black" $ \black ->+ allocNamedColor defaultColormap "white" $ \white ->+ tryAllocNamedColor defaultColormap colorname $ \ ocolor ->+ let color = case ocolor of+ Nothing -> black+ Just c -> c in+ cont black white color+ +try2 cname1 cname2 cont =+ tryM (tryAllocNamedColor defaultColormap cname1)+ (allocNamedColor defaultColormap cname2 cont)+ cont
+ hsrc/kernelutils/InternAtom.hs view
@@ -0,0 +1,35 @@+module InternAtom(internAtomK, internAtomF, internAtom,+ atomNameK, atomNameF, atomName) where+import Command+import Event+--import Font(FontStruct)+--import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import LayoutRequest(LayoutRequest)+import Xrequest+--import Xtypes++internAtomK = ia xrequestK++internAtomF = ia xrequestF++internAtom a e = ia xrequest a e++ia k atomNm ifExists =+ let gotit (GotAtom atom) = Just atom+ gotit _ = Nothing+ in k (InternAtom atomNm ifExists) gotit++atomNameK = an xrequestK++atomNameF = an xrequestF++atomName a = an xrequest a++-- Here we need a Maybe String, so add an extra Just (the inner Just+-- is stripped by the fudlogue).++an k atom = + let gotit (GotAtomName (Just s)) = Just (Just s)+ gotit _ = Nothing+ in k (GetAtomName atom) gotit
+ hsrc/kernelutils/KernelUtils.hs view
@@ -0,0 +1,14 @@+module KernelUtils (-- * Kernel utilities+ module BgF,module GetWindowProperty,module GreyBgF,module InternAtom,module ParK,module QueryPointer,module QuitK,module ShapeK,module SimpleF,module QueryTree,module GetVisual,module MapstateK) where+import BgF+import GetWindowProperty+import GreyBgF+import InternAtom+import ParK+import QueryPointer+import QuitK+import ShapeK+import SimpleF+import QueryTree+import GetVisual+import MapstateK
+ hsrc/kernelutils/MapstateK.hs view
@@ -0,0 +1,5 @@+module MapstateK where+import Fudget+import Spops(mapstateSP)++mapstateK f s = K $ mapstateSP f s
+ hsrc/kernelutils/ParK.hs view
@@ -0,0 +1,52 @@+module ParK(parK,compK) where+--import Command(Command(..))+import CompSP+--import Event(Event(..))+import Fudget+--import Message(Message(..))+--import Path(Path(..))+--import SP+import Spops+import IsRequest+import CompFfun+import SpEither+++parK :: K a b -> K a b -> K a b+parK (K l) (K r) = K{-kk-} (parKSP l r)++parKSP :: KSP a b -> KSP a b -> KSP a b+parKSP l r = pkp [] (l `compEitherSP` r) where+ pkp routeq k = pk routeq (pullSP k)+ pk routeq (os,k) = pos os where+ pos os =+ case os of+ [] ->+ getSP $ \msg ->+ case msg of+ Low e | isResponse e ->+ case routeq of+ [] -> pos [] -- response without request?+ r:routeq -> feed routeq [r msg]+ _ -> feedr [Left msg, Right msg]+ where feed routeq l = pkp routeq (startupSP l k)+ feedr = feed routeq+ o:os -> case o of+ Right (High a) -> out (High a)+ Left (High a) -> out (High a)+ Right (Low c) -> lowout c Right+ Left (Low c) -> lowout c Left+ where+ lowout c route =+ putSP (Low c) $ + if isRequest c+ then pk (routeq++[route]) (os,k)+ else pos os+ out m = putSP m $ pos os++compK :: K a b -> K c d -> K (Either a c) (Either b d)+compK (K l) (K r) = K{-kk-} (compKSP l r)++compKSP :: KSP a b -> KSP c d -> KSP (Either a c) (Either b d)+compKSP l r = parKSP (Left `postMapHigh'` l `preProcessHigh'` filterLeftSP)+ (Right `postMapHigh'` r `preProcessHigh'` filterRightSP)
+ hsrc/kernelutils/QueryPointer.hs view
@@ -0,0 +1,15 @@+module QueryPointer(queryPointerK) where+import Command+import Event+--import Font(FontStruct)+--import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import LayoutRequest(LayoutRequest)+import Xrequest+--import Xtypes++queryPointerK =+ let f (PointerQueried s r w m) = Just (s, r, w, m)+ f _ = Nothing+ in xrequestK QueryPointer f+
+ hsrc/kernelutils/QueryTree.hs view
@@ -0,0 +1,45 @@+module QueryTree where+import Command+import Event+--import Font(FontStruct)+--import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import LayoutRequest(LayoutRequest)+--import Path(Path(..))+import Xrequest+--import Xtypes++queryTreeK = + xrequestK QueryTree gotit+ where+ gotit (TreeQueried r p cs) = Just (r,p,cs)+ gotit _ = Nothing++queryTreeF = + xrequestF QueryTree gotit+ where+ gotit (TreeQueried r p cs) = Just (r,p,cs)+ gotit _ = Nothing++{-+(defaultRootWindowK,defaultRootWindowF) =+ (xrequestK DefaultRootWindow gotit,xrequestF DefaultRootWindow gotit)+ where+ gotit (GotDefaultRootWindow w) = Just w+ gotit _ = Nothing++Doesn't work???+-}++defaultRootWindowK = + xrequestK DefaultRootWindow gotit+ where+ gotit (GotDefaultRootWindow w) = Just w+ gotit _ = Nothing++defaultRootWindowF = + xrequestF DefaultRootWindow gotit+ where+ gotit (GotDefaultRootWindow w) = Just w+ gotit _ = Nothing+
+ hsrc/kernelutils/QuitK.hs view
@@ -0,0 +1,61 @@+module QuitK where+import Command+import Event+import Fudget+--import FudgetIO+import FRequest+import Xcommand+import HaskellIO(haskellIO)+import InternAtom+--import Message(Message(..))+import NullF+import Spops(nullSP)+import CompFfun(postProcessHighK,preProcessHighK)+--import Sockets+import Xtypes+import DialogueIO hiding (IOError)++quitK action =+ nullSP `postProcessHighK`+ wmK (Just action)+ `preProcessHighK` nullSP++-- (*) wmK always enables the WM_DELETE_WINDOW protocol, since some window+-- managers provide a close button that destroy the window if the protocol+-- is disabled. Sigh.++wmK optAction =+ wmDeleteWindowK $ \dw -> -- (*)+ case optAction of+ Just action ->+ -- wmDeleteWindowK $ \dw -> -- (*)+ internAtomK "WM_PROTOCOLS" False $ \ pr ->+ wmK' (lowHandler action pr dw)+ Nothing -> wmK' (const id)+ where+ lowHandler action pr dw event =+ case event of+ XEvt (ClientMessage a (Long (p : _))) | a == pr && Atom (fromIntegral p) == dw ->+ action + _ -> id++ wmK' lowHandler = loop+ where+ loop =+ getK $ \msg ->+ case msg of+ Low event -> lowHandler event loop+ High (Left title) -> xcommandK (StoreName title) loop+ High (Right True) -> xcommandK MapRaised loop+ High (Right False) -> unmapWindowK loop+ _ -> loop++-- Some handlers:+exitK cont = haskellIO (Exit 0) (const nullK)+unmapWindowK = xcommandK UnmapWindow+reportK = putK (High ())++wmDeleteWindowK cont =+ internAtomK "WM_DELETE_WINDOW" False $ \dw ->+ xcommandK (SetWMProtocols [dw]) $+ cont dw
+ hsrc/kernelutils/ShapeK.hs view
@@ -0,0 +1,55 @@+module ShapeK(dynShapeK, shapeK) where+import Command(XCommand(FreeGC,FreePixmap,ShapeCombineMask,DrawMany))+import XDraw+import CompFfun(prepostMapHigh')+import Convgc+--import Event+import LayoutRequest(LayoutResponse(..))+import FRequest+import Gc+import Fudget+--import FudgetIO+import Xcommand+import NullF+import ParK+import Pixmap+import EitherUtils(stripEither)+import Data.Maybe(fromJust)+import Geometry(pP,Rect(..),origin,Size)+import Xtypes++dynShapeK gcattrs shapeCmds f = compK (shapeK1 gcattrs shapeCmds) f++shapeK :: (Size -> [DrawCommand]) -> K a b -> K a b+shapeK shapeCmds f =+ K{-kk-} (prepostMapHigh' Right stripEither dk)+ where+ K dk = dynShapeK [] shapeCmds f++shapeK1 gcattrs shape =+ convGCattrsK gcattrs (\gcattrs' -> shapeP gcattrs' shape Nothing)++shapeP gcattrs shape size =+ let reshape shape' size' =+ createPixmap size' 1 $ \pm ->+ pmCreateGC pm rootGC [GCFunction GXcopy, GCForeground pixel0] $ \gcclr ->+ pmCreateGC pm gcclr (GCForeground pixel1 :+ GCBackground pixel0 :+ gcattrs) $ \gc ->+ xcommandsK [drawshape pm size' shape' gc gcclr,+ ShapeCombineMask ShapeBounding (pP 0 0) pm ShapeSet,+ FreePixmap pm,+ FreeGC gcclr,+ FreeGC gc] $+ shapeP gcattrs shape' (Just size')+ in getK $ \msg ->+ case msg of+ Low (LEvt (LayoutSize size')) -> reshape shape size'+ High shape' | size /= Nothing -> reshape shape' (fromJust size)+ _ -> shapeP gcattrs shape size++drawshape pm size shapeCmds gc gcclr =+ DrawMany (Pixmap pm) [+ (gcclr,[FillRectangle (Rect origin size)]),+ (gc,shapeCmds size)]+
+ hsrc/kernelutils/SimpleF.hs view
@@ -0,0 +1,48 @@+module SimpleF(Drawer(..), Fms'(..), MapState(..), simpleF, simpleWindowF, simpleK) where+import Color+import Command+import XDraw+import Dlayout(windowF)+import DShellF+--import FDefaults+--import Event+import Fudget+import FudgetIO+import FRequest+--import Xcommand+import Gc+import Geometry(Size)+import LayoutRequest+--import Message(Message(..))+--import NullF+--import Spops+import MapstateK+import Xtypes++type MapState a b c = a -> b -> (a, c)++type Fms' a b c = MapState a (KEvent b) [KCommand c]++type Drawer = DrawCommand -> FRequest++simpleK k size s0 = simpleK' k size True True s0++simpleK' :: (Drawer->Drawer->Fms' a b c) -> Size -> Bool -> Bool -> a -> K b c+simpleK' k size fixedh fixedv s0 =+ allocNamedColorPixel defaultColormap "black" $ \fg ->+ allocNamedColorPixel defaultColormap "white" $ \bg ->+ wCreateGC rootGC [GCFunction GXcopy,GCForeground fg,GCBackground bg] $ \fgc ->+ wCreateGC fgc [GCForeground bg] $ \bgc ->+ putLow (layoutRequestCmd (plainLayout size fixedh fixedv)) $+ mapstateK (k (wDraw fgc) (wDraw bgc)) s0++simpleF title k size s0 =+ shellF title $+ simpleWindowF k size False False s0++simpleWindowF k size fh fv s0 =+ windowF [XCmd $ ChangeWindowAttributes [CWEventMask eventmask]] $+ simpleK' k size fh fv s0+ where+ eventmask = [ExposureMask, KeyPressMask, KeyReleaseMask, ButtonPressMask,+ ButtonReleaseMask]
+ hsrc/layout/AlignP.hs view
@@ -0,0 +1,35 @@+module AlignP where+--import Alignment(Alignment(..))+--import Geometry(Line(..), Point(..), Rect(..), Size(..), padd, psub, rR)+--import LayoutDir(LayoutDir)+import LayoutRequest+import Utils(mapPair, number, swap)+import HbcUtils(apSnd)+import List2(sort)+--import Spacers++-- placer operations++idP :: Placer+idP = P $ \ [req] -> (req, (: []))++--revP :: Placer -> Placer+revP = mapP revP'+ where revP' placer = apSnd (reverse .) . placer . reverse++mapP f (P p) = P (f p)++flipP :: Placer -> Placer+flipP = mapP flipP'+ where+ flipP' placer = mapPair (flipReq,flipP2) . placer . map flipReq+ flipP2 p2 = map flipRect.p2.flipRect++permuteP :: [Int] -> Placer -> Placer+permuteP perm = mapP permuteP'+ where+ permuteP' placer = apSnd (rpermf .) . placer . fpermf+ rperm = (map snd . sort . map swap . number 0) perm+ fpermf = permf perm+ rpermf = permf rperm+ permf perm xs = map (xs!!) perm
+ hsrc/layout/Alignment.hs view
@@ -0,0 +1,12 @@+module Alignment where++type Alignment = Double++aTop = 0 :: Alignment+aBottom = 1 :: Alignment++aLeft = 0 :: Alignment+aRight = 1 :: Alignment++aCenter = 0.5 :: Alignment+
+ hsrc/layout/AutoLayout.hs view
@@ -0,0 +1,352 @@+{-# LANGUAGE CPP #-}+module AutoLayout(autoLayoutF,autoLayoutF',nowait) where+--import Prelude hiding (IO)+import LayoutRequest(LayoutMessage(..),LayoutResponse(..),LayoutRequest(minsize),LayoutHint,Spacer,Placer(..),Placer2,unS)+import LayoutDoNow+import PathTree hiding (pos)+import Geometry(Rect)+import Fudget+--import Spops+--import FudgetIO+import NullF(getK,putK,putsK) --,F,K+import Loops(loopThroughRightF)+import UserLayoutF+--import Xtypes+--import Event+--import Command+import FRequest+--import Path+import Direction+--import Placers+--import LayoutDir(LayoutDir)+--import CompOps+import IoF(ioF)+import CmdLineEnv(argFlag)+--import EitherUtils()+import Data.Maybe(isJust)+import HbcUtils(apFst,apSnd)+import Spacers(idS,compS,spacerP)+import AutoPlacer(autoP)+import SizingF+#ifdef __NHC__+import qualified Sizing+#else+import qualified Sizing(Sizing(..))+#endif+--import ContinuationIO(stderr)++-- debugging:+import StdIoUtil(echoStderrK)+--import NonStdTrace(trace)+--import Maptrace(ctrace)+--import SpyF++debugK :: String -> K hi ho -> K hi ho+debugK =+ if dbg+ then \ msg -> echoStderrK ("AutoLayout: "++msg)+ else const id+ where+ dbg = argFlag "ad" False++type LayoutTree = PathTree LayoutInfo++mapLT lf nf = mapPathTree (mapLayoutInfo lf nf)++top0 = Node (NodeInfo (Just "top",NoPlacerInfo)) Tip Tip++data LayoutInfo+ = NodeInfo NodeInfo+ | LeafInfo LeafInfo -- only in leaves+ deriving (Show)++mapLayoutInfo lf nf n = case n of+ NodeInfo n -> NodeInfo (nf n)+ LeafInfo l -> LeafInfo (lf l)++type LeafInfo = (LayoutRequest,Maybe Rect)+ -- (Layout s fh fv,Nothing) : received layout req, layout not computed+ -- (Layout s fh fv,Just rect) : rect is current placement.++type NodeInfo = ((Maybe LayoutHint), PlacerInfo)++data PlacerInfo =+ NoPlacerInfo |+ JustSpacer Spacer |+ SpacerPlacer Spacer Placer (Maybe Placer2) Spacer + deriving (Show)++data PlacementState+ = Placed (Rect->Rect)+ | Waiting + deriving (Show)++autoLayoutF = autoLayoutF' nowait Sizing.Dynamic++nowait = argFlag "nowait" False++autoLayoutF' :: Bool -> Sizing.Sizing -> F a b -> F a b+autoLayoutF' nowait sizing fud =+ loopThroughRightF + (userLayoutF (layoutDoNow fud)) + ({- spyF -} (sizingF sizing (ioF (autoLayoutMgrK0 state0 top0))))+ -- Note that the sizingF filter is not wrapped around fud and hence+ -- does not have to examine all commands and events!+ where+ state0 = if nowait then Placed id else Waiting++autoLayoutMgrK0 pstate ltree =+ debugK "autoLayoutMgrK" $+ autoLayoutMgrK pstate ltree++autoLayoutMgrK pstate ltree =+ --echoK (show (pstate,ltree)) $+ getK $ \ msg ->+ case msg of+ High (path,layoutmsg) ->+ case layoutmsg of+ LayoutDoNow ->+ debugK "LayoutDoNow" $+ debugK (show ltree) $+ newPlace ltree+ LayoutRequest req ->+ debugK (show path ++ " Layout "++show (minsize req)) $+ debugK (show ltree') $+ changePlacement ltree'+ where ltree' = updateLeaf path req ltree''+ ltree'' = if newBox ltree path+ then forgetPlaces ltree+ else ltree+ -- LayoutHint & LayoutPlacer are only sent during initialisation.+ -- They will be received before any child Layout requests.+ LayoutHint hint ->+ debugK (show path ++ " LayoutHint "++ show hint) $+ updnode (insertHint hint)+ LayoutPlacer placer ->+ debugK (show path ++ " LayoutPlacer ...") $+ updnode (insertPlacer placer)+ LayoutSpacer spacer ->+ debugK (show path ++ " LayoutSpacer ...") $+ updnode (insertSpacer spacer)+ -- LayoutReplaceSpacer is sent by dynSpacerF.+ LayoutReplaceSpacer spacer ->+ debugK (show path ++ " LayoutReplaceSpacer ...") $+ replnode (replaceSpacer spacer)+ LayoutReplacePlacer placer ->+ debugK (show path ++ " LayoutReplacePlacer ...") $+ replnode (replacePlacer placer)+ LayoutDestroy -> + debugK (show (path,ltree) ++ " LayoutDestroy") $+ -- should check if the subtree contains anything but hints.+ if newBox ltree path then debugK ("not in tree") same else+ changePlacement (forgetPlaces (pruneLTree path ltree))+ -- !! forgetPlaces should be called when the structure changes,+ -- but not when an existing fudget requests a new size...+ LayoutMakeVisible _ _ -> putK (Low (LCmd layoutmsg)) $ same+ LayoutScrollStep _ -> putK (Low (LCmd layoutmsg)) $ same+ _ -> same -- !!! handle other layout requests?!+ where updnode u = newTree (updateLNode path u ltree)+ replnode u = changePlacement (forgetPlaces (updateLNode path u ltree))+ Low (LEvt (LayoutPlace rect)) ->+ debugK ("splitting 1 Place into "++show (length msgs)) $+ putsK (map High msgs) $+ newTree ltree'+ where (ltree',msgs) = doLayout (s2 rect) ltree+ s2 = case pstate of+ Placed s2 -> s2+ _ -> id+ Low _ -> debugK "Ignored low level msg" same+ where+ same = autoLayoutMgrK pstate ltree+ newTree t' = newState pstate t'+ newState p' t' = autoLayoutMgrK p' t'+ changePlacement ltree' =+ case pstate of+ Placed _ -> newPlace ltree'+ Waiting -> newTree ltree'+ newPlace ltree =+ let ltree' = chooseLayout ltree+ in case collectReqs ltree' of+ ([],_) -> debugK "newPlace without any requests in ltree" same+ ((req,s2):_,ltree2) ->+ putK (Low (layoutRequestCmd req)) $+ newState (Placed s2) ltree2++updateLNode path i t = updateNode id emptyNode t path $+ \(NodeInfo ni) -> NodeInfo (i ni)++insertHint hint (_,pi) = (case pi of+ SpacerPlacer _ _ _ _ -> Nothing+ _ -> Just hint,pi)++insertPlacer placer (hint,pi) = (Nothing,case pi of+ NoPlacerInfo -> SpacerPlacer idS placer Nothing idS+ JustSpacer s -> SpacerPlacer s placer Nothing idS+ SpacerPlacer s1 p _ s2 -> SpacerPlacer (s1 `compS` s2) (p `compP` placer)+ Nothing idS)+ where compP :: Placer -> Placer -> Placer+ compP (P p1) (P p2) = P $ \ reqs ->+ let (req1,p1r) = p1 [req2]+ (req2,p2r) = p2 reqs+ in (req1,p2r.head.p1r)++insertSpacer spacer (hint,pi) = (hint,case pi of+ NoPlacerInfo -> JustSpacer spacer+ JustSpacer s -> JustSpacer (s `compS` spacer)+ SpacerPlacer s1 p p2 s2 -> SpacerPlacer s1 p p2 (s2 `compS` spacer))++replaceSpacer spacer (hint,pi) = (hint,pi')+ where+ pi' = case pi of+ NoPlacerInfo -> JustSpacer spacer+ JustSpacer s -> JustSpacer spacer+ SpacerPlacer s1 p p2 s2 -> SpacerPlacer spacer p p2 s2 -- hmm++replacePlacer placer (hint,pi) = (hint,pi')+ where+ pi' = case pi of+ NoPlacerInfo -> SpacerPlacer idS placer Nothing idS+ JustSpacer s -> SpacerPlacer s placer Nothing idS+ SpacerPlacer s1 p p2 s2 -> SpacerPlacer s1 placer Nothing s2++updateLeaf path l t =+ updateNode invalid emptyNode t path (const (LeafInfo (l,Nothing)))++pruneLTree path t = pruneTree invalid emptyNode t path++forgetPlaces = mapLT (apSnd (const Nothing)) id+ +newBox x = subTree (const False) True x++invalid (NodeInfo i) = NodeInfo (invalid' i)+ where+ invalid' (hi,SpacerPlacer s p p2 s2) = (hi,SpacerPlacer s p Nothing s2)+ invalid' ni = ni++emptyNode = NodeInfo (Nothing,NoPlacerInfo)++hasPlacer (Nothing,SpacerPlacer _ _ _ _) = True+hasPlacer _ = False++-- strip hints below placer, insert autoP where there are hints left+chooseLayout = snd . attrMapLT lf nf False where+ lf strip _ i = (strip,(),i)+ nf strip _ n = (strip',(),n') where+ strip' = case n of+ (Nothing,SpacerPlacer _ _ _ _) -> True+ _ -> strip --+ n' = if strip then n else choosePlacer n++choosePlacer i = case i of+ (hi@(Just _),pi) -> (hi,case pi of+ NoPlacerInfo -> SpacerPlacer idS autoP Nothing idS+ JustSpacer s -> SpacerPlacer s autoP Nothing idS+ p -> p)+ i -> i++attrMapLT lf nf = attrMapPathTree f where+ f i s a = case a of+ LeafInfo li -> a3 LeafInfo $ lf i s li+ NodeInfo ni -> a3 NodeInfo $ nf i s ni+ a3 c (i,s,b) = (i,s,c b)++collectReqs = apFst (flip compose []) . attrMapLT lf nf idS where+ lf s _ i@(req,oplace) = (s,reqf,i) where + reqf = (unS s lr:)+ lr = case oplace of+{- -- You can use static sizing of shell windows instead of this:+ Just (Rect _ currentsize) ->+ -- use current size, not originally requested size+ --ctrace "spacer" ("current",i) $+ mapLayoutSize (const currentsize) req+-}+ _ -> --ctrace "spacer" ("nocurrent",i)+ req+ nf s reqfs n@(hi,pi) = case pi of+ NoPlacerInfo -> (s,reqf,n)+ JustSpacer s1 ->+ --ctrace "spacer" (fst ((s `compS` s1) (Layout origin False False))) $+ (s `compS` s1,reqf,n)+ SpacerPlacer s1 p orp2 s2 ->+ --ctrace "spacer" (n,fst (compp $ [Layout origin False False])) $ + (inherS,syntreq,n') where+ rp2@(req2,p2) = compp `spacer2P` reqfl+ reqfl = reqf []+ compp = if hashint then p else sl `spacerP` p+ inherS = if hashint then sl `compS` s2 else s2+ syntreq = if null reqfl then id else (unS idS req2:)+ sl = s `compS` s1+ hashint = isJust hi+ orp2' = if null reqfl then Nothing else Just rp2+ n' = (hi,SpacerPlacer s1 p orp2' s2)+-- Just (req,_) -> ctrace "spacer" (n,req) (s2,(idS req:),n)+ where reqf = compose reqfs++ compose = foldr (.) id++doLayout rect tree = runIO (doLayoutIO tree []) [rect]++spacer2P (P p) reqfs = (req,s2f.p2) where+ (reqs,s2s) = unzip reqfs+ s2f rs = [s2 r | (s2,r) <- zip s2s rs]+ (req,p2) = p reqs++doLayoutIO t path =+ case t of+ Tip -> returnIO t+ Node (LeafInfo (l,maybeOldRect)) _ _ ->+ getIO `bindIO` \ r ->+ putIO (reverse path,r) `thenIO` + -- check if r is different from old rect?+ returnIO (Node (LeafInfo (l,Just r)) Tip Tip)+ Dynamic dt -> returnIO Dynamic `ap` dynDoLayoutIO dt path 0 1+ Node ni@(NodeInfo (_,pi)) lt rt ->+ case pi of+ SpacerPlacer s1 p orp2 s2 ->+ case orp2 of+ Just (req,placer2) ->+ getIO `bindIO` \ r ->+ ungetIO (placer2 r) `thenIO`+ doBranches+ Nothing -> returnIO t -- no requests in this tree+ _ -> doBranches+ where+ doBranches =+ returnIO (Node ni) `ap` doLayoutIO lt (L:path)+ `ap` doLayoutIO rt (R:path)+++dynDoLayoutIO dt path n i =+ case dt of+ DynTip -> returnIO dt+ DynNode t lt rt ->+ returnIO DynNode `ap`+ doLayoutIO t (Dno (unpos n):path) `ap`+ dynDoLayoutIO lt path n (2*i) `ap`+ dynDoLayoutIO rt path (n+i) (2*i)++--++type IO' a i o = i -> o -> (a,(i,o))++runIO io i =+ let (a,(_,o)) = io i []+ in (a,o)++returnIO a i o = (a,(i,o))+putIO o1 is os = ((),(is,o1:os))+getIO (i:is) os = (i, (is,os))+--getIO (i:is) os = (Just i, (is,os))+--getIO [] os = (Nothing,(is,os))+ungetIO is' is os = ((),(is'++is,os))++bindIO io1 xio2 i0 o0 =+ let (x,(i1,o2)) = io1 i0 o1+ (y,(i2,o1)) = xio2 x i1 o0+ in (y,(i2,o2))++thenIO f1 f2 = f1 `bindIO` const f2++fIO `ap` xIO = fIO `bindIO` \ f ->+ xIO `bindIO` \ x ->+ returnIO (f x)
+ hsrc/layout/AutoPlacer.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE CPP #-}+module AutoPlacer(autoP,autoP') where+import LayoutRequest+import Geometry+import Placers(horizontalP',verticalP')+import Spacers() -- synonym Distance, for hbc+import AlignP(idP)+--import LayoutDir+import CmdLineEnv(argFlag)+import Defaults(defaultSep)+import Data.Ratio+import Debug.Trace(trace)++-- should get hints somehow+autoP = autoP' defaultSep++autoP' :: Size -> Placer+autoP' (Point hsep vsep) = P $ \ requests ->+ case requests of+ [] -> trace "autoP []" $ (plainLayout 1 True True, \ r -> [])+ [r] -> unP idP requests+ _ -> p where+ h2@(h,_) = unP (horizontalP' hsep) requests+ v2@(v,_) = unP (verticalP' vsep) requests+ p = if goodness h2 requests<goodness v2 requests+ then h2 else v2++{-+--godness : measure how good a layout is.+-- 1st: a layout is better if it uses less screen space.+-- 2nd: a layout is better if it is more quadratic +-- (rather than long and narrow)+goodness (Layout {minsize=Point x y}) = (x*y,x+y)+ -- (area, circumference of rect / 2)+-- This doesn't work, because of separation between fudgets...+-}++goodness =+ if argFlag "sg" False+ then \ p1 rs -> (1%1,simpleGoodness (fst p1))+ else newGoodness++simpleGoodness (Layout {minsize=Point w h}) = w+h++#if 1+-- normal version+newGoodness (Layout {minsize=s@(Point w h)},placer2) reqs =+ (wasted % (w*h),w+h)+ where+ wasted = sum (zipWith waste reqs (placer2 (Rect origin s)))+ waste (Layout {minsize=Point rw rh,fixedh=fh,fixedv=fv}) (Rect _ (Point aw ah)) =+ case (fh,fv) of+ (True,True) -> aw*ah-rw*rh+ (False,False) -> 0+ (True,False) -> (aw-rw)*ah+ (False,True) -> (ah-rh)*aw+#else+-- Röjemo's debug version+-- needs updating+newGoodness (Layout {minsize=s@(Point w h)},placer2) reqs =+ trace ("w = " ++ show w ++ "\n"+ ++ "h = " ++ show h ++ "\n"+ ++ "wlist = " ++ show wlist ++ "\n"+ ++ "wasted = " ++ show wasted ++ "\n"+ ++ "w*h = " ++ show (w*h) ++ "\n"+ ++ "(wasted % (w*h),w+h) = " ++ show (wasted % (w*h),w+h) ++ "\n")+ (wasted % (w*h),w+h)+ where+ wlist = (zipWith waste reqs (placer2 (Rect origin s)))+ wasted = sum wlist+ waste (Layout (Point rw rh) fh fv) (Rect _ (Point aw ah)) =+ case (fh,fv) of+ (True,True) -> trace ("aw*ah-rw*rh = " ++ show aw ++ '*':show ah ++ '-':show rw ++ '*':show rh ++ "\n") $ aw*ah-rw*rh+ (False,False) -> trace ("0\n") 0+ (True,False) -> trace ("(aw-rw)*ah = (" ++ show aw ++ '-':show rw ++ ")*" ++ show ah ++ "\n") $ (aw-rw)*ah+ (False,True) -> trace ("(ah-rh)*aw = (" ++ show ah ++ '-':show rh ++ ")*" ++ show aw ++ "\n") $ (ah-rh)*aw+#endif
+ hsrc/layout/CondLayout.hs view
@@ -0,0 +1,32 @@+module CondLayout(ifSizeP,ifSizeS,stretchCaseS,alignFixedS,alignFixedS') where+import LayoutRequest+--import Geometry(Size)+import Spacers(idS,hAlignS,vAlignS,hvAlignS,compS,noStretchS)++--ifSizeP :: (Size->Size->Bool) -> Placer -> Placer -> Placer+--ifSizeS :: (Size->Size->Bool) -> Spacer -> Spacer -> Spacer+ifSizeP b (P p1) (P p2) = P $ ifSize b p1 p2+ifSizeS b (S s1) (S s2) = S $ ifSize b s1 s2++ifSize p primP spareP reqs =+ if p primSize spareSize+ then primP2+ else spareP2+ where+ primP2@(Layout {minsize=primSize},_) = primP reqs+ spareP2@(Layout {minsize=spareSize},_) = spareP reqs++stretchCaseS :: ((Bool,Bool)->Spacer) -> Spacer+stretchCaseS sS = S $ \ req -> unS (sS (fixedh req,fixedv req)) req++alignFixedS ha va =+ stretchCaseS $ \ fixedhv ->+ case fixedhv of+ (False,False) -> idS+ (True, False) -> hAlignS ha+ (False,True) -> vAlignS va+ (True, True) -> hvAlignS ha va++alignFixedS' ha va =+ stretchCaseS $ \ fhv ->+ uncurry noStretchS fhv `compS` alignFixedS ha va
+ hsrc/layout/DynListLF.hs view
@@ -0,0 +1,34 @@+module DynListLF(dynListLF) where+import Fudget+import CompOps((>+<))+import DynListF+import Dynforkmerge(DynMsg(..))+import Loops(loopThroughRightF)+import SerCompF(concatMapF)+import UserLayoutF+--import Geometry+import LayoutRequest+import LayoutSP(dynLayoutMgrF)+import LayoutF(LayoutDirection(..))++dynListLF :: Placer -> F (Int, DynFMsg a b) (Int, b)+dynListLF lter =+ loopThroughRightF+ (concatMapF ctrl) (dynLayoutMgrF 0 Forward lter>+<userLayoutF dynListF)++ctrl msg =+ case msg of+ Right dyn@(i,dynmsg) ->+ case dynmsg of+ DynCreate _ -> [toMgrDyn (i,True),toDyn dyn]+ DynDestroy -> [toMgrDyn (i,False),toDyn dyn]+ DynMsg _ -> [toDyn dyn]+ Left (Left pp) -> [toDynL pp]+ Left (Right (Left ll)) -> [toMgr ll]+ Left (Right (Right x)) -> [out x]++toDyn=Left. Right. Right+toDynL=Left. Right. Left+toMgr=Left. Left. Left+toMgrDyn=Left. Left. Right+out=Right
+ hsrc/layout/DynSpacerF.hs view
@@ -0,0 +1,18 @@+module DynSpacerF(dynSpacerF,dynPlacerF) where+import Fudget+import LayoutRequest+import SerCompF(idLeftF)+import CompSP(postMapSP)+import Path(here)+import Message+--import Command+import FRequest++dynSpacerF = dynLayoutMsgF LayoutReplaceSpacer+dynPlacerF = dynLayoutMsgF LayoutReplacePlacer++dynLayoutMsgF lmsg fud = F (post `postMapSP` fudsp)+ where+ F fudsp = idLeftF fud+ post = message Low (either sendLmsg High)+ sendLmsg x = Low (here,LCmd (lmsg x))
+ hsrc/layout/HorizontalAlignP.hs view
@@ -0,0 +1,96 @@+module HorizontalAlignP where+import Data.List(mapAccumL)+import LayoutRequest+import Geometry+import Spacers(Distance(..),layoutModifierS,idS)+import Defaults(defaultSep)++-- Better names:+alignP = horizontalAlignP+alignP' = horizontalAlignP'++horizontalAlignP = horizontalAlignP' defaultSep++horizontalAlignP' :: Distance -> Placer+horizontalAlignP' sep = P haP+ where+ haP reqs = (req,placer2)+ where+ sepp = pP sep 0+ req = refpLayout rsize fh fv [ref1,ref2]+ fh = all fixedh reqs+ fv = False -- any fixedv reqs+ reqrects0 = snd $ mapAccumL reqrect (-sepp) reqs+ where+ reqrect ref0 (Layout {minsize=s,fixedh=fh,fixedv=fv,refpoints=rps}) =+ (ref2',((Rect d s,(fh,fv)),(d+ref1,ref2')))+ where d = ref0-ref1+sepp+ ref2' = d+ref2+ (ref1,ref2) = case rps of+ [] -> middleRefs s+ _ -> (head rps,last rps)++ reqrects = map adj reqrects0+ where adj ((r,f),(ref1,ref2)) =+ ((moverect r (-minp),f),(ref1-minp,ref2-minp))+ minp = pMin (0:[d | ((Rect d _,_),_) <- reqrects0])++ rsize = pMax (1:[p+s | ((Rect p s,_),_) <- reqrects])+ (ref1,ref2) =+ case reqrects of+ [] -> middleRefs rsize+ _ -> (fst . snd . head $ reqrects,snd . snd . last $ reqrects)++ placer2 rect@(Rect p asize) = [moverect r d | ((r,_),_)<-reqrects]+ where d = p -- + scalePoint 0.5 (pmax 0 (asize-rsize))++--refMiddleS :: Spacer+refMiddleS = S refMiddleS'++refMiddleS' req =+ let (ref1,ref2) = middleRefs (minsize req)+ in (req{refpoints=[ref1,ref2]},id)+-- in (Layout s fh fv wa ha [ref1,ref2] wanted,id)++--refEdgesS :: Spacer+refEdgesS = S refEdgesS'+ where+ refEdgesS' req@(Layout {refpoints=[]}) = refMiddleS' req+ refEdgesS' req@(Layout {minsize=Point w _,refpoints=rps}) =+ (req {refpoints=[ref1,ref2]},id)+ where+ ref1 = (head rps){xcoord=0}+ ref2 = (last rps){xcoord=w}++middleRefs (Point w h) = (pP 0 h2,pP w h2)+ where h2 = h `div` 2++noRefsS :: Spacer+noRefsS = S $ \ req -> (req {refpoints=[]},id)++moveRefsS :: Point -> Spacer+moveRefsS d = layoutModifierS (mapLayoutRefs (d+))++---++spacersP :: Placer -> [Spacer] -> Placer+spacersP (P placer) spacers = P $ \ reqs ->+ let+ (reqs',spacers2) = unzip (zipWith unS (spacers++repeat idS) reqs)+ (req,placer2) = placer reqs'+ placer2' = zipWith id spacers2 . placer2+ in (req,placer2')++---+overlayAlignP :: Placer+overlayAlignP = P $ \ ls ->+ let maxrp = maximum [head (refpoints l) | l<-ls, not (null (refpoints l))]+ ss = [f ms rps | Layout { minsize=ms,refpoints=rps}<-ls ]+ where f s [] = s+ f s (rp:_) = s+maxrp-rp+ req = refpLayout (pMax ss) (any fixedh ls) (any fixedv ls) [maxrp]+ placer2 r = [f r rps | Layout {refpoints=rps} <- ls]+ where f r [] = r+ f (Rect p s) (rp:_) = Rect (p+d) (s-d)+ where d=maxrp-rp+ in (req,placer2)
+ hsrc/layout/Layout.hs view
@@ -0,0 +1,29 @@+module Layout (-- * Layout+ module AutoLayout,module AlignP,module Alignment,+ --module Barlayouter,+ module LayoutDir,module LayoutF,module LayoutRequest,module Placers,module MatrixP,module Layoutspec,module TableP,module TryLayout,module NameLayout,module UserLayoutF,module AutoPlacer,module DynListLF,module Placer,module Spacer,module Spacers,module Placers2,module DynSpacerF,module Sizing,module CondLayout,module HorizontalAlignP,module ParagraphP) where+import AutoLayout+import AlignP+import Alignment+--import Barlayouter+import LayoutDir+import LayoutF+import LayoutRequest+import Placers+import MatrixP+import Layoutspec+import TableP+import TryLayout+import NameLayout+import UserLayoutF+import DynListLF+import AutoPlacer+import Placer+import Spacer+import Spacers+import Placers2+import DynSpacerF+import Sizing+import CondLayout+import HorizontalAlignP+import ParagraphP
+ hsrc/layout/LayoutDir.hs view
@@ -0,0 +1,35 @@+module LayoutDir where+import Geometry(Point(..), xcoord, ycoord)+import LayoutRequest+import Utils(swap)++data Orientation = Above | Below | RightOf | LeftOf+ deriving (Eq, Ord, Show)++data LayoutDir = Horizontal | Vertical deriving (Eq, Ord, Show)+++xc Horizontal = xcoord+xc Vertical = ycoord++yc Horizontal = ycoord+yc Vertical = xcoord++fixh Horizontal = fixedh+fixh Vertical = fixedv++fixv Horizontal = fixedv+fixv Vertical = fixedh++mkp Horizontal x y = Point x y+mkp Vertical x y = Point y x++vswap Horizontal = id+vswap Vertical = swap++colinear Horizontal h v = h+colinear Vertical h v = v++orthogonal Horizontal h v = v+orthogonal Vertical h v = h+
+ hsrc/layout/LayoutDoNow.hs view
@@ -0,0 +1,27 @@+module LayoutDoNow where++import Fudget+--import Command+import FRequest+--import Event+--import Message+import Spops+--import SP(SP)+import Path(here)+import LayoutRequest+import IsRequest++layoutDoNow (F sp) = F{-ff-} (layoutDoNow' sp)++layoutDoNow' f = donow 0 (pullSP f) where+ donow pendingreqs (os,f) = + putsSP os $ + let n' = pendingreqs + newreqs+ newreqs = length (filter isReq os)+ isReq (Low (_,c)) = isRequest c+ isReq _ = False+ nResp (Low (_,e)) | isResponse e = 1+ nResp _ = 0+ in if n' == 0 then putSP (Low (here,LCmd LayoutDoNow)) f+ else + getSP $ \msg -> donow (n' - nResp msg) (walkSP f msg)
+ hsrc/layout/LayoutF.hs view
@@ -0,0 +1,52 @@+module LayoutF(serCompLF, compLF, listLF, untaggedListLF,+ --rbLayoutF,+ nullLF, holeF, holeF', lF, LayoutDirection(..),orientP) where+--import TableP+import CompF+import CompOps((>^=<))+import Fudget+import FRequest+import Geometry() -- instances+import LayoutDir(Orientation(..))+import LayoutRequest+import Placers+import ListF+import NullF+import FudgetIO+import SerCompF(serCompF)+import Utils(number)+--import Xtypes+import AlignP(revP)+import Placer(placerF)++data LayoutDirection = Forward | Backward deriving (Eq, Ord,Show)++holeF' s = putLow (layoutRequestCmd (plainLayout s False False)) nullF+holeF = holeF' 0+nullLF = holeF++--listLF :: Eq a => Placer -> [(a, F b c)] -> F (a, b) (a, c)+listLF placer fl = lF (length fl) Forward placer (listF fl)++untaggedListLF :: Placer -> [F a b] -> F (Int, a) b+untaggedListLF layout fs = snd >^=< listLF layout (number 0 fs)++compLF = cLF compF+serCompLF = cLF serCompF+--rbLayoutF sep = lF 3 Forward (rightBelowP sep)++cLF :: ((F a b) -> (F c d) -> F e f) -> (F a b,Orientation) -> F c d -> F e f+cLF cF (f1,ori) f2 = lF 2 Forward (orientP ori) (cF f1 f2)++lF :: Int -> LayoutDirection -> Placer -> (F a b) -> F a b+lF 0 _ _ f = nullLF+lF nofudgets dir placer f = placerF placer' f where + placer' = if dir == Backward then revP placer else placer++orientP :: Orientation -> Placer+orientP ori =+ case ori of+ Above -> verticalP+ Below -> revP verticalP+ LeftOf -> horizontalP+ RightOf -> revP horizontalP
+ hsrc/layout/LayoutHints.hs view
@@ -0,0 +1,15 @@+module LayoutHints(module LayoutHints,LayoutHint(..)) where+import Fudget+import LayoutRequest+import FRequest+--import Geometry(Point, Size(..),Rect)+import NullF(putMessageFu)+--import Command++serHint = "ser" :: LayoutHint+parHint = "par" :: LayoutHint+listHint = "list" :: LayoutHint+loopHint = "loop" :: LayoutHint++layoutHintF :: LayoutHint -> F a b -> F a b+layoutHintF hint = putMessageFu (Low (LCmd (LayoutHint hint)))
+ hsrc/layout/LayoutRequest.hs view
@@ -0,0 +1,81 @@+module LayoutRequest where+import Geometry(Point(..), Size(..),Rect(..){-,padd,psub,pmax,pP-})+--import EitherUtils(mapMaybe)+--import HO(apFst)+--import Maptrace(ctrace) -- debugging+import Alignment+import ShowFun()++data LayoutRequest+ = Layout { minsize :: Size,+ fixedh, fixedv :: Bool,+ wAdj, hAdj :: Int -> Size,+ -- If the available width is w+ -- then the size of this box should be wAdj w.+ -- Analogously for hAdj.+ refpoints :: [Point], -- used by some placers+ wantedPos :: Maybe (Point,Size,Alignment)+ }+ deriving (Show)++plainLayout s fh fv = refpLayout s fh fv []+refpLayout s fh fv rps = Layout s fh fv wa ha rps Nothing+ where+ wa w = {-ctrace "wa" (show (w::Int,s)) $-} s+ ha h = {-ctrace "ha" (show (h::Int,s)) $-} s+ --wa = if fh then const s else \ w -> pmax s (pP w 0)+ --ha = if fv then const s else \ h -> pmax s (pP 0 h)++data LayoutMessage+ = LayoutRequest LayoutRequest+ | LayoutMakeVisible Rect (Maybe Alignment,Maybe Alignment)+ | LayoutScrollStep Int+ | LayoutName String+ | LayoutPlacer Placer+ | LayoutSpacer Spacer+ | LayoutHint LayoutHint+ | LayoutDoNow+ | LayoutDestroy+ | LayoutReplaceSpacer Spacer -- for use by dynSpacerF+ | LayoutReplacePlacer Placer -- for use by dynPlacerF+ deriving (Show)++data LayoutResponse+ = LayoutPlace Rect+ | LayoutSize Size+ | LayoutPos Point -- Position in parent window. Occationally useful.+ deriving Show++layoutMakeVisible r = LayoutMakeVisible r (Nothing,Nothing)++newtype Placer = P Placer1 deriving (Show)++type Placer1 = ([LayoutRequest] -> Placer2)+type Placer2 = (LayoutRequest, Rect -> [Rect])+unP (P p) = p++newtype Spacer = S Spacer1 deriving (Show)+type Spacer1 = (LayoutRequest -> Spacer2)+type Spacer2 = (LayoutRequest, Rect -> Rect)+unS (S s) = s++type LayoutHint = String -- ??++--mapLayoutSize f req@(Layout {minsize=s}) = req{minsize=f s}+mapLayoutSize f = mapAdjLayoutSize f id id++mapAdjLayoutSize f wf hf req@(Layout {minsize=s,wAdj=wa,hAdj=ha}) =+ req{minsize=f s, wAdj=f.wa.wf, hAdj=f.ha.hf}++mapLayoutRefs f req@(Layout{refpoints=rps}) = req{refpoints=map f rps}++flipReq (Layout p fh fv wa ha rps wanted) =+ Layout (flipPoint p) fv fh+ (flipPoint . ha) (flipPoint . wa)+ (map flipPoint rps)+ (fmap flipWanted wanted)++flipWanted (p,s,a) = (flipPoint p,flipPoint s,a)++flipRect (Rect p s) = Rect (flipPoint p) (flipPoint s)+flipPoint (Point x y) = Point y x
+ hsrc/layout/LayoutSP.hs view
@@ -0,0 +1,125 @@+module LayoutSP(layoutMgrF,dynLayoutMgrF) where+--import Command+import Data.List(sortBy)+--import Direction+--import Event+import FRequest+import Fudget+import CompOps((>=^<))+import Geometry(Rect,rR)+import LayoutRequest+import Path(here,showPath{-,Path(..),subPath-})+import Spops+--import EitherUtils(mapMaybe)+--import Utils(number, replace)+import HbcUtils(apFst)+--import Xtypes+--import NonStdTrace(trace)+--import CmdLineEnv(argKey)+import LayoutF(LayoutDirection(..))+import Maptrace(ctrace)++default (Int)++mytrace x = ctrace "layoutftrace" x++layoutMgrF :: Int -> LayoutDirection -> Placer -> F (Path, LayoutMessage) (Path, Rect)+layoutMgrF fudgetCnt dir lter1 = dynLayoutMgrF fudgetCnt dir lter1 >=^< Left++dynLayoutMgrF :: Int -> LayoutDirection -> Placer -> F (Either (Path, LayoutMessage) (Int,Bool)) (Path, Rect)+dynLayoutMgrF fudgetCnt0 dir (P lter1) = F{-ff-} $ getNLimits fudgetCnt0 []+ where+ sortTags = sortBy (order dir)+ where+ order Forward = ofst compare+ order Backward = ofst (flip compare)+ ofst r (x,_) (y,_) = r x y+ getNLimits 0 l = doLter1 Nothing $ sortTags l+ getNLimits n l =+ let same = getNLimits n l in+ getSP $ \msg -> case msg of+ High (Left (path,lmsg)) ->+ case lmsg of+ LayoutRequest lr -> getNLimits (n-1) ((path,lr):l)+ _ -> putSP (Low (path,LCmd lmsg)) same -- !!!+ High (Right (dyn,created)) ->+ if created+ then getNLimits (n+1) l+ else mytrace "fudget destroyed during getNLimits in layoutMgrF" $+ --let l' =+ -- if {-already received layout request from the destoyed fudget-}+ -- then {-remove it from l-}+ -- else l+ -- in getNLimits (n-1) l'+ same+ Low _ -> mytrace "unexpected event in getNLimits in layoutMgrF" $+ same+ doLter1 oplace slims =+ let (req,lter2) = lter1 (map snd slims)+ in mytrace ("req is"++show req) $ + putSP (Low (here,layoutRequestCmd req)) $+ mytrace ("enter loop with "++show (length slims)) $+ loop lter2 slims oplace+ loop lter2 slims oplace =+ let same = loop lter2 slims oplace+ in+ getSP $ \msg -> case msg of+ High (Left (path,LayoutRequest lr)) ->+ case upd slims path lr of+ Nothing -> case (oplace >>= \place ->+ flip lookup (zip (map fst slims) (snd place)) path) of+ Nothing -> same+ Just r -> putSP (High (path,r)) same+ Just slims' -> mytrace ("reenter: "++show (length slims')) $+ doLter1 (fmap (apFst (const $ rR 0 0 0 0)) oplace) slims'+ where upd slims path lr =+ try path Nothing $+ mytrace ("lF: trying subPath"+++ show(path,slims,longesteq path (map fst slims)::Path)) $+ try (longesteq path (map fst slims)) (Just path) Nothing+ where try path orepl fail = u slims []+ where u [] _ = fail+ u (pl@(path',lr'):rest) l = + let nslims p = Just (reverse l ++ ((p,lr):rest)) in+ if path'==path then case orepl of+ Nothing -> {-if lr == lr' then Nothing else -} nslims path+ Just repl -> nslims repl++ else u rest (pl:l)+ High (Left (path,lr)) -> putSP (Low (path,LCmd lr)) same -- !!!+ High (Right (dyn,created)) ->+ if created+ then getNLimits 1 slims+ else mytrace "fudget destroyed in loop in layoutMgrF" $+ -- remove it!+ same+ Low (path,LEvt (LayoutPlace r)) -> mytrace ("Layoutplace "++showPath path++","++show r) $+ case oplace of + Just (r',_) | r == r' -> mytrace ("lF: same rect "++show r) same+ _ -> let rects = lter2 r+ slims' = slims {-map (\((path,Layout s v h),Rect p s') ->+ mytrace (show (showPath path,s,s'))$(path,Layout s' v h)) $ zip slims rects-}+ paths = map fst slims+ crects = zip paths rects {- case oplace of+ Nothing -> zip paths rects+ Just (_,orects) -> + [(path,r) | + (path,r,r') <- zip3 paths rects orects, r /= r']-}+ in --mytrace (show$slims'==slims') $+ putsSP [mytrace ("putsSP "++show (showPath path,r))$High pr | pr@(path,r) <- crects] $+ loop (snd $ lter1 (map snd slims')) slims' (Just (r,rects))+ Low _ -> mytrace "unexpected event in loop in layoutMgrF" $+ same++--{-+--This is a fix for a problem with dynF, I (th) suppose. I think you can fix it in dynF instead.+begineqlen x = eq 0 x where+ eq n (x:xs) (y:ys) | x == y = eq (n+1) xs ys+ eq n _ _ = n++longesteq p1 (p:ps) = le (p1,begineqlen p1 p) ps where+ le (pm,l) [] = pm+ le (pm,l) (p:ps) = let len = begineqlen p1 p+ pl1 = if len > l then (p,len) else (pm,l)+ in le pl1 ps+-- -}
+ hsrc/layout/Layoutspec.hs view
@@ -0,0 +1,60 @@+module Layoutspec(marginHVAlignLs, hvAlignLs, marginLs, sepLs,hBoxLs', vBoxLs',+ placeLs,spaceLs,revLs, permLs, leafLs, layoutF, Layout) where+import AlignP+--import Alignment(Alignment(..))+import Fudget+--import Geometry(Point, Rect, Size(..))+--import LayoutDir(LayoutDir, Orientation)+import LayoutF(LayoutDirection(..), lF)+import LayoutRequest+import Placers+import Spacers+import Utils(oo,unconcat)++data Layout = LeafL | NodeL Placer [Layout] --deriving (Eq, Ord)++layoutF :: Layout -> (F a b) -> F a b+layoutF layout f =+ let (n, lter) = layouter layout+ in lF n Forward lter f++leafLs = LeafL++revLs LeafL = LeafL+revLs (NodeL lter ls') = NodeL (revP lter) ls'++npermLs _ LeafL = LeafL+permLs perm (NodeL lter ls') = NodeL (permuteP perm lter) ls'++modLs ltermod l =+ case l of+ LeafL -> NodeL (ltermod idP) [LeafL]+ NodeL lter ls' -> NodeL (ltermod lter) ls'++placeLs = NodeL+spaceLs = modLs . spacerP++vBoxLs' = placeLs . verticalP'+hBoxLs' = placeLs . horizontalP'++sepLs = spaceLs . sepS+marginLs = spaceLs . marginS+hvAlignLs = oo spaceLs hvAlignS+marginHVAlignLs sep ha va = spaceLs (marginHVAlignS sep ha va)++--layouter :: Layout -> (Int, Placer)+layouter layout =+ case layout of+ LeafL -> (1, idP)+ NodeL lter ls' -> let (ns, lters) = unzip (map layouter ls')+ in (sum ns, combl lter ns lters)++combl rootlter ns nodelters = P $ \ leafreqs ->+ let (nodereqs, noderess) =+ unzip (zipWith unP nodelters (unconcat ns leafreqs))+ (rootreq, rootres) = unP rootlter nodereqs+ leafres rootrect = concatMap apply (zip noderess (rootres rootrect))+ in (rootreq, leafres)++apply (f, x) = f x+
+ hsrc/layout/MatrixP.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE CPP #-}+module MatrixP(matrixP,matrixP') where+import Geometry+import LayoutRequest+import LayoutDir(LayoutDir(..),xc,yc,mkp)+import Spacers(Distance)+import Defaults(defaultSep)+import Data.List(mapAccumL)++#ifndef __HBC__+#define fromInt fromIntegral+#endif++matrixP n = matrixP' n Horizontal defaultSep++matrixP' :: Int -> LayoutDir -> Distance -> Placer+matrixP' count' ld sep = P $ \ requests ->+ let n = length requests+ maxsize = (pMax . (origin:) . map minsize) requests+ rps' = concatMap refpoints requests+ maxh = xc ld maxsize+ maxv = yc ld maxsize+ ncols = count' `min` n+ nrows = (n - 1) `quot` count' + 1+ his = sep * (ncols - 1)+ vis = sep * (nrows - 1)+ h = his + maxh * ncols+ v = vis + maxv * nrows+ mat2 (Rect gotpos gotsize) =+ let x0 = xc ld gotpos+ y0 = yc ld gotpos+ width = xc ld gotsize+ height = yc ld gotsize+ goth,gotv :: Double+ goth = fromInt (width - his) / fromInt ncols+ gotv = fromInt (height - vis) / fromInt nrows+ pl i _ =+ let (x, y) = (i `rem` count', i `quot` count')+ in (i + 1, Rect+ (mkp ld (x0 + truncate (fromInt x * (goth + fromInt sep)))+ (y0 + truncate (fromInt y * (gotv + fromInt sep))))+ (mkp ld (truncate goth)+ (truncate gotv)))+ in snd (mapAccumL pl 0 requests)+ in (refpLayout (mkp ld h v) False False rps', mat2)++#ifdef __NHC__+fromInt = fromIntegral+#endif
+ hsrc/layout/NameLayout.hs view
@@ -0,0 +1,193 @@+module NameLayout(LName(..),placeNL,spaceNL,modNL,marginNL,sepNL,hvAlignNL,marginHVAlignNL,nullNL,hBoxNL,hBoxNL',vBoxNL, vBoxNL',leafNL, NameLayout, nameF,+ listNF, nameLayoutF) where++--import NonStdTrace(trace)+import LayoutRequest+import NullF+import Spops+--import Command+--import Event+import FRequest+--import Xtypes+import EitherUtils(plookup)+import Data.Maybe(fromJust)+import Fudget+import Path+import Geometry+import Placers+import Spacers+--import Message+import ListF+import Loopthrough+import Cont+--import LayoutDir+import AlignP+--import Alignment+import Utils+import Maptrace+import AutoLayout+import ParF++type LName = String+newtype NameLayout = NL (MLNode LName) -- abstract++-- The layout structure datatype+type MLNode a = (Maybe LayoutRequest, LNode a)+data LNode a = + LNode Int Placer (Maybe (Rect -> [Rect])) [MLNode a]+ | LLeaf (LLeaf a) deriving Show++data LLeaf a = Name a | Req LayoutRequest deriving Show++type NPath = [Int]++-----------------------------------------------------------------------------------+-- Exported functions++placeNL :: Placer -> [NameLayout] -> NameLayout+placeNL lter ns = let dns = map deNL ns in+ buildnl $ LNode (length (filter (nothing.fst) dns)) lter Nothing dns++spaceNL :: Spacer -> NameLayout -> NameLayout+spaceNL = modNL . spacerP++modNL :: (Placer -> Placer) -> NameLayout -> NameLayout+modNL ltermod (NL (req,n)) = NL $ case n of+ LNode i lter f ls -> (req,LNode i (ltermod lter) f ls)+ LLeaf l -> + let lter = ltermod idP+ P lter' = lter in + case l of+ Req r -> leafReq $ fst $ lter' $ [r]+ _ -> (Nothing,LNode 1 lter Nothing [(req,n)])++marginNL = spaceNL . marginS+sepNL = spaceNL . sepS++hvAlignNL = spaceNL `oo` hvAlignS+marginHVAlignNL sep ha va = spaceNL (marginHVAlignS sep ha va)++hBoxNL = placeNL $ horizontalP+hBoxNL' d = placeNL $ horizontalP' d+vBoxNL = placeNL $ verticalP+vBoxNL' d = placeNL $ verticalP' d+leafNL name = buildnl $ LLeaf $ Name name+nullNL = NL $ leafReq $ plainLayout (Point 1 1) False False++nameF :: LName -> F a b -> F a b+nameF n = putMessageFu (Low (LCmd (LayoutName n))) . autoLayoutF++-- local++nothing Nothing = True+nothing _ = False++buildnl :: LNode LName -> NameLayout+buildnl x = NL (Nothing,x)+deNL (NL x) = x++leafReq :: LayoutRequest -> MLNode a+leafReq req = (Just req,LLeaf $ Req $ req)++listNF :: (Eq a, Show a) => [(a, F b c)] -> F (a, b) (a, c) +listNF fs = listF [(t, nameF (show t) f) | (t, f) <- fs]++-- The main layout function+nameLayoutF :: NameLayout -> F a b -> F a b+nameLayoutF (NL ltree) (F fsp) =+ let layoutSP =+ getAllPNames (countLNames ltree) [] $ \pnames ->+ let (pathTable, ltree') = rebuildTree pnames [] ltree+ in lSP pathTable ltree'+ lSP pt ltree = + let same = lSP pt ltree in+ getSP $ \msg ->+ case msg of+ -- A message from the fudget+ Left (Low (path, LCmd (LayoutRequest lr))) ->+ ctrace "nameLayoutF" lr $+ let ltree' = updateTree path (pathlookup pt path) ltree lr+ in case ltree' of + (Just lreq, _) -> --trace (show ltree') $+ putSP (Right (Low ([], layoutRequestCmd lreq))) $+ lSP pt ltree'+ _ -> lSP pt ltree'+ Left x -> putSP (Right x) $ same+ -- A message to the fudget+ Right (Low (path, LEvt (LayoutPlace r))) ->+ putsSP (map (Left. Low) $ traverseTree r ltree) $ same+ Right x -> putSP (Left x) $ same+ in parF nullF $ F{-ff-} $ loopThroughRightSP layoutSP fsp+-- fix for autolayout++-----------------------------------------------------------------------------------+-- Local functions++-- Counts the number of named leafs in a layout structure+countLNames :: MLNode a -> Int+countLNames (_, LLeaf (Name _)) = 1+countLNames (_, LLeaf _) = 0+countLNames (_, LNode _ _ _ ns) = sum (map countLNames ns)++-- Traverses the layout structure, returning a mapping from leaf names to paths+getAllPNames :: Int -> [(LName, Path)] -> + Cont (SP (Either (FCommand a) b) c) [(LName,Path)]+getAllPNames 0 pnames c = c pnames+getAllPNames n pnames c =+ waitForSP layoutName $ \pname ->+ getAllPNames (n-1) (pname:pnames) c+ where layoutName (Left (Low (path, LCmd (LayoutName name)))) = + Just(name, path)+ layoutName _ = Nothing++-- Rebuilds the layout structure. +-- Returns also a mapping from ordinary paths to number paths.+rebuildTree :: [(LName, Path)] -> NPath -> MLNode LName ->+ ([(Path, NPath)], MLNode Path)+rebuildTree pnames np (_, LLeaf (Name name)) = + case lookup name pnames of+ Nothing -> error ("Couldn't find name "++ show name ++ + " in (name, path) table.")+ Just path -> ([(path, np)], (Nothing, LLeaf $ Name path))+rebuildTree pnames np (_, (LLeaf (Req r))) = ([],(Just r, (LLeaf (Req r))))+rebuildTree pnames np (_, LNode c lter Nothing ns) =+ (concat ts, (Nothing, LNode c lter Nothing ns'))+ where (ts, ns') = unzip (zipWith (rebuildTree pnames) + (map ((np++) . (:[])) [1..]) ns)+++-- Inserts layout requests in the layout structure.+-- Trigged by some fudget emitting a layout request+updateTree :: Path -> + Maybe NPath -> + MLNode Path -> + LayoutRequest -> + MLNode Path+updateTree path Nothing _ lr = + error ("Hmmm. Couldn't find path " ++ show path +++ "in updateTree\nSomeone has probably forgotten to name a fudget.")+updateTree path (Just npath) lo lr = snd $ upd npath lo lr+ where upd _ (mlr, LLeaf (Name p)) lr = + (nothing mlr, (Just lr, LLeaf (Name path)))+ upd (n:np) (mlr, LNode c lter@(P lter') mr ns) lr =+ let (before, this:after) = splitAt (n-1) ns+ (ready, child) = upd np this lr+ c' = if ready then max (c-1) 0 else c+ ns' = before ++ [child] ++ after+ in if c' == 0 then+ let (lreq, rectf) = lter' (map (fromJust . fst) ns')+ in (nothing mlr, + (Just lreq, LNode c' lter (Just rectf) ns'))+ else+ (False, (Nothing, LNode c' lter mr ns'))+ upd _ othernode _ = (False,othernode)++-- We have got a rectangle. Emit commands to all subfudgets saying how large+-- they should be. +traverseTree :: Rect -> MLNode Path -> [TEvent]+traverseTree r (_, LLeaf (Name path)) = [(path, LEvt $ LayoutPlace r)]+traverseTree r (_, LLeaf _) = []+traverseTree r (_, LNode _ _ (Just rectf) ns) =+ concat (zipWith traverseTree (rectf r) ns) ++pathlookup table p = plookup (flip subPath p) table
+ hsrc/layout/ParagraphP.hs view
@@ -0,0 +1,51 @@+module ParagraphP where+import LayoutRequest+import Geometry+--import ListUtil(chopList)+import HbcUtils(apFst,chopList)+import Defaults(defaultSep)+import Placers(verticalP')+import Spacers() -- synonym Distance, for hbc+import HorizontalAlignP(horizontalAlignP')+--import Maptrace(ctrace)+import Utils(oo)+import CmdLineEnv(argReadKey)+--import IntMemo++paragraphP = paragraphP' defaultSep+paragraphP' = paragraphP'' horizontalAlignP'++paragraphP'' :: (Int->Placer) -> Size -> Placer+paragraphP'' horizP' (Point hsep vsep) = P paP+ where+ paP reqs = ({-ctrace "paraReq" (req, wAdj req $ xcoord $ minsize req)-} req,paraPlacer2)+ where+ width0 = argReadKey "paragraph-width" 600 :: Int+ req = (paraReq width0) { wAdj=minsize . paraReq }+ paraReq width = fst (paraP width)+ paraPlacer2 rect@(Rect _ (Point w _)) =+ --ctrace "paraPlacer2" rect $+ snd (paraP w) rect+ paraP = {-memoInt-} paraP' -- memoInt slows down and consumes a lot of heap+ paraP' width = (vreq,placer2)+ where+ (vreq,vplacer2) = unP (verticalP' vsep) hreqs+ placer2 = concat . zipWith id hplacers2 . vplacer2+ (hreqs,hplacers2) =+ unzip . map (unP (horizP' hsep)) . breakLines width $ reqs++ breakLines w rs = {-ctrace "breakLines" (w,map length rss)-} rss+ where rss = breakLines' w rs++ breakLines' = chopList . (atLeastOne `oo` takeLine)+ takeLine wremain reqs = + case reqs of+ [] -> ([],[])+ r:rs -> --ctrace "takeLine" (wremain,w) $+ if wremain<w+ then ([],reqs)+ else apFst (r:) (takeLine (wremain-w-hsep) rs)+ where w=xcoord (minsize r)++atLeastOne ([],x:xs) = ([x],xs)+atLeastOne xsys = xsys
+ hsrc/layout/Placer.hs view
@@ -0,0 +1,34 @@+module Placer where+import Fudget+import LayoutRequest+import FRequest+--import Geometry(Point, Size(..),Rect)+import NullF(putMessageFu)+--import Command+--import Defaults(defaultSep)+import Placers(horizontalP,verticalP)+import MatrixP(matrixP)+import Spacers(spacerP)+import TableP(tableP)+import AlignP(revP)+import AutoPlacer(autoP)++--import AlignP+--import Alignment++placerF :: Placer -> F a b -> F a b+placerF placer = putMessageFu (Low (LCmd (LayoutPlacer placer)))++spacerF :: Spacer -> F a b -> F a b+spacerF spacer = putMessageFu (Low (LCmd (LayoutSpacer spacer)))++spacer1F s = placerF (s `spacerP` autoP)++hBoxF = placerF horizontalP+vBoxF = placerF verticalP++revHBoxF = placerF (revP horizontalP)+revVBoxF = placerF (revP verticalP)++matrixF = placerF . matrixP+tableF = placerF . tableP
+ hsrc/layout/Placers.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE CPP #-}+module Placers(linearP, verticalP, horizontalP, horizontalP', verticalP') where+import Geometry+import LayoutDir+import LayoutRequest+import Spacers(Distance(..))+import Data.List(mapAccumL)+import Utils(part)+import Defaults(defaultSep)+import Maptrace(ctrace) -- debugging+--import NonStdTrace(trace)+import IntMemo++#ifndef __HBC__+#define fromInt fromIntegral+#endif+ +horizontalP = horizontalP' defaultSep+verticalP = verticalP' defaultSep++horizontalP' = linearP Horizontal+verticalP' = linearP Vertical++linearP :: LayoutDir -> Distance -> Placer+linearP ld sep = P $ linearP' ld sep++linearP' ld sep [] = ctrace "linearP" ("linearP "++show ld++" []") $+ (plainLayout 1 (ld==Horizontal) (ld==Vertical),\ r -> [])+linearP' ld sep requests =+ let minsizes = map minsize requests+ totis = sep * (max 0 (length requests - 1))+ h = max 0 (h'-sep) -- totis + sum (map (xc ld) minsizes)+ (h',rpss) = mapAccumL adjust 0 requests+ where adjust x (Layout {minsize=rsz,refpoints=rps}) =+ (x+rw+sep,map adj1 rps)+ where adj1 p = mkp ld (x+xc ld p) (yc ld p)+ rw = xc ld rsz+ v = (maximum . (0:) . map (yc ld)) minsizes+ line2 gotr =+ let goth = (fromInt . xc ld . rectsize) gotr - fromInt totis+ gotv = (yc ld . rectsize) gotr+ startx = (fromInt . xc ld . rectpos) gotr+ starty = (yc ld . rectpos) gotr+#if 0+-- Old solution+ requests' = requests+#else+-- New, experimental solution:+ requests' = map req' requests+ where+ req' req = req {minsize=adj gotv}+ where adj=orthogonal ld (wAdj req) (hAdj req)+#endif+ (fih, flh) = part (fixh ld) requests'+ fixedh' =+ (fromInt . sum . map (xc ld . minsize)) fih+ floath = (fromInt . sum . map (xc ld . minsize)) flh+ fixedR = if floath > 0.0 then 1.0 else goth / fixedh'+ floatR =+ if floath == 0.0 then 1.0 else (goth - fixedh') / floath+ rR' req = if fixh ld req then fixedR else floatR+ pl x req =+ let width = (fromInt . xc ld . minsize) req * rR' req+ in (x + width + fromInt sep,+ Rect (mkp ld (truncate x) starty)+ (mkp ld (truncate width) gotv))+ in snd (mapAccumL pl startx requests')+ (fh',fv') = vswap ld (allf and fixh,allf or fixv)+ rps' = concat rpss --concatMap refpoints requests+ allf conn fix = conn (map (fix ld) requests)+ req0 = refpLayout (mkp ld h v) fh' fv' rps'+ req =+ case ld of+ Horizontal -> req0 { hAdj=memoInt ha } + where ha h = Point (totis+sum ws) h+ where ws = map (xcoord . flip hAdj h) requests+ Vertical -> req0 { wAdj=memoInt wa } + where wa w = Point w (totis+sum hs)+ where hs = map (ycoord . flip wAdj w) requests+ in (req,line2)++#ifdef __NHC__+fromInt = fromIntegral+#endif
+ hsrc/layout/Placers2.hs view
@@ -0,0 +1,72 @@+module Placers2(overlayP,+ verticalLeftP,verticalLeftP',+ horizontalCenterP,horizontalCenterP') where+import LayoutRequest+import Spacers(Distance(..))+import Geometry+import Defaults(defaultSep)+import Data.List(mapAccumL)+import IntMemo++overlayP :: Placer+overlayP = P overlayP'+ where+ overlayP' ls = (req,placer2)+ where+ ss = map minsize ls+ rps = concatMap refpoints ls+ wa w = Point w (maximum (1:map (ycoord . flip wAdj w) ls))+ ha h = Point (maximum (1:map (xcoord . flip hAdj h) ls)) h+ req = (refpLayout (pMax ss) (any fixedh ls) (any fixedv ls) rps) {wAdj=memoInt wa,hAdj=memoInt ha}+ placer2 r = [r | _ <- ls]++verticalLeftP = verticalLeftP' defaultSep++verticalLeftP' :: Distance -> Placer +verticalLeftP' sep = P vlP+ where+ vlP ls = (req,placer2)+ where+ req = (refpLayout (Point w h) False (and fvs) (concat rpss)) {wAdj=memoInt wa}+ wa aw = Point aw (sum hs+totsep)+ where hs = [ycoord (wAdj (min aw w)) | Layout{minsize=Point w _,wAdj=wAdj}<-ls]+ totsep = sep*(length ls-1)+ (ss,fhs,fvs) = unzipsfhv ls+ (ws,hs) = unzip [(w,h) | Point w h <- ss]+ w = maximum (1:ws)+ h = max 1 (h'-sep) -- (sum hs + sep*(length hs-1))+ (h',rpss) = mapAccumL adjust 0 ls+ where adjust y (Layout {minsize=Point _ rh,refpoints=rps}) =+ (y+rh+sep,map adj1 rps)+ where adj1 (Point rx ry) = Point rx (y+ry)+ placer2 (Rect (Point x0 y0) _) = placer2' hs ss y0+ where placer2' (h:hs) (s:ss) y =+ Rect (Point x0 y) s:placer2' hs ss (y+sep+h)+ placer2' _ _ _ = []++horizontalCenterP = horizontalCenterP' defaultSep++horizontalCenterP' :: Distance -> Placer +horizontalCenterP' sep = P hcP+ where+ hcP ls = (req,placer2)+ where+ req = (refpLayout (Point w h) (and fhs) False (concat rpss)) {hAdj=memoInt ha}+ (ss,fhs,fvs) = unzipsfhv ls+ ha ah = Point (sum ws+totsep) ah+ where ws = [xcoord (hAdj (min ah h)) | Layout{minsize=Point _ h,hAdj=hAdj}<-ls]+ totsep = sep*(length ls-1)+ (ws,hs) = unzip [(w,h) | Point w h <- ss]+ w = max 1 w' --(sum ws + sep*(length ws-1))+ h = maximum (1:hs)+ (w',rpss) = mapAccumL adjust 0 ls+ where adjust x (Layout {minsize=Point rw rh,refpoints=rps}) =+ (x+rw+sep,map adj1 rps)+ where adj1 (Point rx ry) = Point (x+rx) (ry+(h-rh) `div` 2)+ placer2 (Rect (Point x0 y0) (Point _ ah)) = placer2' ws hs ss x0+ where placer2' (w:ws) (h:hs) (s:ss) x =+ Rect (Point x (y0+(ah-h) `div` 2)) s:placer2' ws hs ss (x+sep+w)+ placer2' _ _ _ _ = []++unzipsfhv ls =+ unzip3 [(s,fh,fv) | Layout {minsize=s,fixedh=fh,fixedv=fv} <- ls]
+ hsrc/layout/Sizing.hs view
@@ -0,0 +1,14 @@+module Sizing where+import Geometry(pmax)++data Sizing+ = Static | Growing | Dynamic+-- | StaticDebug+ deriving (Eq,Show,Read)++newSize sizing curSize reqSize =+ case sizing of+ Static -> curSize+-- StaticDebug -> curSize+ Growing -> pmax curSize reqSize+ Dynamic -> reqSize
+ hsrc/layout/SizingF.hs view
@@ -0,0 +1,47 @@+module SizingF(sizingF) where+import LoopLow(loopThroughLowF)+import Spops(mapAccumlSP)+import LayoutRequest+import FRequest+--import Event+--imaport Command+import Geometry(Rect(..))+--import Fudget+import Sizing(newSize)+--import Maptrace(ctrace) -- debugging++sizingF = loopThroughLowF . sizingSP++sizingSP sizing = mapAccumlSP sizingT state0+ where+ --tr = if sizing==StaticDebug then ctrace "dsizing" else const id+ state0 = Nothing++ sizingT Nothing msg =+ case msg of+ Left (path,LCmd (LayoutRequest (Layout size' fh' fv' wa' ha' rps' wanted'))) ->+ (Just (Nothing,size',fh',fv'{-,rps'-}),msg)+ _ -> (Nothing,msg)+ sizingT s@(Just state@(optpos,size,fh,fv{-,rps-})) msg =+ case msg of+ Left (path,LCmd (LayoutRequest r@(Layout size' fh' fv' wa' ha' rps' wanted'))) ->+ case (state' == state,optpos) of+ (True,Just pos) -> (s,Right (path,LEvt (LayoutPlace (Rect pos size))))+ _ -> --tr (show (state,state'))+ (Just state',msg')+ where size'' = newSize sizing size size'+ state' = (optpos,size'',fh',fv'{-,rps'-})+ msg' = Left (path,layoutRequestCmd r{minsize=size''})+ Right (_,LEvt (LayoutPlace rect@(Rect pos' size'))) -> (Just (Just pos',size',fh,fv{-,rps-}),msg)+ _ -> (s,msg)++{-+sizingF prevents a fudget from outputting a layout request that doesn't change+anything. The sizing parameter also restricts what kind of resizing is allowed.++sizingF assumes that the argument fudget has only ONE layout box and will+confuse things if layout requests are received from several different paths.++sizingF is used in autoLayoutF and there is probably no reason to use it in+other places (i.e., use autoLayoutF' if there seems to be a need for sizingF).+-}
+ hsrc/layout/Spacer.hs view
@@ -0,0 +1,17 @@+-- replaces modules AlignF and SepF+module Spacer(module Spacer,Distance(..)) where+--import LayoutRequest+import Spacers+import Placer(spacer1F)++marginHVAlignF m h v = spacer1F $ marginHVAlignS m h v++alignF uladd bradd halign valign =+ spacer1F (hvMarginS uladd bradd `compS` hvAlignS halign valign)++layoutModifierF = spacer1F . layoutModifierS++noStretchF fh fv = spacer1F (noStretchS fh fv)++sepF = spacer1F . sepS+marginF = spacer1F . marginS
+ hsrc/layout/Spacers.hs view
@@ -0,0 +1,112 @@+module Spacers where+import LayoutRequest+import Geometry+import Utils(mapPair)+import Alignment++---- Spacer types++type Distance = Int+++---- Primitive Spacers++-- Fixed margins++hMarginS, vMarginS :: Distance -> Distance -> Spacer+hMarginS dLeft dRight = hvMarginS (pP dLeft 0) (pP dRight 0)+vMarginS dTop dBottom = hvMarginS (pP 0 dTop) (pP 0 dBottom)++hvMarginS :: Size -> Size -> Spacer+hvMarginS dUpperLeft dBottomRight = S $ \ req ->+ let growth = dUpperLeft + dBottomRight+ in (mapLayoutRefs (+dUpperLeft) $+ mapAdjLayoutSize (+growth) (+(-xcoord growth)) (+(-ycoord growth)) req,+ center' dUpperLeft growth)++center p (Rect r s) = Rect (r+p) (s-(p+p))+center' offset shrink (Rect r s) = Rect (r+offset) (s-shrink)++sepS :: Size -> Spacer+sepS s = hvMarginS s s++marginS :: Distance -> Spacer+marginS d = sepS (diag d)++-- Flexible margins++leftS = hAlignS aLeft+hCenterS = hAlignS aCenter+rightS = hAlignS aRight++vAlignS = flipS . hAlignS+topS = flipS leftS+vCenterS = flipS hCenterS+bottomS = flipS rightS++hvAlignS hpos vpos = hAlignS hpos `compS` vAlignS vpos+centerS = vCenterS `compS` hCenterS++hAlignS :: Alignment -> Spacer+hAlignS hpos = S $ \ (Layout size@(Point rw _) fh fv wa ha rps wanted) ->+ let+ wa' w = wa (min rw w)+ hAlignR (Rect p@(Point x y) s@(Point aw ah)) =+ Rect (pP (x+spaceLeft) y) (pP rw' ah)+ where+ space = aw-rw'+ spaceLeft = scale hpos space+ rw' = min rw aw+ rw = xcoord (ha ah)+ in (Layout size False{-fh-} fv wa' ha rps wanted,hAlignR)++marginHVAlignS sep halign valign = marginS sep `compS` hvAlignS halign valign++--- Spacer operations++spacerP :: Spacer -> Placer -> Placer+spacerP (S spacer) (P placer) = P $ \ reqs ->+ let (req',placer2) = placer reqs+ (req'',spacer2) = spacer req'+ in (req'',placer2.spacer2)++--flipS :: Spacer -> Spacer+flipS = mapS flipS'+ where+ flipS' spacer = mapPair (flipReq,flipS2) . spacer . flipReq+ flipS2 spacer2 = flipRect.spacer2.flipRect++mapS f (S sp) = S (f sp)++--idS :: Spacer+idS = S $ \ req -> (req,id)++compS :: Spacer -> Spacer -> Spacer+compS (S spa) (S spb) = S $ \ req ->+ let (req',spb2) = spb req+ (req'',spa2) = spa req'+ in (req'',spb2.spa2)+++sizeS,maxSizeS,minSizeS :: Size -> Spacer+sizeS = resizeS . const+maxSizeS = resizeS . pmin+minSizeS = resizeS . pmax++resizeS :: (Size->Size) -> Spacer+resizeS = layoutModifierS . mapLayoutSize+-- The above and below lines now mean the same+--resizeS f = layoutModifierS (mapAdjLayoutSize f id id)++noStretchS :: Bool -> Bool -> Spacer+noStretchS fh fv = layoutModifierS lf+ where lf req = req { fixedh=fh, fixedv=fv }+--noStretchS fh fv req = (mapLayout lf req ,id)+-- where lf size _ _ wa ha rps = Layout size fh fv wa ha rps++mapLayout f req =+ case req of+ Layout size fh fv wa ha rps wanted -> f size fh fv wa ha rps wanted++--layoutModifierS :: (LayoutRequest -> LayoutRequest) -> Spacer+layoutModifierS lf = S $ \ req -> (lf req,id)
+ hsrc/layout/TableP.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE CPP #-}+module TableP(tableP,tableP') where+import Geometry(Point(..), Rect(..), rR, xcoord, ycoord)+import LayoutDir(LayoutDir(..), vswap)+import LayoutRequest+import Spacers(Distance(..))+import HbcUtils(chopList)+import Data.List(transpose,mapAccumL)+import Utils(lhead)+import Defaults(defaultSep)+import IntMemo++import Maptrace(ctrace)+tr x = ctrace "tableP" x x++tableP n = tableP' n Horizontal defaultSep++tableP' :: Int -> LayoutDir -> Distance -> Placer+tableP' count' ld sep = P $ \ requests ->+ let --sizes = map minsize requests+ (rows, columns) =+ let hmatrix = chopList (splitAt count') requests+ vmatrix = transpose hmatrix+ in vswap ld (hmatrix, vmatrix)+ nrows = length rows+ ncols = length columns+ vsep = (nrows - 1) * sep+ hsep = (ncols - 1) * sep+ rowhs = map (maximum . (0:) . map (ycoord.minsize)) rows+ colws = map (maximum . (0:) . map (xcoord.minsize)) columns+ --rowfixws = map (and . map fixedh) rows+ rowfixhs = map (or . map fixedv) rows+ colfixws = map (or . map fixedh) columns+ --colfixhs = map (and . map fixedv) columns+ h = sum rowhs+ w = sum colws+ toth = h + vsep+ totw = w + hsep+ tot = Point totw toth+ totfh = and rowfixhs+ totfw = and colfixws+ rps = concatMap (\(r,p)->map (p+) (refpoints r)) (zip requests cellps)+ where cellps = [Point x y | y<-place 0 sep rowhs,x<-place 0 sep colws]+-- where cellps = [Point x y | y<-0:init rowhs,x<-0:init colws] --sep??+ table2 (Rect (Point x0 y0) got@(Point width height)) =+ let --Point extraw extrah = (got `psub` tot) --`pmax` origin+#if 0+-- old solution+ rowhs' = arowhs height --pad flexh extrah rowhs rowfixhs+ colws' = acolws width --pad flexw extraw colws colfixws+#else+-- new solution+ ((colws',rowhs'),(w',h')) =+ if width<=totw -- hmm...+ then (adjrowhs width,(width,sum rowhs'+vsep))+ else (adjcolws height,(sum colws'+hsep,height))+#endif+ colws'' = adjsizes (tr (width-w')) colws' colfixws+ rowhs'' = adjsizes (tr (height-h')) rowhs' rowfixhs+ xs = place x0 sep colws''+ ys = place y0 sep rowhs''+ placedrows =+ [[rR x y w h|(x,w)<-zip xs colws'']|(y,h)<-zip ys rowhs'']+{- old+ w' = sum colws'+ h' = sum rowhs'+ hscale,vscale :: Double+ hscale = fromInt (width - hsep) / fromInt w'+ vscale = fromInt (height - vsep) / fromInt h'+ placecols x y h' [] = []+ placecols x y h' (w' : ws) =+ let w'' = scale hscale w'+ in rR x y w'' h' : placecols (x + w'' + sep) y h' ws+ placerows y [] = []+ placerows y (h' : hs) =+ let h'' = scale vscale h'+ in placecols x0 y h'' colws' : placerows (y + h'' + sep) hs+ placedrows = placerows y0 rowhs'+-}++ rectss =+ case ld of+ Horizontal -> placedrows+ Vertical -> transpose placedrows+ rects = concat rectss+ in (if length rects<length requests + then ctrace "tableP" (length requests,length rects)+ else id) $+ lhead requests rects++ acolws aw = adjsizes (aw-totw) colws colfixws+ arowhs ah = adjsizes (ah-toth) rowhs rowfixhs++ adjsizes extra ss fixs = pad flex extra ss fixs+ where+ flex = sum [s | (s,fixed) <-zip ss fixs, not fixed]++ pad _ 0 ws _ = ws+ pad 0 extra ws _ = ws+ pad flex extra (w:ws) (fixed:fs) =+ if fixed+ then w:pad flex extra ws fs+ else let e = (extra*w `quot` flex) `max` (-w)+ in w+e:pad (flex-w) (extra-e) ws fs+ pad _ _ _ _ = []++ adjrowhs = memoInt adjrowhs'+ adjrowhs' w = (colws,map maximum (transpose colhs))+ where colhs = [map (ycoord . flip wAdj colw) column |+ (colw,column) <- zip colws columns]+ colws = acolws w++ adjcolws = memoInt adjcolws'+ adjcolws' h = (map maximum (transpose rowws),rowhs)+ where rowws = [map (xcoord . flip hAdj rowh) row |+ (rowh,row) <- zip rowhs rows]+ rowhs = arowhs h++ wa w = ctrace "tablePwa" s s+ where s = Point w (vsep+h)+ h = sum (snd (adjrowhs w))+{- --old:+ h = sum . map maximum . transpose $ colhs+ colhs = [map (ycoord . flip wAdj colw) col |+ (colw,col) <- zip (acolws w) columns]+-}+ ha h = Point (hsep+w) h+ where w = sum (fst (adjcolws h))+{- --old:+ w = sum . map maximum . transpose $ rowws+ rowws = [map (xcoord . flip hAdj rowh) row |+ (rowh,row) <- zip (arowhs h) rows]+-}+ in ((refpLayout tot totfw totfh rps){wAdj=memoInt wa,hAdj=memoInt ha}, table2)++place pos0 sep = snd . mapAccumL f pos0+ where f pos size = (pos+size+sep,pos)++#ifdef __NHC__+fromInt = fromIntegral+#endif
+ hsrc/layout/TryLayout.hs view
@@ -0,0 +1,16 @@+module TryLayout(tryLayoutK) where++import FRequest+--import Message+import Cont+import LayoutRequest+--import Command+--import Fudget+--import Xtypes+--import Event++tryLayoutK lreq =+ cmdContK (layoutRequestCmd lreq) $ \r ->+ case r of+ LEvt (LayoutSize s) -> Just s+ _ -> Nothing
+ hsrc/layout/UserLayoutF.hs view
@@ -0,0 +1,26 @@+module UserLayoutF where+import Fudget+import FRequest+--import Command+--import Event+import Geometry(Rect)+--import CompOps+import Spops(concatMapSP)+import CompSP(preMapSP,serCompSP)+import LayoutRequest+--import Message(Message(..))++userLayoutF :: F a b -> F (Either (Path,Rect) a) (Either (Path,LayoutMessage) b)+userLayoutF (F fud) = F{-ff-} (concatMapSP post `serCompSP` fud `preMapSP` pre)+ where+ pre msg =+ case msg of+ High (Right x) -> High x+ High (Left (p,place)) -> Low (p,LEvt (LayoutPlace place))+ Low pev -> Low pev+ post msg =+ case msg of+ High x -> [High (Right x)]+ Low (p,LCmd req) -> [High (Left (p,req))]+ --Low d@(p,XCmd DestroyWindow) -> [Low d] --,High (Left (p,LayoutDestroy))]+ Low pcmd -> [Low pcmd]
+ hsrc/lowlevel/Cont.hs view
@@ -0,0 +1,97 @@+module Cont(Cont(..),conts, tryM, cmdContF, cmdContK, cmdContK', waitForSP, waitForK, waitForF, waitForFu, cmdContSP,tryGet,getLeftSP,getRightSP,fContWrap,kContWrap,dropSP,contMap) where+--import Direction+import Fudget+import Message(stripHigh, stripLow, aLow) --Message(..),+import Path(here)+--import SP+import Spops+import StreamProcIO+import EitherUtils(stripLeft,stripRight)++cmdContSP :: a -> (b -> Maybe c) -> Cont (SP b a) c+cmdContSP cmd expected process =+ putsSP [cmd] (waitForSP expected process)++waitForSP expected process =+ let contSP pending =+ getSP (\msg ->+ case expected msg of+ Just answer -> startupSP (reverse pending) (process answer)+ Nothing -> contSP (msg : pending))+ in contSP []++waitForK expected = kContWrap (waitForSP expected)++waitForF :: (a -> Maybe b) -> Cont (F a c) b+waitForF expected = fContWrap (waitForSP expectHigh)+ where expectHigh msg = stripHigh msg >>= expected++waitForFu :: (KEvent hi -> Maybe ans) -> Cont (F hi ho) ans+waitForFu expected = fContWrap (waitForSP expectk)+ where expectk = expected . aLow snd++getLeftSP = waitForSP stripLeft+getRightSP = waitForSP stripRight++waitForLow expected = waitForSP expectLow+ where expectLow msg = stripLow msg >>= expected++cmdContLow cmd expected = putSP (Low cmd) . waitForLow expected++{- old:+cmdContLow cmd exp' =+ cmdContSP (Low cmd)+ (\msg ->+ case msg of+ Low ev -> exp' ev+ _ -> Nothing)+-}++cmdContK :: FRequest -> (FResponse -> Maybe a) -> Cont (K b c) a+cmdContK xcmd expected = kContWrap (cmdContLow xcmd expected)++cmdContK' msg expected = kContWrap (cmdContSP msg expected)++cmdContF :: FRequest -> (FResponse -> Maybe a) -> Cont (F b c) a+cmdContF cmd exp' =+ fContWrap $+ cmdContLow (here, cmd)+ (\tev ->+ case tev of+ (t, ev) | t == here -> exp' ev+ _ -> Nothing)++conts :: (a -> Cont c b) -> [a] -> Cont c [b]+conts g sl c =+ let co al [] = c (reverse al)+ co al (s : sl') = g s (\a -> co (a : al) sl')+ in co [] sl++tryM :: Cont c (Maybe a) -> c -> Cont c a+tryM e errc c = e $ \ov ->+ case ov of+ Nothing -> errc+ Just v -> c v++tryGet :: Cont c (Maybe a) -> (Cont c a) -> Cont c a+tryGet e errc c = tryM e (errc c) c++dropSP expected c = dropit where+ dropit =+ getSP $ \msg ->+ case expected msg of+ Just m -> c m+ Nothing -> dropit++contMap op = m+ where m = get $ \ x -> op x $ \ y -> put y $ m+-- or: where m = get $ flip op $ flip put m+++fContWrap :: Cont (FSP hi ho) a -> Cont (F hi ho) a+fContWrap waitsp = F{-ff-} . waitsp . fContSP+ where fContSP contF x = case contF x of F sp -> sp++kContWrap :: Cont (KSP hi ho) a -> Cont (K hi ho) a+kContWrap waitsp = K{-kk-} . waitsp . kContSP+ where kContSP contK x = case contK x of K sp -> sp
+ hsrc/lowlevel/Display.hs view
@@ -0,0 +1,17 @@+module Display(openDisplay) where+import Command+import Event+--import Font(FontStruct)+--import Fudget+--import Geometry(Line, Point, Rect, Size(..))+--import LayoutRequest(LayoutRequest)+import Xrequest+--import Xtypes++-- DECONSTR :: (a<->b) -> b -> (Maybe a) +openDisplay name =+ xrequestF (OpenDisplay name)+ (let e (DisplayOpened a) = Just a+ e _ = Nothing+ in e)+
+ hsrc/lowlevel/FudgetIO.hs view
@@ -0,0 +1,32 @@+module FudgetIO where+import Fudget+import EitherUtils(Cont(..))+import Message(stripLow,stripHigh)++{-+The purpose of the FudgetIO class is to allow the many IO operations that+can be performed from both fudgets and fudget kernels, e.g., createGC,+loadQueryFont and allocNamedColor, to use one overloaded name instead of+two separate names.+-}++class FudgetIO f where+ waitForMsg :: (KEvent hi -> Maybe ans) -> Cont (f hi ho) ans+ putMsg :: KCommand ho -> f hi ho -> f hi ho++ -- Less useful methods:+ --nullMsg :: f hi ho -- name ?!+ --getMsg :: (KEvent hi -> f hi ho) -> f hi ho++putMsgs msgs k = foldr putMsg k msgs+putHigh x = (putMsg . High) x+putLow x = (putMsg . Low) x+putLows lows k = foldr putLow k lows++getHigh x = waitForMsg stripHigh x+getLow x = waitForMsg stripLow x++cmdContMsg msg expected = putMsg msg . waitForMsg expected++cmdContLow cmd expected = cmdContMsg (Low cmd) expectLow+ where expectLow msg = stripLow msg >>= expected
+ hsrc/lowlevel/Srequest.hs view
@@ -0,0 +1,48 @@+module Srequest(select,sIOsucc,sIOstr,sIOerr,sIO,Cont(..)) where+import FRequest+import FudgetIO+import EitherUtils(Cont(..))+--import NullF(F,K)+import DialogueIO hiding (IOError) -- Select+import ShowFailure++sIOsucc sreq cont =+ socketIO sreq sFail $ \ r ->+ case r of+ Left Success -> cont+ Left r -> error ("sIOsucc: Expected Success, but got "++show r)+ Right r -> error ("sIOsucc: Expected Success, but got "++show r)++sIO sreq = sIOerr sreq sFail++sIOerr sreq fcont rcont =+ socketIO sreq fcont $ \ r ->+ case r of+ Right sr -> rcont sr+ Left dr -> error ("Socket IO: expected a SocketResponse, but got "++show dr)++sIOstr sreq cont =+ socketIO sreq sFail $ \ r ->+ case r of+ Left (Str s) -> cont s+ Left r -> error ("sIOsucc: Expected Str, but got "++show r)+ Right r -> error ("sIOsucc: Expected Str, but got "++show r)+ +---++sFail f = error ("Socket IO error: "++showFailure f)++socketIO sreq econt scont =+ cmdContLow (SReq sreq) expect $ either econt scont+ where expect msg =+ case msg of+ SResp sr -> Just (Right (Right sr))+ DResp (Failure f) -> Just (Left f)+ DResp r -> Just (Right (Left r))+ _ -> Nothing++----++select ds = putLow . DReq . Select $ ds+ -- no response from Select+-- eta expanded because of the monomorphism restriction
+ hsrc/lowlevel/TagEvents.hs view
@@ -0,0 +1,180 @@+{-# LANGUAGE CPP #-}+module TagEvents(tagEventsSP) where+import Command+import CompSP(preMapSP,serCompSP)+import SpEither(mapFilterSP)+import Cont(cmdContSP)+import CmdLineEnv(argFlag)+--import Direction+import Event+--import Font(FontStruct)+import Fudget+import FRequest+--import Geometry(Line, Point, Rect, Size(..))+import IOUtil(getEnvi)+--import LayoutRequest(LayoutRequest)+import Loopthrough+import Message(stripLow) --Message(..),+import Path+import WindowF(autumnize)+import ShowCommandF+import Sockets+import Spops+import Tables+--import Version+import Xtypes+--import Maptrace+--import EitherUtils+import Data.Maybe(isNothing)+import ShowFailure+import DialogueIO+import Prelude hiding (IOError)++--mtrace = ctrace "tagEvents"+mtrace x y = y++tagEventsSP :: F i o -> SP (Path, Response) (Path, Request)+tagEventsSP mainF =+ loopThroughRightSP+ tagEventsCtrlSP+ (mapFilterSP stripLow `serCompSP` mainFSP `preMapSP` Low)+ where+ F mainFSP = traceit mainF++openDisplay' cont =+ if isNothing (getEnvi "DISPLAY")+ then cont faildisp+ else+ cmdContSP (tox $ XRequest (noDisplay, noWindow, OpenDisplay ""))+ (\e ->+ case e of+ Right (_, XResponse (DisplayOpened d)) -> Just d+ Right (_, Failure f) -> error ("Cannot open the display (the program is probably not linked with the X routines): "++showFailure f)+ _ -> Nothing)+ (\disp ->+ if disp == Display 0 then+ error "Cannot open display"+ else+ putSP (tox $ Select [DisplayDe disp]) $ cont disp)+ where faildisp = error "the environment variable DISPLAY is not set!"+ tox x = Right (here,x)++tagEventsCtrlSP::+ SP (Either TCommand (Path,Response)) (Either TEvent (Path,Request))+tagEventsCtrlSP =+ openDisplay' tagEventsCtrlSP'+ where+ tagEventsCtrlSP' disp =+ tagSP noSel Nothing path2wid0 wid2path0+ where+ noSel = here+ tagSP selp grabpath path2wid wid2path =+ let same = tagSP selp grabpath path2wid wid2path+ tagSPs = tagSP selp+ tagSPns s = tagSP s grabpath path2wid wid2path+ in getSP $ \msg -> case msg of+ Left (path', cmd) ->+ let newwindow path'' wid = + putSP (Left (path'', XResp (WindowCreated wid))) $+ tagAdd path'' wid+ tox xc = Right (path',xc)+ convertcmd = convert (lookupWid path2wid path')+ convert w cmd = putSP (tox (XCommand (disp, w, cmd)))+ tagAdd p w = tagSPs grabpath (updateWid path2wid p w) + (updatePath wid2path w p)+ in case cmd of+ XCmd xcmd@(SetSelectionOwner s atom) ->+ -- currently, different selections are not distinguished+ convertcmd xcmd $ + (if s && selp /= noSel && path' /= selp then + putSP (Left (selp,XEvt (SelectionClear atom))) else id) $+ tagSPns (if s then path' else noSel)+ XCmd (ReparentToMe rchild w) -> + -- lookup w in table, change path to rchild, emit reparent cmd+ -- TODO: change subpaths too!+ let npath' = newChildPath path' rchild+ npath = autumnize npath' -- used in repTest (?)+ wpath = lookupPath wid2path w+ opath = autumnize wpath+ nparent = lookupWid path2wid path'+ npath2wid = moveWids path2wid opath npath+ nwid2path = movePaths wid2path opath npath+ in convert w (ReparentWindow nparent) $+ if null wpath+ then {-ctrace "rep" (npath',opath,w) $-} tagAdd npath' w+ else tagSPs grabpath npath2wid nwid2path+ XCmd (SelectWindow w) -> tagAdd path' w+ XCmd GetWindowId -> putSP (Left (path',XEvt (YourWindowId wid))) same+ where wid = lookupWid path2wid path'+ XCmd DestroyWindow ->+ putsSP [tox (XCommand (disp, wid, DestroyWindow))+ | wid <- subWids path2wid path']+ (tagSPs grabpath (pruneWid path2wid path') wid2path)+ XCmd (GrabEvents toMe) -> mtrace ("Grab",toMe,msg) $+ tagSPs (Just (toMe,path',autumnize path')) path2wid wid2path+ XCmd UngrabEvents -> tagSPs Nothing path2wid wid2path+ --DoXCommands xcmds -> foldr convertcmd same xcmds+ XCmd (DrawMany w gcdcmdss) | not optimizeDrawMany ->+ foldr convertcmd same+ [Draw w gc dcmd | (gc,dcmds)<-gcdcmdss,dcmd<-dcmds]+ XCmd xcmd -> convertcmd xcmd same+ DReq req -> putSP (tox req) same+ SReq sreq -> putSP (tox (SocketRequest sreq)) same+ XReq xreq ->+ case xreq of+ CreateMyWindow _ -> error "GUI fudget outside a shell fudget"+ CreateSimpleWindow rchild _ ->+ createWindow disp xreq (lookupWid path2wid path')+ (newwindow (newChildPath path' rchild))+ CreateRootWindow _ _ -> + createWindow disp xreq rootWindow (newwindow path')+ _ -> putSP (tox (XRequest (disp, + lookupWid path2wid path', xreq))) same+ LCmd _ -> same -- layout pseudo command+ Right (path', resp) -> case resp of+ AsyncInput (_, XEvent (wid, event)) ->+ case event of+ MappingNotify -> same+ ButtonEvent {} -> checkGrab+ KeyEvent {} -> checkGrab+ MotionNotify {} -> checkGrab+ SelectionClear atom -> pass $ tagSPns noSel+ DestroyNotify w -> if argFlag "destroyPrune" False then+ pass $ tagSPs grabpath path2wid' (prunePath wid2path w)+ else passame+ where path2wid' = if null path2' then path2wid+ else pruneWid path2wid path2'+ _ -> passame+ where path2' = lookupPath wid2path wid+ passto p = putSP (Left (p, XEvt event))+ pass = passto path2'+ passame = pass same+ checkGrab = case grabpath of+ Nothing -> passame+ Just (toMe,kpath,path) -> + if path `subPath` path2' then passame+ else if toMe then passto kpath same+ else same+ XResponse xresp -> putSP (Left (path',XResp xresp)) same+ SocketResponse sresp -> putSP (Left (path',SResp sresp)) same+ _ -> putSP (Left (path', DResp resp)) same++newChildPath parent rchild = absPath (autumnize parent) rchild+ +createWindow disp xreq wid cont =+ cmdContSP (Right (here, XRequest (disp, wid, xreq)))+ (\msg -> case msg of+ Right (_, XResponse (WindowCreated wid')) -> Just wid'+ _ -> Nothing)+ cont++traceit = showCommandF "debug"++optimizeDrawMany =+ argFlag "optdrawmany"+#ifdef __GLASGOW_HASKELL__+ True+#else+ False+#warning "not optimising DrawMany"+#endif
+ hsrc/lowlevel/WindowF.hs view
@@ -0,0 +1,148 @@+module WindowF(adjustBorderWidth,border_width,getBWidth,kernelF, toKernel, kernelTag,autumnize, windowKF) where+import Command+import CompOps((>+<))+import CompSP(prepostMapSP)+--import CompSP(serCompSP)+import Utils(pair,mapList)+import Direction+import Event+--import Font(FontStruct)+import Fudget+import FRequest+import Geometry(Point(..), Rect(..), origin, padd, pmax, rR)+import LayoutRequest+import LoopLow+--import Message(Message(..))+import NullF+import Path+--import SerCompF(idRightF)+import CompFfun(prepostMapLow)+import Spops+--import EitherUtils+import Data.Maybe(fromMaybe,isJust)+import Xtypes+import CmdLineEnv(argFlag)+--import DialogueIO hiding (IOError)++kernelF :: (K a b) -> F a b+kernelF (K proc) =+ let prep (High a) = High a+ prep (Low (_, b)) = Low b+ post (High a) = High a+ post (Low b) = Low (here, b)+ in {-F-}ff (prepostMapSP prep post proc)++toLowHere = mapList (Low . pair here)++winF :: (Rect -> FRequest) -> [FRequest] -> Rect -> K a b -> F a b+winF winCmd startcmds rect w =+ putMessagesF (toLowHere (winCmd rect : startcmds)) (kernelF w)++newKTag = not (argFlag "oldKTag" True) -- trouble with autolayout...++kernelTag = if newKTag then here else turn L here+autumnize = if newKTag then id else autumnize' where+ autumnize' [] = []+ autumnize' l = (reverse . tail . reverse) l+++toKernel x = mapList (Low . pair kernelTag) x++getBWidth cws = case cws of+ [] -> Nothing+ CWBorderWidth bw':_ -> Just bw'+ _:cws -> getBWidth cws++adjustBorderWidth b (Point x y) = Point (x+b2) (y+b2) where b2 = 2*b++border_width = 0::Int -- Should agree with the value in the core for XCreateSimpleWindow in xdecode.c and ghc-dialogue/DoXRequest.hs++windowKF :: (Rect -> FRequest) -> Bool -> Bool -> [FRequest] -> Maybe Rect -> K a b -> F c d -> F (Either a c) (Either b d)+windowKF winCmd isShell nomap startcmds oplace k f =+ let ctrlSP (bw,nomap) =+ getSP $ \msg ->+ let same = ctrlSP (bw,nomap)+ pass = putSP msg + passame = pass same+ adjB b s = if isShell then s else adjustBorderWidth b s+ in case msg of+ Left (tag,cmd) -> case cmd of+ XReq (CreateMyWindow r) | tag /= kernelTag ->+ putSP (Left (kernelTag, + XReq (CreateSimpleWindow tag r))) same+ XCmd (ReparentToMe r w) | r == here && tag /= kernelTag ->+ putSP (Left (kernelTag,XCmd (ReparentToMe tag w))) same+ XCmd (ConfigureWindow cws) | tag == kernelTag -> + -- hopefully, this occurs before LayoutMsg+ let bw' = fromMaybe bw (getBWidth cws) in+ if bw'==bw' then pass $ ctrlSP (bw',nomap) else error "windowKF"+ LCmd (LayoutRequest req) ->+ putSP (Left (tag,layoutRequestCmd (mapLayoutSize (adjB bw) req))) $+ same+ _ -> passame+ Right (tag,evt) -> case evt of+ XResp (WindowCreated _) | tag==kernelTag -> same + -- does not correspond to internal request+ LEvt (LayoutPlace (Rect p s)) -> let ads = adjB (-bw) s in+ putsSP ([Right (tag, LEvt (LayoutPlace (Rect origin ads))),+ Right (kernelTag, LEvt (LayoutSize ads)),+ Right (kernelTag, LEvt (LayoutPos p))] ++ -- TH 990321+ (if isShell then []+ else mapList (Left. pair kernelTag)+ ([XCmd $ moveResizeWindow (checkSize (Rect p ads))] +++ (if nomap || static then []+ else [XCmd MapRaised])))) $+ ctrlSP (bw,True)+ -- The LayoutSize message is not sent by the ordinary layout+ -- system, but by popupGroupF for convenience, to resize the+ -- window without moving it.+ LEvt (LayoutSize s) -> let ads = adjB (-bw) s in+ putsSP ([Right (tag, LEvt (LayoutPlace (Rect origin ads))),+ Right (kernelTag, LEvt (LayoutSize ads))] +++ (if isShell then []+ else [(Left. pair kernelTag)+ (XCmd $ resizeWindow (pmax ads minSize))])) $+ same+ _ -> passame++ minSize = Point 1 1+ checkSize (Rect p s) = Rect p (pmax s minSize)+ static = isJust oplace+ startplace =+ case oplace of+ Nothing -> rR 0 0 10 10+ Just p -> p+ statlimits (Rect p s) = layoutRequestCmd (plainLayout (padd p s) True True)+ wf =+ winF winCmd+ (startcmds +++ (case oplace of+ Nothing -> []+ Just r -> [statlimits r] +++ (if nomap then [] else [XCmd MapRaised])))+ startplace+ k+ wff = adjTag (wf>+<f)+ adjTag = if newKTag then prepostMapLow addktag removektag else id where+ addktag ([],m) = ([L],m)+ addktag tm = tm+ removektag ([L],m) = ([],m)+ removektag tm = tm++ windowf = loopThroughLowF (ctrlSP (border_width,nomap)) wff+ --windowf = windowf' ctrlSP nomap wf f+ in case oplace of+ Nothing -> windowf+ Just place -> let prep' (High ltag) = [(ltag, LEvt (LayoutPlace place))]+ prep' (Low (_, LEvt (LayoutPlace _))) = []+ prep' (Low msg) = [msg]+ post' (ltag, LCmd _) = [High ltag]+ post' cmd = [Low cmd]+ in loopLow (concmapSP post') (concmapSP prep') windowf++{-+windowf' ctrlSP nomap wf f =+ let wff = wf>+<f+ windowf = loopThroughLowF (ctrlSP (border_width,nomap)) wff+ in windowf+--}
+ hsrc/lowlevel/Xcommand.hs view
@@ -0,0 +1,15 @@+module Xcommand(+ xcommand,xcommandK,xcommandF,+ xcommands,xcommandsK,xcommandsF) where+import FRequest+import FudgetIO+import NullF(F,K)++xcommandK = xcommand :: (XCommand -> K i o -> K i o)+xcommandF = xcommand :: (XCommand -> F i o -> F i o)++xcommandsK = xcommands :: ([XCommand] -> K i o -> K i o)+xcommandsF = xcommands :: ([XCommand] -> F i o -> F i o)++xcommand xcmd = putLow (XCmd xcmd)+xcommands xcmds = putLows (map XCmd xcmds)
+ hsrc/lowlevel/Xrequest.hs view
@@ -0,0 +1,31 @@+module Xrequest(xrequest,xrequestF, xrequestK,Cont(..)) where+--import Command(XRequest)+--import Event(XResponse)+import FRequest+import FudgetIO+import EitherUtils(Cont(..))+import NullF(F,K)+--import DialogueIO hiding (IOError)++xrequestK = xrequest :: (XRequest -> (XResponse -> Maybe a) -> Cont (K b c) a)+xrequestF = xrequest :: (XRequest -> (XResponse -> Maybe a) -> Cont (F b c) a)++xrequest xreq expected = cmdContLow (XReq xreq) expectXResp+ where expectXResp msg =+ case msg of+ XResp xr -> expected xr+ _ -> Nothing++{- old:+xrequestK = xrequest cmdContK++xrequestF = xrequest cmdContF++xrequest k cmd exp' =+ k (DoXRequest cmd)+ (\msg ->+ case msg of+ IOResponse (XResponse xr) -> exp' xr+ _ -> Nothing)++-}
+ hsrc/sp/CompSP.hs view
@@ -0,0 +1,156 @@+module CompSP(prepostMapSP, postMapSP, preMapSP, idRightSP, idLeftSP, idHighSP,+ idLowSP, compMsgSP, compSP, compEitherSP, serCompSP) where+import Message(Message(..))+import SP+import Spops++--serCompSP :: SP b c -> SP a b -> SP a c+serCompSP sp1 sp2 =+ case sp1 of+ PutSP y sp1' -> PutSP y (serCompSP sp1' sp2)+ GetSP xsp1 -> serCompSP1 xsp1 sp2+ NullSP -> NullSP++serCompSP1 xsp1 sp2 =+ case sp2 of+ PutSP y sp2' -> serCompSP (xsp1 y) sp2'+ GetSP xsp2 -> GetSP (serCompSP1 xsp1 . xsp2)+ NullSP -> NullSP++---++compSP = compEitherSP++--compEitherSP :: SP a1 b1 -> SP a2 b2 -> SP (Either a1 a2) (Either b1 b2)+compEitherSP sp1 sp2 =+ case sp1 of+ PutSP y sp1' -> PutSP (Left y) (compEitherSP sp1' sp2)+ GetSP xsp1 -> compEitherSP1 xsp1 sp2+ NullSP -> rEitherSP sp2++--and compEitherSP1 :: (*a1->SP *a1 *b1) -> SP *a2 *b2 -> SP (Either *a1 *a2) (Either *b1 *b2)+compEitherSP1 xsp1 sp2 =+ case sp2 of+ PutSP y sp2' -> PutSP (Right y) (compEitherSP1 xsp1 sp2')+ GetSP xsp2 -> compEitherSP12 xsp1 xsp2+ NullSP -> lEitherSP (GetSP xsp1)++--and compEitherSP2 :: (SP *a1 *b1) -> (*a2->SP *a2 *b2) -> SP (Either *a1 *a2) (Either *b1 *b2)+compEitherSP2 sp1 xsp2 =+ case sp1 of+ PutSP y sp1' -> PutSP (Left y) (compEitherSP2 sp1' xsp2)+ GetSP xsp1 -> compEitherSP12 xsp1 xsp2+ NullSP -> rEitherSP (GetSP xsp2)++--and compEitherSP12 :: (*a1->SP *a1 *b1) -> (*a2->SP *a2 *b2) -> SP (Either *a1 *a2) (Either *b1 *b2)+compEitherSP12 xsp1 xsp2 =+ GetSP (\x ->+ case x of+ Left a -> compEitherSP2 (xsp1 a) xsp2+ Right b -> compEitherSP1 xsp1 (xsp2 b))++lEitherSP sp1 =+ case sp1 of+ PutSP y sp1' -> PutSP (Left y) (lEitherSP sp1')+ GetSP xsp1 -> lEitherSP1 xsp1+ NullSP -> NullSP++lEitherSP1 xsp1 =+ GetSP (\x ->+ case x of+ Left a -> lEitherSP (xsp1 a)+ Right b -> lEitherSP1 xsp1)++rEitherSP sp2 =+ case sp2 of+ PutSP y sp2' -> PutSP (Right y) (rEitherSP sp2')+ GetSP xsp2 -> rEitherSP2 xsp2+ NullSP -> NullSP++rEitherSP2 xsp2 =+ GetSP (\x ->+ case x of+ Right a -> rEitherSP (xsp2 a)+ Left b -> rEitherSP2 xsp2)++---+--and preMapSP :: SP *b *c -> (*a->*b) -> SP *a *c+preMapSP sp pre =+ case sp of+ PutSP y sp' -> PutSP y (preMapSP sp' pre)+ GetSP xsp -> GetSP (\x -> preMapSP (xsp (pre x)) pre)+ NullSP -> NullSP++--and postMapSP :: (*b->*c) -> SP *a *b -> SP *a *c+postMapSP post sp =+ case sp of+ PutSP y sp' -> PutSP (post y) (postMapSP post sp')+ GetSP xsp -> GetSP (\x -> postMapSP post (xsp x))+ NullSP -> NullSP++prepostMapSP pre post sp =+ case sp of+ PutSP y sp' -> PutSP (post y) (prepostMapSP pre post sp')+ GetSP xsp -> GetSP (\x -> prepostMapSP pre post (xsp (pre x)))+ NullSP -> NullSP++---+idLowSP sp = compMsgSP idSP sp++idHighSP sp = compMsgSP sp idSP++idLeftSP sp = compEitherSP idSP sp++idRightSP sp = compEitherSP sp idSP++---+--and compMsgSP :: SP *a1 *b1 -> SP *a2 *b2 -> SP (Message *a1 *a2) (Message *b1 *b2)+-- compMsgSP was constructed from compEitherSP with some global substitutions+compMsgSP sp1 sp2 =+ case sp1 of+ PutSP y sp1' -> PutSP (Low y) (compMsgSP sp1' sp2)+ GetSP xsp1 -> compMsgSP1 xsp1 sp2+ NullSP -> rMsgSP sp2++compMsgSP1 xsp1 sp2 =+ case sp2 of+ PutSP y sp2' -> PutSP (High y) (compMsgSP1 xsp1 sp2')+ GetSP xsp2 -> compMsgSP12 xsp1 xsp2+ NullSP -> lMsgSP (GetSP xsp1)++compMsgSP2 sp1 xsp2 =+ case sp1 of+ PutSP y sp1' -> PutSP (Low y) (compMsgSP2 sp1' xsp2)+ GetSP xsp1 -> compMsgSP12 xsp1 xsp2+ NullSP -> rMsgSP (GetSP xsp2)++compMsgSP12 xsp1 xsp2 =+ GetSP (\x ->+ case x of+ Low a -> compMsgSP2 (xsp1 a) xsp2+ High b -> compMsgSP1 xsp1 (xsp2 b))++lMsgSP sp1 =+ case sp1 of+ PutSP y sp1' -> PutSP (Low y) (lMsgSP sp1')+ GetSP xsp1 -> lMsgSP1 xsp1+ NullSP -> NullSP++lMsgSP1 xsp1 =+ GetSP (\x ->+ case x of+ Low a -> lMsgSP (xsp1 a)+ High b -> lMsgSP1 xsp1)++rMsgSP sp2 =+ case sp2 of+ PutSP y sp2' -> PutSP (High y) (rMsgSP sp2')+ GetSP xsp2 -> rMsgSP2 xsp2+ NullSP -> NullSP++rMsgSP2 xsp2 =+ GetSP (\x ->+ case x of+ High a -> rMsgSP (xsp2 a)+ Low b -> rMsgSP2 xsp2)+
+ hsrc/sp/Dynforkmerge.hs view
@@ -0,0 +1,34 @@+module Dynforkmerge(DynMsg(..), DynSPMsg(..), dynforkmerge) where+import SP+import Utils(part)++data DynMsg a b = DynCreate b |+ DynDestroy |+ DynMsg a + deriving (Eq, Ord)++type DynSPMsg a b = DynMsg a (SP a b)++dynforkmerge :: Eq a => SP (a, DynSPMsg b c) (a, c)+dynforkmerge = dfm []++dfm dynxsps =+ GetSP (\msg ->+ case msg of+ (t, DynCreate dynsp) -> dfmout t dynsp dynxsps+ (t, DynMsg msg') -> dfmin t msg' dynxsps+ (t, DynDestroy) -> dfmrm t dynxsps)++dfmout t dynsp dynxsps =+ case dynsp of+ PutSP y sp' -> PutSP (t, y) (dfmout t sp' dynxsps)+ GetSP xsp -> dfm ((t, xsp) : dynxsps)+ NullSP -> dfm dynxsps++dfmin t msg dynxsps =+ case part ((== t) . fst) dynxsps of+ ([], _) -> dfm dynxsps+ ([(_, xsp)], dynxsps') -> dfmout t (xsp msg) dynxsps'+ _ -> error "Same tag used twice in dynforkmerge (or dynListF)."++dfmrm t dynxsps = dfm (filter ((t /=) . fst) dynxsps)
+ hsrc/sp/IdempotSP.hs view
@@ -0,0 +1,17 @@+module IdempotSP where+import Spops(getSP,putSP)+import SP(SP)++idempotSP :: Eq a => SP a a+idempotSP =+ getSP $ \ x ->+ putSP x $+ idempotSP' x+ where+ idempotSP' x =+ getSP $ \ x' ->+ (if x'==x+ then id+ else putSP x') $+ idempotSP' x'+
+ hsrc/sp/InputSP.hs view
@@ -0,0 +1,70 @@+module InputSP where+import InputMsg+import Spops+import CompSP(serCompSP)+import SpEither(mapFilterSP)+import Utils(replace,setFst,setSnd)++-- New version: works with abstract InputMsg.+inputPairSP = mapFilterSP lift `serCompSP` ipSP (Nothing,Nothing)+ where+ ipSP optvalues = getSP $ either (change setFst) (change setSnd)+ where+ change setOne inputmsg =+ putSP (mapInp (const optvalues') inputmsg) $+ ipSP optvalues'+ where+ optvalues' = setOne optvalues (Just $ stripInputMsg inputmsg)++ lift = liftMaybeInputMsg . mapInp liftMaybePair++ liftMaybePair (Just x,Just y) = Just (x,y)+ liftMaybePair _ = Nothing++ liftMaybeInputMsg m = fmap im (stripInputMsg m)+ where im x = mapInp (const x) m++{- -- old version:+inputPairSP = ipSP Nothing Nothing+ where+ ipSP optx opty =+ getSP $ \msg ->+ case msg of+ Left (InputChange x) -> changeL InputChange x+ Left (InputDone k x) -> changeL (InputDone k) x+ Right (InputChange y) -> changeR InputChange y+ Right (InputDone k y) -> changeR (InputDone k) y+ where+ changeL f x =+ case opty of+ Just y -> putsSP [f (x,y)] cont+ Nothing -> cont+ where cont = ipSP (Just x) opty+ changeR f y =+ case optx of+ Just x -> putsSP [f (x,y)] cont+ Nothing -> cont+ where cont = ipSP optx (Just y)+-}++inputListSP tags = ilSP [(tag,Nothing)|tag<-tags]+ where+ ilSP acc =+ getSP $ \(t,msg) ->+ case msg of+ InputChange x -> change t InputChange x+ InputDone k x -> change t (InputDone k) x+ where+ change t f x = putsSP [f [(t,x)|(t,Just x)<-acc']] (ilSP acc')+ where acc' = replace (t,Just x) acc+++stripInputSP = mapFilterSP notLeave+ where + notLeave (InputChange s) = Just s+ notLeave (InputDone k s) = if k == inputLeaveKey+ then Nothing+ else Just s++inputDoneSP = mapFilterSP inputDone+inputLeaveDoneSP = mapFilterSP inputLeaveDone
+ hsrc/sp/Loop.hs view
@@ -0,0 +1,69 @@+module Loop(loopLeftSP,loopSP,loopOnlySP) where+import SP+import Queue++-- New versions with explicit queues for improved efficiency:+-- (Adding a message to the loop queue is O(1) instead of O(n), n=queue length.)++loopLeftSP sp = llSP empty sp+ where+ llSP q sp =+ case sp of+ PutSP (Right out) sp' -> PutSP out (llSP q sp')+ PutSP (Left loop') sp' -> llSP (enter q loop') sp'+ GetSP xsp ->+ case qremove q of+ Just (loop',q') -> llSP q' (xsp (Left loop'))+ Nothing -> GetSP (loopLeftSP.xsp.Right)+ NullSP -> NullSP++loopSP sp = lSP empty sp+ where+ lSP q sp =+ case sp of+ PutSP x sp' -> PutSP x (lSP (enter q x) sp')+ GetSP xsp ->+ case qremove q of+ Just (x,q') -> lSP q' (xsp x)+ Nothing -> GetSP (loopSP.xsp)+ NullSP -> NullSP++loopOnlySP sp = loSP empty sp+ where+ loSP q sp =+ case sp of+ PutSP x sp' -> loSP (enter q x) sp'+ GetSP xsp ->+ case qremove q of+ Just (x,q') -> loSP q' (xsp x)+ Nothing -> GetSP (loopOnlySP.xsp)+ NullSP -> NullSP+++{--- old:++loopLeftSP sp =+ case sp of+ PutSP (Right out) sp' -> PutSP out (loopLeftSP sp')+ PutSP (Left loop') sp' -> loopLeftSP (feed1SP (Left loop') sp')+ GetSP xsp -> GetSP (loopLeftSP.xsp.Right)+ NullSP -> NullSP++loopSP sp =+ case sp of+ PutSP x sp' -> PutSP x (loopSP (feed1SP x sp'))+ GetSP xsp -> GetSP (loopSP.xsp)+ NullSP -> NullSP++loopOnlySP sp =+ case sp of+ PutSP x sp' -> loopOnlySP (feed1SP x sp')+ GetSP xsp -> GetSP (loopOnlySP.xsp)+ NullSP -> NullSP++feed1SP x sp =+ case sp of+ PutSP y sp' -> PutSP y (feed1SP x sp')+ GetSP xsp' -> xsp' x+ NullSP -> NullSP+-}
+ hsrc/sp/Loopthrough.hs view
@@ -0,0 +1,79 @@+module Loopthrough(loopThroughRightSP) where+import SP+--import Spops+import Queue++loopThroughRightSP sp1 sp2 = ltrSP empty sp1 sp2++-- When sp1 and sp2 are unknown:+ltrSP q sp1 sp2 =+ case sp1 of+ PutSP (Right out) sp1' -> PutSP out (ltrSP q sp1' sp2)+ PutSP (Left loop') sp1' -> ltrSP (enter q loop') sp1' sp2+ GetSP xsp1 -> ltrSP1 q xsp1 sp2+ NullSP -> NullSP++-- When sp1 is waiting for input:+ltrSP1 q xsp1 sp2 =+ case sp2 of+ PutSP x sp2' -> ltrSP q (xsp1 (Left x)) sp2'+ GetSP xsp2 ->+ case qremove q of+ Just (x,q') -> ltrSP1 q' xsp1 (xsp2 x)+ Nothing -> GetSP (\x -> ltrSP2 (xsp1 (Right x)) xsp2)+ NullSP -> GetSP (lltrSP . xsp1 . Right)++-- When sp2 is waiting for input:+ltrSP2 sp1 xsp2 =+ case sp1 of+ PutSP (Right out) sp1' -> PutSP out (ltrSP2 sp1' xsp2)+ PutSP (Left loop') sp1' -> loopThroughRightSP sp1' (xsp2 loop')+ GetSP xsp1 -> GetSP (\x -> ltrSP2 (xsp1 (Right x)) xsp2)+ NullSP -> NullSP++-- When sp2 has terminated:+lltrSP sp1 =+ case sp1 of+ PutSP (Right out) sp1' -> PutSP out (lltrSP sp1')+ PutSP (Left loop') sp1' -> lltrSP sp1'+ GetSP xsp1 -> GetSP (lltrSP . xsp1 . Right)+ NullSP -> NullSP++{- old (inefficient queueing and too strict in sp2):++loopThroughRightSP sp1 sp2 =+ case sp1 of+ PutSP (Right out) sp1' -> PutSP out (loopThroughRightSP sp1' sp2)+ PutSP (Left loop') sp1' -> case sp2 of+ GetSP xsp2 -> loopThroughRightSP sp1'+ (xsp2 loop')+ NullSP -> lltrSP sp1'+ _ -> loopThroughRightSP sp1'+ (feedSP' loop' [] sp2)+ GetSP xsp1 -> ltrSP1 xsp1 sp2+ NullSP -> NullSP++ltrSP1 xsp1 sp2 =+ case sp2 of+ PutSP x sp2' -> loopThroughRightSP (xsp1 (Left x)) sp2'+ GetSP xsp2 -> GetSP (\x -> ltrSP2 (xsp1 (Right x)) xsp2)+ NullSP -> GetSP (lltrSP . xsp1 . Right)++ltrSP2 sp1 xsp2 =+ case sp1 of+ PutSP (Right out) sp1' -> PutSP out (ltrSP2 sp1' xsp2)+ PutSP (Left loop') sp1' -> loopThroughRightSP sp1' (xsp2 loop')+ GetSP xsp1 -> GetSP (\x -> ltrSP2 (xsp1 (Right x)) xsp2)+ NullSP -> NullSP++lltrSP sp1 =+ case sp1 of+ PutSP (Right out) sp1' -> PutSP out (lltrSP sp1')+ PutSP (Left loop') sp1' -> lltrSP sp1'+ GetSP xsp1 -> GetSP (lltrSP . xsp1 . Right)+ NullSP -> NullSP++-- normal code+feedSP' = feedSP++-}
+ hsrc/sp/ParSP.hs view
@@ -0,0 +1,21 @@+module ParSP(seqSP, parSP) where+import SP++parSP sp1 sp2 =+ case sp1 of+ PutSP y sp1' -> PutSP y (parSP sp1' sp2)+ GetSP xsp1 -> parSP1 xsp1 sp2+ NullSP -> sp2++parSP1 xsp1 sp2 =+ case sp2 of+ PutSP y sp2' -> PutSP y (parSP1 xsp1 sp2')+ GetSP xsp2 -> GetSP (\x -> parSP (xsp1 x) (xsp2 x))+ NullSP -> GetSP xsp1++seqSP sp1 sp2 =+ case sp1 of+ PutSP y sp1' -> PutSP y (seqSP sp1' sp2)+ GetSP xsp -> GetSP (\x -> seqSP (xsp x) sp2)+ NullSP -> sp2+
+ hsrc/sp/SP.hs view
@@ -0,0 +1,8 @@+module SP where+import ShowFun() -- show instance for function types++data SP a b = PutSP b (SP a b) |+ GetSP (a -> SP a b) |+ NullSP + deriving (Show)+
+ hsrc/sp/SPmonad.hs view
@@ -0,0 +1,26 @@+module SPmonad where+import SP(SP)+import ParSP(seqSP)+import Spops+import StateMonads(Mk(..),toMkc) --,bmk,toMs++type SPm i o ans = Mk (SP i o) ans++putsSPm :: [o] -> SPm i o ()+putsSPm = toMkc . putsSP++putSPm :: o -> SPm i o ()+putSPm = toMkc . putSP++getSPm :: SPm i o i+getSPm = Mk getSP++nullSPm :: SPm i o ()+nullSPm = return ()++monadSP :: (SPm i o ()) -> SP i o+monadSP (Mk spm) = spm (const nullSP)++toSPm :: (SP i o) -> SPm i o ()+toSPm sp = toMkc (seqSP sp)+
+ hsrc/sp/SPstateMonad.hs view
@@ -0,0 +1,23 @@+module SPstateMonad where+import SP(SP)+import Spops+import StateMonads(Mk(..),Ms(..),toMs,toMsc,loadMs,storeMs)++type SPms i o s ans = Ms (SP i o) s ans++putsSPms :: [o] -> SPms i o s ()+putSPms :: o -> SPms i o s ()+getSPms :: SPms i o s i+nullSPms :: SPms i o s ()+loadSPms :: SPms i o s s+storeSPms :: s -> SPms i o s ()+stateMonadSP :: s -> SPms i o s ans -> (ans -> SP i o) -> SP i o++putsSPms = toMsc . putsSP+putSPms = toMsc . putSP+getSPms = toMs getSP+nullSPms = return ()+loadSPms = loadMs+storeSPms = storeMs++stateMonadSP s0 (Mk spm) sp = spm (\ans state->sp ans) s0
+ hsrc/sp/SpEither.hs view
@@ -0,0 +1,19 @@+module SpEither where+import SP+import EitherUtils(stripLeft,stripRight)+import Spops(concatMapSP)++mapFilterSP f = m+ where m = GetSP $ \x->+ case f x of+ Just y -> PutSP y m+ Nothing -> m++filterLeftSP = mapFilterSP stripLeft+filterRightSP = mapFilterSP stripRight++filterJustSP = mapFilterSP id++splitSP = concatMapSP (\(x, y) -> [Left x, Right y])++toBothSP = concatMapSP (\x -> [Left x, Right x])
+ hsrc/sp/Spinterp.hs view
@@ -0,0 +1,9 @@+module Spinterp(interpSP) where+import SP++interpSP put get null' sp =+ case sp of+ PutSP x sp' -> put x (interpSP put get null' sp')+ GetSP xsp -> get (\x -> interpSP put get null' (xsp x))+ NullSP -> null'+
+ hsrc/sp/Spops.hs view
@@ -0,0 +1,96 @@+module Spops(module Spops,Cont(..)) where+import SP+import EitherUtils(Cont(..))++{- INLINE nullSP -}+nullSP :: SP a b+nullSP = NullSP++putsSP :: [b] -> SP a b -> SP a b+putsSP [] sp = sp+putsSP (x : xs) sp = PutSP x (putsSP xs sp)++{- INLINE putSP -}+putSP :: b -> SP a b -> SP a b+putSP = PutSP++appendStartSP :: [b] -> SP a b -> SP a b+appendStartSP zs (PutSP y sp) = PutSP y (putsSP zs sp)+appendStartSP zs sp = putsSP zs sp++stepSP :: [b] -> Cont (SP a b) a+stepSP ys xsp = putsSP ys (GetSP xsp)++getSP :: Cont (SP a b) a+getSP = GetSP++walkSP sp x =+ case sp of+ PutSP y sp' -> let (ys, sp'') = walkSP sp' x+ in (y : ys, sp'')+ GetSP xsp' -> pullSP (xsp' x)+ NullSP -> ([], NullSP)++pullSP sp =+ case sp of+ PutSP y sp' -> let (ys, sp'') = pullSP sp'+ in (y : ys, sp'')+ _ -> ([], sp)++runSP sp xs =+ case sp of+ PutSP y sp' -> y : runSP sp' xs+ GetSP xsp -> case xs of+ x : xs' -> runSP (xsp x) xs'+ [] -> []+ NullSP -> []++feedSP :: a -> [a] -> SP a b -> SP a b+feedSP x xs sp =+ case sp of+ PutSP y sp' -> PutSP y (feedSP x xs sp')+ GetSP xsp' -> startupSP xs (xsp' x)+ NullSP -> NullSP++startupSP :: [a] -> SP a b -> SP a b+startupSP [] sp = sp+startupSP (x : xs) sp = feedSP x xs sp++delaySP sp = GetSP (\x -> startupSP [x] sp)++mapSP f = m where m = GetSP (\x -> PutSP (f x) m)++idSP = GetSP (\x -> PutSP x idSP)++--and concatMapSP :: (*a->[*b]) -> SP *a *b+concatMapSP f = m where m = GetSP (\x -> putsSP (f x) m)++concmapSP = concatMapSP++concatMapAccumlSP f s0 =+ GetSP (\x ->+ let (s, y) = f s0 x+ in putsSP y (concatMapAccumlSP f s))++mapstateSP = concatMapAccumlSP++mapAccumlSP f s0 =+ GetSP (\x ->+ let (s, y) = f s0 x+ in PutSP y (mapAccumlSP f s))++concatSP = GetSP (\xs -> putsSP xs concatSP)+concSP = concatSP++zipSP (x : xs) = getSP (\y -> putSP (x, y) (zipSP xs))+zipSP [] = nullSP++filterSP p = getSP (\x -> (if p x then putSP x else id) (filterSP p))++splitAtElemSP :: (a -> Bool) -> Cont (SP a b) [a]+splitAtElemSP p xsp =+ let lSP acc =+ getSP (\x -> if p x then xsp (reverse acc) else lSP (x : acc))+ in lSP []++chopSP splitSP' = splitSP' (\xs -> putSP xs (chopSP splitSP'))
+ hsrc/sp/StreamProc.hs view
@@ -0,0 +1,16 @@+module StreamProc (-- * Stream processors+ module CompSP,module Dynforkmerge,module Loop,module Loopthrough,module ParSP,module SP,module SPmonad,module SPstateMonad,module Spinterp,module Spops,module SpEither,module IdempotSP,module StreamProcIO,module InputSP) where+import CompSP+import Dynforkmerge+import Loop+import Loopthrough+import ParSP+import SP(SP)+import SPmonad+import SPstateMonad+import Spinterp+import Spops+import SpEither+import IdempotSP+import StreamProcIO+import InputSP
+ hsrc/sp/StreamProcIO.hs view
@@ -0,0 +1,14 @@+module StreamProcIO where+import SP++class StreamProcIO sp where -- or: SPIO SP_IO SpIO SpIo ?+ put :: o -> sp i o -> sp i o+ get :: (i -> sp i o) -> sp i o+ end :: sp i o -- null?++puts xs sp = foldr put sp xs++instance StreamProcIO SP where+ put = PutSP+ get = GetSP+ end = NullSP
+ hsrc/types/Direction.hs view
@@ -0,0 +1,3 @@+module Direction(Direction(..)) where++data Direction = L | R | Dno Int deriving (Eq, Ord, Read, Show)
+ hsrc/types/Drawcmd.hs view
@@ -0,0 +1,37 @@+module Drawcmd(move, moveDrawCommands, moveDrawCommand) where+import DrawTypes+import Geometry(Move(..))+--import Xtypes++instance Move DrawCommand where move = flip moveDrawCommand++moveDrawCommand cmd v =+ case cmd of+ DrawLine l -> DrawLine (move v l)+ DrawLines cm ps -> DrawLines cm (movePoints cm ps v)+ DrawImageString p s -> DrawImageString (move v p) s+ DrawString p s -> DrawString (move v p) s+ DrawRectangle r -> DrawRectangle (move v r)+ FillRectangle r -> FillRectangle (move v r)+ FillPolygon shape coordMode ps ->+ FillPolygon shape coordMode (movePoints coordMode ps v)+ DrawArc r a1 a2 -> DrawArc (move v r) a1 a2+ FillArc r a1 a2 -> FillArc (move v r) a1 a2+ CopyArea d r p -> CopyArea d r (move v p)+ CopyPlane d r p n -> CopyPlane d r (move v p) n+ DrawPoint p -> DrawPoint (move v p)+ CreatePutImage r fmt pxls -> CreatePutImage (move v r) fmt pxls+ DrawImageStringPS p s -> DrawImageStringPS (move v p) s+ DrawStringPS p s -> DrawStringPS (move v p) s+ DrawImageString16 p s -> DrawImageString16 (move v p) s+ DrawString16 p s -> DrawString16 (move v p) s++movePoints cm ps v =+ case cm of+ CoordModeOrigin -> move v ps+ CoordModePrevious ->+ case ps of+ p:ps' -> move v p:ps'+ [] -> []++moveDrawCommands cmds p = map (`moveDrawCommand` p) cmds
+ hsrc/types/Fudget.hs view
@@ -0,0 +1,44 @@+module Fudget(+ module Fudget,SP,+ --XCommand,XEvent,+ FRequest,FResponse,+ Message(..),Path(..),Direction) where+--import Command(XCommand)+--import Event(XEvent)+import FRequest(FRequest,FResponse)+import Message(Message(..))+import Direction(Direction)+import Path(Path(..))+import SP(SP)++type TEvent = (Path, FResponse)+type TCommand = (Path, FRequest)++type Fa a b c d = SP (Message a c) (Message b d)++type FEvent a = Message TEvent a+type KEvent a = Message FResponse a++type FCommand a = Message TCommand a+type KCommand a = Message FRequest a++type Fudget a b = F a b++-- Traditional definitions:+--type F a b = Fa TEvent TCommand a b+--type K a b = Fa XEvent XCommand a b++-- New definitions:++type FSP hi ho = SP (FEvent hi) (FCommand ho) -- = old def of F hi ho+type KSP hi ho = SP (KEvent hi) (KCommand ho) -- = old def of K hi ho++newtype F hi ho = F (FSP hi ho)+newtype K hi ho = K (KSP hi ho)+--data F hi ho = F (FSP hi ho)+--data K hi ho = K (KSP hi ho)++kk=K+ff=F+unK (K sp) = sp+unF (F sp) = sp
+ hsrc/types/InputMsg.hs view
@@ -0,0 +1,41 @@+-- | Types for messages from buttons and input fields+module InputMsg where+import AuxTypes(KeySym(..))++-- | Button clicks+data Click = Click deriving (Eq, Ord, Show)++-- | Output from dialog popups with OK and Cancel buttons+data ConfirmMsg = Confirm | Cancel deriving (Eq, Ord, Show)++toConfirm (Left _) = Confirm+toConfirm (Right _) = Cancel+fromConfirm Confirm = Left Click+fromConfirm Cancel = Right Click++data InputMsg a = InputChange a |+ InputDone KeySym a + deriving (Eq, Ord, Show)++inputMsg = InputDone inputButtonKey+inputChange = InputChange++inputButtonKey = "." :: KeySym+inputLeaveKey = "" :: KeySym++stripInputMsg (InputDone _ x) = x+stripInputMsg (InputChange x) = x++tstInp p (InputChange s) = p s+tstInp p (InputDone k s) = p s++mapInp f (InputChange s) = InputChange (f s)+mapInp f (InputDone k s) = InputDone k (f s)++instance Functor InputMsg where fmap = mapInp++inputDone (InputDone k s) | k /= inputLeaveKey = Just s+inputDone _ = Nothing++inputLeaveDone (InputDone _ s) = Just s+inputLeaveDone _ = Nothing
+ hsrc/types/ListRequest.hs view
@@ -0,0 +1,31 @@+module ListRequest where++default (Int)++data ListRequest a+ = ReplaceItems Int Int [a] -- from, how many, new lines+ | HighlightItems [Int] -- replaces list of highlighted lines+ | PickItem Int -- as if user clicked on a line+listEnd = -1++replaceAll = ReplaceItems 0 listEnd -- replace all text+replaceAllFrom from = ReplaceItems from listEnd+deleteItems from cnt = ReplaceItems from cnt []+insertItems from = ReplaceItems from 0+appendItems = ReplaceItems listEnd listEnd+changeItems from txt = ReplaceItems from (length txt) txt++replaceItems = ReplaceItems+highlightItems = HighlightItems+pickItem = PickItem++--applyListRequest (ReplaceItems 0 cnt newtxt) oldtxt | cnt==listEnd = newtxt+applyListRequest (ReplaceItems from cnt newtxt) oldtxt =+ let before = if from==listEnd+ then oldtxt+ else take from oldtxt+ after = if from==listEnd || cnt==listEnd+ then []+ else drop (from+cnt) oldtxt+ in before++newtxt++after+applyListRequest _ oldtxt = oldtxt
+ hsrc/types/Message.hs view
@@ -0,0 +1,33 @@+module Message where++data Message a b = Low a | High b deriving (Eq, Ord, Show)++isHigh (High _) = True+isHigh _ = False++isLow (Low _) = True+isLow _ = False++stripHigh (High a) = Just a+stripHigh _ = Nothing++stripLow (Low b) = Just b+stripLow _ = Nothing++mapMessage fl fh' (Low l) = Low (fl l)+mapMessage fl fh' (High h) = High (fh' h)++message fl fh (Low l) = fl l+message fl fh (High h) = fh h++aLow f (Low l) = Low (f l)+aLow f (High h) = High h++aHigh f (High h) = High (f h)+aHigh f (Low l) = Low l++pushMsg (High xs) = fmap High xs+pushMsg (Low xs) = fmap Low xs++instance Functor (Message a) where+ fmap = aHigh
+ hsrc/types/Path.hs view
@@ -0,0 +1,30 @@+module Path(showPath, subPath, absPath, path, turn, here, Path(..)) where+import Direction+import Utils(lhead)++type Path = [Direction]++here :: Path+here = []++turn :: Direction -> Path -> Path+turn dir p = dir : p++path :: Path -> (Direction, Path)+path (dir : p) = (dir, p)+path [] = error "path.m: path []"++absPath :: Path -> Path -> Path+absPath absp relp = absp ++ relp++subPath :: Path -> Path -> Bool+subPath subp p = length subp <= length p && lhead subp p == subp++showPath :: Path -> String+showPath =+ concatMap (\x ->+ case x of+ L -> "L"+ R -> "R"+ Dno n -> "N(" ++ show n ++ ")")+
+ hsrc/types/Popupmsg.hs view
@@ -0,0 +1,5 @@+module Popupmsg where+import Geometry++data PopupMsg a = Popup Point a | Popdown deriving (Eq, Ord)+
+ hsrc/types/Rects.hs view
@@ -0,0 +1,52 @@+module Rects where+import Geometry++--newtype Region = Region [Rect]++intersectRects rs (Rect p2 s2) = ir rs+ where+ br2 = p2+s2+ ir [] = []+ ir (Rect p1 s1:es) =+ let ul = pmax p1 p2+ br = pmin (p1+s1) br2+ s@(Point w h) = br-ul+ in if w<=0 || h<=0 then ir es else Rect ul s:ir es++overlaps (Rect (Point x1 y1) (Point w1 h1))+ (Rect (Point x2 y2) (Point w2 h2)) =+ x1<x2+w2 && x2<x1+w1 && y1<y2+h2 && y2<y1+h1+--x1<=x2+w2 && x2<=x1+w1 && y1<=y2+h2 && y2<=y1+h1+-- rR 0 0 10 10 doesn't overlap with rR 0 10 10 10++boundingRect r1@(Rect p1 s1) r2@(Rect p2 s2) =+ if s1==0 then r2 else if s2==0 then r1 else Rect p s+ where p = pmin p1 p2+ s = pmax (p1+s1) (p2+s2) - p++diffRect r1 r2@(Rect (Point x2 y2) (Point w2 h2)) =+ if overlaps r1 r2 -- faster handling of common(?) case+ then intersectRects outside_r2 r1+ else [r1]+ where+ u@(Rect p1@(Point x1 y1) s1@(Point w1 h1)) = boundingRect r1 r2+ outside_r2 = [a,b,c,d]+ a = Rect p1 (Point w1 (y2-y1))+ b = Rect (Point x1 y2) (Point (x2-x1) h2)+ c = Rect (Point xc y2) (Point (x1+w1-xc) h2) where xc = x2 + w2+ d = Rect (Point x1 yd) (Point w1 (y1+h1-yd)) where yd = y2+h2++{-+ u:+ +-----------------------------++ | a |+ | |+ +--------+-------+------------++ | b | r2 | c |+ | | | |+ +--------+-------+------------++ | |+ | d |+ | |+ +-----------------------------++-}
+ hsrc/types/Types.hs view
@@ -0,0 +1,11 @@+module Types (-- * Types+ module Direction,module Drawcmd,module Fudget,module Message,module Path,module Popupmsg,module InputMsg,module ListRequest,module Rects) where+import Direction+import Drawcmd+import Message+import Path+import Popupmsg+import InputMsg+import ListRequest+import Fudget+import Rects
+ hsrc/utils/CmdLineEnv.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE CPP #-}+module CmdLineEnv(options, progName, resourceName, args, argKey, argReadKey, argFlag, argKeyList) where+import IOUtil(progArgs,progName,getEnvi)+import FilePaths(aFilePath,pathTail)+--import ListUtil(chopList,breakAt)+import Utils(segments)+import HbcUtils(apFst, apSnd, breakAt)+import Data.Char+import Data.Maybe(fromMaybe)+--import NonStdTrace(trace)++argReadKey key def = case lookupOptions key of+ Nothing -> def+ Just a -> case reads a of+ (v,_):_ -> v+ _ -> error (" Illegal value to flag -"++key+++ " (default value is "++show def++" of type "+++ showType def++"): "++a)+#ifndef __HBC__+ where showType _ = "<type??>"+#endif++argKey key def = lookupOptions key `elseM` def+argFlag key def = argKey key (if def then yes else no) == yes+argKeyList key def = maybe def (segments (/=':')) (lookupOptions key)++lookupOptions key = lookup key options+ `orM` (env ("FUD_"++ removePath progName++"_"++key))+ `orM` (env ("FUD_"++key))++ where removePath = reverse . fst . breakAt '/' . reverse+ env e = getEnvi e >>= \v -> Just (if v == "" then yes else v)+ --getEnvi' e = trace ("getEnvi "++e) $ getEnvi e++orM :: Maybe a -> Maybe a -> Maybe a+--orM = (++)+orM Nothing b = b+orM a b = a++elseM :: Maybe a -> a -> a+elseM = flip fromMaybe+--elseM (Just a) a' = a+--elseM Nothing a' = a'++yes = "yes"+no = "no"++(args, options) =+ let parse (('-' : ak) : av : al) = case av of+ '-':avr -> if not (null avr) && isAlpha (head avr)+ && reverse (take 4 (reverse ak)) /= "font" + then apSnd ((ak, yes) :) (parse (av:al))+ else thearg+ _ -> thearg+ where thearg = apSnd ((ak, av) :) (parse al)+ parse ['-' : ak] = ([], [(ak, yes)])+ parse ("-":al) = (al,[])+ parse (a : al) = apFst (a :) (parse al)+ parse [] = ([], [])+ in parse progArgs+++resourceName = pathTail (aFilePath progName)
+ hsrc/utils/Defaults.hs view
@@ -0,0 +1,56 @@+module Defaults(look3d, new3d, edgeWidth, defaultSep,+ paperColor, fgColor, bgColor, inputFg, inputBg,+ shadowColor, shineColor,+ defaultPosition, defaultSize, defaultFont, menuFont,+ buttonFont, labelFont, metaKey) where+import Geometry(pP)+--import ListUtil(chopList,breakAt)+import Utils(segments)+import AuxTypes(Modifiers(..))+import ResourceIds(FontName(..),ColorName(..))+import CmdLineEnv++argFont = argKey :: ( String -> FontName -> FontName)+argColor = argKey :: (String -> ColorName -> ColorName)++buttonFont = argFont "buttonfont" labelFont+menuFont = argFont "menufont" labelFont+labelFont = argFont "labelfont" "variable"+defaultFont = argFont "font" "fixed"++shineColor = argColor "shine" (if look3d then "white" else "lightgrey")+shadowColor = argColor "shadow" (if look3d+ then if new3d+ then "grey45"+ else "black"+ else "grey30")+paperColor = argColor "paper" "white"+inputFg = argColor "inputfg" fgColor+inputBg = argColor "inputbg" paperColor+fgColor = argColor "fg" "black"+bgColor = argColor "bg" "grey"++--defaultSep :: Int+defaultSep :: (Num a) => a+defaultSep = fromIntegral (argReadKey "sep" 5::Int)++defaultPosition =+ case segments (/='+') (argKey "geometry" "") of+ [_, x, y] -> Just (pP (read x) (read y))+ _ -> Nothing++defaultSize =+ case segments (/='x') (takeWhile (/='+') (argKey "geometry" "")) of+ [x, y] -> Just (pP (read x) (read y))+ _ -> Nothing++edgeWidth :: Int+edgeWidth = argReadKey "edgew" (if look3d then 2 else 4)++look3d = argFlag "look3d" True+new3d = argFlag "new3d" True+++-- | This should be modifier corresponding to Meta_L & Meta_R (see xmodmap).+-- It is usually Mod1, but in XQuartz it appears to be Mod2 instead...+metaKey = argReadKey "metakey" Mod1
+ hsrc/utils/EitherUtils.hs view
@@ -0,0 +1,51 @@+module EitherUtils where+import Data.Maybe+import Data.List(find)++type Cont c a = (a -> c) -> c++plookup p = fmap snd . find (p.fst)++-- mapfilter = Maybe.mapMaybe+-- stripMaybe = Maybe.fromJust+-- stripMaybeDef = Maybe.fromMaybe+-- isM = Maybe.isJust++--mapMaybe :: (a->b) -> Maybe a -> Maybe b+--mapMaybe = fmap++stripLeft (Left a) = Just a+stripLeft _ = Nothing++stripRight (Right b) = Just b+stripRight _ = Nothing++stripEither (Left a) = a+stripEither (Right b) = b++filterLeft = mapMaybe stripLeft++filterRight = mapMaybe stripRight++isLeft (Left _) = True+isLeft _ = False++isRight (Right _) = True+isRight _ = False++mapEither fl fr (Left l) = Left (fl l)+mapEither fl fr (Right r) = Right (fr r)++swapEither (Left x) = Right x+swapEither (Right y) = Left y++-- JSP 920929+splitEitherList [] = ([], [])+splitEitherList (x : xs) =+ let (lefts, rights) = splitEitherList xs+ in case x of+ Left a -> (a : lefts, rights)+ Right a -> (lefts, a : rights)++fromLeft (Left x) = x+fromRight (Right y) = y
+ hsrc/utils/FilePaths.hs view
@@ -0,0 +1,86 @@+module FilePaths(AFilePath,rootPath,aFilePath,filePath,+ compactPath,isAbsolute,joinPaths,pathRelativeTo,+ extendPath,pathTail,pathHead,pathLength) where+import Data.List(intersperse)+--import IO(openDirectory, statFile)+--import ListUtil(chopList,breakAt)+import Utils(segments)++newtype AFilePath = P [String] deriving (Eq,Ord)+-- data AFilePath = Root | Cwd | AFilePath :/ String++aFilePath :: FilePath -> AFilePath+aFilePath = P . splitpath++rootPath = P [""]++filePath :: AFilePath -> FilePath+filePath (P path) = joinpath path++compactPath (P path) = P (compactpath path)++extendPath (P path) node = P (node:path)++pathTail :: AFilePath -> String+pathTail (P []) = "." -- ??+pathTail (P [""]) = "/" -- ??+pathTail (P (t:_)) = t++pathHead (P []) = (P []) -- ??+pathHead (P (t:h)) = P h++pathLength (P path) = length path++isAbsolute (P ns) = isabsolute ns++joinPaths (P parent) (P child) =+ if isabsolute child+ then P child+ else P (child++parent) -- compactpath?++P file `pathRelativeTo` P dir =+ if take dirlen rfile == rdir+ then P (reverse (drop dirlen rfile))+ else P file+ where+ rdir = reverse dir+ rfile = reverse file+ dirlen = length rdir++isabsolute [] = False+isabsolute ns = null (last ns)++splitpath = reverse . segments (/='/')++joinpath [] = "."+joinpath [""] = "/"+joinpath ns = concat (intersperse "/" (reverse ns))++compactpath [] = []+compactpath (".." : xs) =+ case compactpath xs of+ [""] -> [""] -- parent of root directory, stay in root directory+ ys@("..":_) -> "..":ys -- relative path to grandparent, keep ".."+ _:ys -> ys -- parent of child, optimize+ ys -> "..":ys -- other, keep ".."+--compactpath ["..",""] = [""] -- parent of root directory+--compactpath (".." : "." : xs) = compactpath ("..":xs)+--compactpath (".." : x : xs) | x /= ".." = compactpath xs+compactpath ("" : xs@(_:_)) = compactpath xs+compactpath ("." : xs) = compactpath xs+compactpath (x : xs) = x : compactpath xs++{-+ls s =+ let paths = map (: s) . sort . filter (/= ".")+ in case openDirectory (joinpath s) of+ Right files -> paths files+ Left msg -> [msg : s]++isdir s =+ case statFile (joinpath s) of+ Right ns -> let mode = ns !! (3 - 1)+ in bitand mode 61440 == 16384+ Left _ -> False++-}
+ hsrc/utils/FudUtilities.hs view
@@ -0,0 +1,15 @@+module FudUtilities (-- * Utilities+ module Defaults, module CmdLineEnv, module FilePaths, module Geometry, module MapstateMsg, module EitherUtils, module StringUtils, module Utils, module FudVersion) where+import Defaults+import CmdLineEnv+import Geometry+import FilePaths+import MapstateMsg+import EitherUtils+import StringUtils+import Utils+import FudVersion++--import Message(Message)+--import SP(SP)+--import Xtypes(FontName(..))
+ hsrc/utils/FudVersion.hs view
@@ -0,0 +1,7 @@+module FudVersion where++version = version_0_18_3++version_0_18_3 = "version 0.18.3" -- only for documentation, use "version" instead++-- The version number should be increased immediately after a public release.
+ hsrc/utils/Geometry.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE CPP #-}+module Geometry where+-- This module should be moved to ../types/++import Data.Ix++class Move a where move :: Point -> a -> a++fmove 0 = id+fmove p = fmap (move p)++instance Move a => Move [a] where move = fmove+instance Move a => Move (Maybe a) where move = fmove++data Point = Point { xcoord, ycoord :: Int }+ deriving (Eq, Ord, Show, Read, Ix)+type Size = Point+data Line = Line Point Point deriving (Eq, Ord, Show, Read)+data Rect = Rect {rectpos::Point, rectsize::Size}+ deriving (Eq, Ord, Show, Read)+{-+instance Show Point where showsPrec d (Point x y) = showsPrec d (x,y)+instance Read Point where readsPrec d s = [(pP x y,r)|((x,y),r)<-readsPrec d s]++instance Show Rect where+ showsPrec d (Rect p s) =+ showParen (d>=10) $+ showString "R " . showsPrec 10 p . showChar ' ' . showsPrec 10 s+-}+-- convenient abbreviations:+origin = Point 0 0+pP x y = Point x y+lL x1 y1 x2 y2 = Line (Point x1 y1) (Point x2 y2)+rR x y w h = Rect (Point x y) (Point w h)+diag x = Point x x++-- selectors:+--xcoord (Point x _) = x+--ycoord (Point _ y) = y++--rectsize (Rect _ size) = size+--rectpos (Rect pos _) = pos++-- basic operations:+padd (Point x1 y1) (Point x2 y2) = Point (x1 + x2) (y1 + y2)+psub (Point x1 y1) (Point x2 y2) = Point (x1 - x2) (y1 - y2)++instance Num Point where+ (+) = padd+ (-) = psub+ Point x1 y1 * Point x2 y2 = Point (x1*x2) (y1*y2) -- hmm+ negate = psub origin+ abs (Point x y) = Point (abs x) (abs y) -- hmm+ signum (Point x y) = Point (signum x) (signum y) -- hmm+ fromInteger i = let i' = fromInteger i in Point i' i'+#ifdef __HBC__+ fromInt i = Point i i+#endif++rsub (Rect p1 _) (Rect p2 _) = psub p1 p2++posrect (Rect pos size) newpos = Rect newpos size+moverect (Rect pos size) delta = Rect (padd pos delta) size+sizerect (Rect pos size) newsize = Rect pos newsize+growrect (Rect pos size) delta = Rect pos (padd size delta)++moveline (Line p1 p2) delta = Line (padd p1 delta) (padd p2 delta)++rect2line (Rect p s) = Line p (p `padd` s)+line2rect (Line p1 p2) = Rect p1 (p2 `psub` p1)++instance Move Point where move = padd+instance Move Rect where move = flip moverect+instance Move Line where move = flip moveline++-- misc:+Point x1 y1 =.> Point x2 y2 = x1 >= x2 && y1 >= y2+inRect pt (Rect p1 p2) = pt =.> p1 && p2 =.> psub pt p1+scale k i = truncate (k * fromIntegral i)+scalePoint k (Point x y) = Point (scale k x) (scale k y)+rectMiddle (Rect (Point x y) (Point w h)) =+ Point (x + w `quot` 2) (y + h `quot` 2)++freedom (Rect _ outer) (Rect _ inner) = psub outer inner++pmin (Point x1 y1) (Point x2 y2) = Point (x1 `min` x2) (y1 `min` y2)+pmax (Point x1 y1) (Point x2 y2) = Point (x1 `max` x2) (y1 `max` y2)++pMin (p : pl) = foldr pmin p pl+pMin [] = error "pMin on []"++pMax (p : pl) = foldr pmax p pl+pMax [] = error "pMax on []"++plim p0 p1 p = pmax p0 (pmin p1 p)++-- | confine outer inner: moves an shrinks inner to fit within outer+confine (Rect outerpos outersize) (Rect innerpos innersize) =+ let newsize = pmin outersize innersize+ maxpos = padd outerpos (psub outersize newsize)+ in Rect (plim outerpos maxpos innerpos) newsize++-- | rmax gives an enclosing rect+rmax r1 r2 = line2rect (Line (pmin lp1 lp2) (pmax lp1' lp2'))+ where Line lp1 lp1' = rect2line r1+ Line lp2 lp2' = rect2line r2
+ hsrc/utils/HbcUtils.hs view
@@ -0,0 +1,44 @@+-- | Useful functions from hbc-library modules ListSet, ListMap, ListUtil, HO+-- and UTF8+module HbcUtils(module HbcUtils,module FudUTF8) where+import Data.List((\\))+import FudUTF8++-- * From ListSet++-- | Union of sets as lists+union :: (Eq a) => [a] -> [a] -> [a]+union xs ys = xs ++ (ys \\ xs)+++-- * From ListMap+lookupWithDefault :: (Eq a) => [(a, b)] -> b -> a -> b+lookupWithDefault [] d _ = d+lookupWithDefault ((x,y):xys) d x' = if x == x' then y else lookupWithDefault xys d x'+++-- * From ListUtil+mapFst f = map (apFst f)+mapSnd f = map (apSnd f)++breakAt c = apSnd (drop 1) . break (==c)++chopList :: ([a] -> (b, [a])) -> [a] -> [b]+chopList f l = unfoldr f null l+ where+ -- | Repeatedly extract (and transform) values until a predicate hold. Return the list of values.+ unfoldr :: (a -> (b, a)) -> (a -> Bool) -> a -> [b]+ unfoldr f p x | p x = []+ | otherwise = y:unfoldr f p x'+ where (y, x') = f x++assoc :: Eq k => (v -> r) -> r -> [(k, v)] -> k -> r+assoc f z xs k = maybe z f (lookup k xs)++-- * From HO++apFst f (x, y) = (f x, y)+apSnd f (x, y) = (x, f y)++curry3 f x y z = f (x,y,z)+uncurry3 f ~(x,y,z) = f x y z
+ hsrc/utils/MapstateMsg.hs view
@@ -0,0 +1,26 @@+module MapstateMsg(mapLow, mapHigh, mapstateLow, mapstateHigh) where+import Message(Message(..))+--import SP(SP)+import Spops+import HbcUtils(apSnd)++mapstateHigh p s =+ let ms s' (Low msg) = (s', [Low msg])+ ms s' (High msg) = apSnd (map High) (p s' msg)+ in mapstateSP ms s++mapstateLow p s =+ let ms s' (High msg) = (s', [High msg])+ ms s' (Low msg) = apSnd (map Low) (p s' msg)+ in mapstateSP ms s++mapHigh p =+ let ms (High msg) = map High (p msg)+ ms (Low msg) = [Low msg]+ in concmapSP ms++mapLow p =+ let ms (Low msg) = map Low (p msg)+ ms (High msg) = [High msg]+ in concmapSP ms+
+ hsrc/utils/StringUtils.hs view
@@ -0,0 +1,17 @@+module StringUtils where+--import Char(isAlpha,isAlphanum,isDigit)++expandTabs n = exp (n::Int)+ where+ exp k [] = []+ exp k ('\t':xs) = [' '|_<-[1..k]] ++ exp n xs+ exp k (x:xs) = x:exp (if k==1 then n else k-1) xs++rmBS "" = ""+rmBS (c:'\b':cs) = rmBS cs+rmBS (c:cs) = c:rmBS cs++wrapLine n xs =+ let first = take n xs+ rest = drop n xs+ in first : (if null rest then [] else wrapLine n rest)
+ hsrc/utils/Utils.hs view
@@ -0,0 +1,101 @@+module Utils where+--import ListSet(union)+--import HbcWord+import HbcUtils++infixr 1 `thenC`+infixl 1 `ifC`++aboth f (x, y) = (f x, f y)+mapPair (f, g) (x, y) = (f x, g y)+pairwith f x = (x, f x)+swap (x, y) = (y, x)+pair = (,)++setFst (_,y) x = (x,y)+setSnd (x,_) y = (x,y)++oo f g x y = f (g x y)++-- | Apply a function to the nth element of a list+anth :: Int -> (a->a) -> [a] -> [a]+anth _ _ [] = []+anth 1 f (x : xs) = f x : xs+anth n f (x : xs) = x : anth (n - 1) f xs++--dropto p = while (\l -> l /= [] && (not . p . head) l) tail++number :: Int -> [a] -> [(Int,a)]+number _ [] = []+number i (x : xs) = (i, x) : number (i + 1) xs++loop f =+ let yf = f yf+ in yf++ifC c b = if b then c else id+thenC = flip ifC++gmap g f = foldr (\x -> \ys -> g (f x) ys) []++unionmap f = gmap union f++-- | Remove the first occurence+remove a (b : bs) | a == b = bs+remove a (b : bs) = b : remove a bs+remove a [] = []++-- | Replace the first occurence+replace p [] = [p]+replace (t, v) ((t', v') : ls') | t == t' = (t, v) : ls'+replace p (l : ls') = l : replace p ls'++unconcat [] _ = []+unconcat (n : ns) xs = xs1:unconcat ns xs2+ where (xs1,xs2) = splitAt n xs++-- | lunconcat xss ys = unconcat (map length xss) ys+lunconcat [] _ = []+lunconcat (n : ns) xs = xs1:lunconcat ns xs2+ where (xs1,xs2) = lsplit n xs+++-- | lhead xs ys = take (length xs) ys, but the rhs is stricter+lhead (x : xs) (y : ys) = y : lhead xs ys+lhead _ _ = []++-- | ltail xs ys = drop (length xs) ys, but the rhs is stricter+ltail [] ys = ys+ltail _ [] = []+ltail (x : xs) (y : ys) = ltail xs ys++-- | lsplit xs ys = (lhead xs ys,ltail xs ys), but without the space leak, -fpbu+lsplit [] ys = ([], ys)+lsplit _ [] = ([], [])+lsplit (x : xs) (y : ys) =+ let (yhs, yts) = lsplit xs ys+ in (y : yhs, yts)++-- | JSP 920928+part p [] = ([], [])+part p (x : xs) =+ let (ys, zs) = part p xs+ in if p x then (x : ys, zs) else (ys, x : zs)++issubset a b = all (`elem` b) a++-- | To avoid problems caused by poor type inference for constructor classes in+-- Haskell 1.3:+mapList = map :: ((a->b)->[a]->[b])++-- From Compat.hs:+--bitxor,bitand::Int->Int->Int+--bitxor x y = wordToInt (bitXor (fromIntegral x) (fromIntegral y))+--bitand x y = wordToInt (bitAnd (fromIntegral x) (fromIntegral y))+++-- | @chopList (breakAt c) == segments (/=c)@+segments p [] = []+segments p xs = case span p xs of+ (xs1,_:xs2) -> xs1:segments p xs2+ (xs1,_) -> [xs1]
+ hsrc/xtypes/AuxTypes.hs view
@@ -0,0 +1,56 @@+-- | Auxiliary Xlib types+module AuxTypes where++data Gravity = ForgetGravity |+ NorthWestGravity |+ NorthGravity |+ NorthEastGravity |+ WestGravity |+ CenterGravity |+ EastGravity |+ SouthWestGravity |+ SouthGravity |+ SouthEastGravity |+ StaticGravity + deriving (Eq, Ord, Read, Show, Bounded, Enum)++data ShapeKind = ShapeBounding | ShapeClip+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++data ShapeOperation = ShapeSet |+ ShapeUnion |+ ShapeIntersect |+ ShapeSubtract |+ ShapeInvert + deriving (Eq, Ord, Show, Read, Bounded, Enum)++-- There already is an Ordering in the 1.3 Prelude+data Ordering' = Unsorted | YSorted | YXSorted | YXBanded+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++type RmClass = String+type RmName = String+type RmQuery = (RmClass, RmName)+type RmSpec = [RmQuery]+type RmValue = String+type RmDatabase = Int++rmNothing = 0::Int++data Modifiers = Shift | Lock | Control+ | Mod1 | Mod2 | Mod3 | Mod4 | Mod5+ | Button1 | Button2 | Button3 | Button4 | Button5+ | Mod13 | Mod14 -- non-standard, but used in XQuartz+ | Any + deriving (Eq, Ord, Show, Read, Bounded, Enum)++clModifiers =+ [Shift, Lock, Control, Mod1, Mod2, Mod3, Mod4, Mod5,+ Button1, Button2, Button3, Button4, Button5]++data Button = AnyButton | Button Int deriving (Eq, Ord, Read, Show)++type ModState = [Modifiers]++type KeySym = String+
+ hsrc/xtypes/Command.hs view
@@ -0,0 +1,132 @@+module Command(module Command,DrawCommand,Drawable(..)) where+import Event(XEvent)+import Direction() -- for hbc+import Path(Path(..))+import Geometry+--import LayoutRequest(LayoutMessage(..))+import Xtypes+import DrawTypes+--import DialogueIO(Request)+import ShowFun()++-- Same order as in .../lml/src/lib/xlib/xlib.h+data XCommand -- X commands+ = CloseDisplay Display+ | DestroyWindow+ | MapRaised+ | LowerWindow+ | UnmapWindow+ | Draw Drawable GCId DrawCommand+ | DrawMany Drawable [(GCId,[DrawCommand])] -- use instead of XDoCommands+ | ClearArea Rect Bool+ | ClearWindow+ | ChangeGC GCId GCAttributeList+ | FreeGC GCId+ | ChangeWindowAttributes [WindowAttributes]+ | ConfigureWindow [WindowChanges]+ | StoreName String+ | SetNormalHints Point+ | SetWMHints Bool -- input+ | UngrabPointer+ | GrabButton Bool Button ModState [EventMask]+ | UngrabButton Button ModState+ | Flush+ | FreePixmap PixmapId+ | ShapeCombineMask ShapeKind Point PixmapId ShapeOperation+ | ShapeCombineRectangles ShapeKind Point [Rect] ShapeOperation Ordering'+ | ShapeCombineShape ShapeKind Point PixmapId ShapeKind ShapeOperation+ | RmDestroyDatabase RmDatabase+ | RmCombineDatabase RmDatabase RmDatabase Bool+ | RmPutLineResource RmDatabase String+ | SetWMProtocols [Atom]+ | SendEvent Window Bool [EventMask] XEvent+ | SetSelectionOwner Bool Atom+ | ConvertSelection Selection+ | ChangeProperty Window Atom Atom Int PropertyMode String+ | FreeColors ColormapId [Pixel] Pixel{-planes-}+ | ReparentWindow Window {- parent -}+ | WarpPointer Point+ | SetRegion GCId Rect -- !!! modifies a GC -- cache problems!+ | AddToSaveSet+ | RemoveFromSaveSet+ | Bell Int+ | SetGCWarningHack {gcon,gcoff::PixmapId}+-- ONLY Pseudo commands below, add new Xlib command above this line !!!+ | GrabEvents Bool+ | UngrabEvents+ | TranslateEvent (XEvent -> Maybe XEvent) [EventMask]+ | ReparentToMe Path Window+ | GetWindowId -- move to XRequest?+ | SelectWindow Window+-- Layout pseudo commands+-- | LayoutMsg LayoutMessage+-- An I/O request to be passed through the top level (not anymore)+-- | DoIO Request+-- | DoXRequest XRequest+--+-- | DoXCommands [XCommand]+ -- Drawing speed hack, bypasses caches and resource management.+ -- Do not put any Alloc/Free, Create/Destroy, Grab/Ungrab type+ -- of commands inside DoXCommands!+--+ | MeButtonMachine -- tells menuPopupF where the buttons are+ deriving (Show,Read)++-- layoutRequestCmd = LayoutMsg . LayoutRequest++data XRequest+ = OpenDisplay DisplayName+ | CreateSimpleWindow Path Rect+ | CreateRootWindow Rect String -- resource name+ | CreateGC Drawable GCId GCAttributeList+ | LoadFont FontName+ | CreateFontCursor Int+ | GrabPointer Bool [EventMask]+ | LMLQueryFont FontId -- doesn't work in Haskell+ | AllocNamedColor ColormapId ColorName+ | AllocColor ColormapId RGB+ | CreatePixmap Size Depth+ | ReadBitmapFile FilePath+ | CreateBitmapFromData BitmapData+ | RmGetStringDatabase String+ | RmGetResource RmDatabase String String+ | TranslateCoordinates+ | InternAtom String Bool+ | GetAtomName Atom+ | GetWindowProperty Int Atom Bool Atom+ | QueryPointer+ | QueryFont FontId+ | LoadQueryFont FontName+ | QueryColor ColormapId Pixel+ | QueryTree+ | DefaultRootWindow+ | GetGeometry+ | DefaultVisual+ | Sync Bool -- discard::Bool+ | QueryTextExtents16 FontId String+ | ListFonts FontName Int -- pattern, maxnames+ | ListFontsWithInfo FontName Int -- pattern, maxnames+ | GetResource RmSpec+ | DbeQueryExtension+ | DbeAllocateBackBufferName SwapAction+ | DbeSwapBuffers SwapAction -- applies only to the fudget's own window.+ -- ONLY Pseudo requests below:+ | CreateMyWindow Rect+ deriving (Eq, Ord, Show, Read)++type Command = XCommand++data BitmapData = BitmapData Size (Maybe Point) [Int] + deriving (Eq, Ord, Show, Read)++type DisplayName = String++-- Convenient abbreviations:+moveWindow (Point x y) = ConfigureWindow [CWX x, CWY y]+resizeWindow (Point w h) = ConfigureWindow [CWWidth w, CWHeight h]+moveResizeWindow (Rect (Point x y) (Point w h)) =+ ConfigureWindow [CWX x, CWY y, CWWidth w, CWHeight h]++clearWindowExpose = ClearArea (rR 0 0 0 0) True+ -- Clears the window and generates appropriate+ -- exposure events.See man page for XClearArea.
+ hsrc/xtypes/DrawInPixmap.hs view
@@ -0,0 +1,23 @@+module DrawInPixmap where+--import Geometry+import XDraw++-- convenient abbreviations for drawing in pixmaps:+pmDrawLine pm gc l = draw (Pixmap pm) gc (DrawLine l)+pmDrawLines pm gc mode ps = draw (Pixmap pm) gc (DrawLines mode ps)+pmDrawImageString pm gc p s = draw (Pixmap pm) gc (DrawImageString p s)+pmDrawString pm gc p s = draw (Pixmap pm) gc (DrawString p s)+pmDrawImageString16 pm gc p s = draw (Pixmap pm) gc (DrawImageString16 p s)+pmDrawString16 pm gc p s = draw (Pixmap pm) gc (DrawString16 p s)+pmDrawImageStringPS pm gc p s = draw (Pixmap pm) gc (DrawImageStringPS p s)+pmDrawStringPS pm gc p s = draw (Pixmap pm) gc (DrawStringPS p s)+pmDrawRectangle pm gc r = draw (Pixmap pm) gc (DrawRectangle r)+pmFillRectangle pm gc r = draw (Pixmap pm) gc (FillRectangle r)+pmFillPolygon pm gc shape mode ps =+ draw (Pixmap pm) gc (FillPolygon shape mode ps)+pmDrawArc pm gc r a1 a2 = draw (Pixmap pm) gc (DrawArc r a1 a2)+pmFillArc pm gc r a1 a2 = draw (Pixmap pm) gc (FillArc r a1 a2)+pmCopyArea dst gc src r p = draw (Pixmap dst) gc (CopyArea src r p)+pmCopyPlane dst gc src r p i = draw (Pixmap dst) gc (CopyPlane src r p i)+pmDrawPoint dst gc p = draw (Pixmap dst) gc (DrawPoint p)+pmCreatePutImage dst gc r s d = draw (Pixmap dst) gc (CreatePutImage r s d)
+ hsrc/xtypes/DrawInWindow.hs view
@@ -0,0 +1,24 @@+module DrawInWindow where+--import Geometry+import XDraw++-- convenient abbreviations for drawing in windows:+wDrawLine gc l = draw MyWindow gc (DrawLine l)+wDrawLines gc mode ps = draw MyWindow gc (DrawLines mode ps)+wDrawImageString gc p s = draw MyWindow gc (DrawImageString p s)+wDrawString gc p s = draw MyWindow gc (DrawString p s)+wDrawImageString16 gc p s = draw MyWindow gc (DrawImageString16 p s)+wDrawString16 gc p s = draw MyWindow gc (DrawString16 p s)+wDrawImageStringPS gc p s = draw MyWindow gc (DrawImageStringPS p s)+wDrawStringPS gc p s = draw MyWindow gc (DrawStringPS p s)+wDrawRectangle gc r = draw MyWindow gc (DrawRectangle r)+wFillRectangle gc r = draw MyWindow gc (FillRectangle r)+wFillPolygon gc shape mode ps = draw MyWindow gc (FillPolygon shape mode ps)+wDrawArc gc r a1 a2 = draw MyWindow gc (DrawArc r a1 a2)+wFillArc gc r a1 a2 = draw MyWindow gc (FillArc r a1 a2)+wDrawCircle gc p r = draw MyWindow gc (drawCircle p r)+wFillCircle gc p r = draw MyWindow gc (fillCircle p r)+wCopyArea gc src r p = draw MyWindow gc (CopyArea src r p)+wCopyPlane gc src r p i = draw MyWindow gc (CopyPlane src r p i)+wDrawPoint gc p = draw MyWindow gc (DrawPoint p)+wCreatePutImage gc r s d = draw MyWindow gc (CreatePutImage r s d)
+ hsrc/xtypes/DrawTypes.hs view
@@ -0,0 +1,44 @@+module DrawTypes where+import Geometry(Point,Rect,Line)+import PackedString(PackedString)+import Xtypes(Pixel,PixmapId,ImageFormat,DbeBackBufferId)++data DrawCommand+-- Don't forget to change ../types/Drawcmd.hs too, if you change things here!!+ = DrawLine Line+ | DrawImageString Point String+ | DrawString Point String+ | DrawRectangle Rect+ | FillRectangle Rect+ | FillPolygon Shape CoordMode [Point]+ | DrawArc Rect Int Int+ | FillArc Rect Int Int+ | CopyArea Drawable Rect Point+ | CopyPlane Drawable Rect Point Int+ | DrawPoint Point+ | CreatePutImage Rect ImageFormat [Pixel]+ --+ | DrawImageStringPS Point PackedString+ | DrawStringPS Point PackedString+ --+ | DrawLines CoordMode [Point]+ | DrawImageString16 Point String+ | DrawString16 Point String+ deriving (Eq, Ord, Show, Read)++data Drawable+ = MyWindow+ | Pixmap PixmapId+ | DbeBackBuffer DbeBackBufferId+ deriving (Eq, Ord, Show, Read)++data CoordMode+ = CoordModeOrigin+ | CoordModePrevious + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data Shape+ = Complex+ | Nonconvex+ | Convex+ deriving (Eq, Ord, Show, Read, Bounded, Enum)
+ hsrc/xtypes/Event.hs view
@@ -0,0 +1,122 @@+module Event(module Event,FontStructList,FontStruct) where+import Font(FontStruct,FontStructList,CharStruct)+import Visual(Visual)+import Geometry+import Xtypes+--import DialogueIO hiding (IOError)++newtype KeyCode = KeyCode Int deriving (Eq, Ord, Show, Read)++data Pressed = Pressed | Released | MultiClick Int+ deriving (Eq, Ord, Show, Read)++data Detail = NotifyAncestor |+ NotifyVirtual |+ NotifyInferior |+ NotifyNonlinear |+ NotifyNonlinearVirtual |+ NotifyPointer |+ NotifyPointerRoot |+ NotifyDetailNothing + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data Mode = NotifyNormal |+ NotifyGrab |+ NotifyUngrab |+ NotifyWhileGrabbed + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data Visibility = VisibilityUnobscured |+ VisibilityPartiallyObscured |+ VisibilityFullyObscured + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data ClientData = Byte String |+ Short [Int] |+ Long [Int] + deriving (Eq, Ord, Show, Read)++data XEvent+ = FocusIn { detail::Detail, mode::Mode }+ | FocusOut { detail::Detail, mode::Mode }+ | KeymapNotify+ | GraphicsExpose { rect::Rect, count::Int, major_code, minor_code::Int}+ | KeyEvent { time::Time, pos,rootPos::Point, state::ModState, type'::Pressed, keycode::KeyCode, keySym::KeySym, keyLookup::KeyLookup }+ | ButtonEvent { time::Time, pos,rootPos::Point, state::ModState, type'::Pressed, button::Button}+ | MotionNotify { time::Time, pos,rootPos::Point, state::ModState }+ | EnterNotify { time::Time, pos,rootPos::Point, detail::Detail, mode::Mode, focus::Bool }+ | LeaveNotify { time::Time, pos,rootPos::Point, detail::Detail, mode::Mode, focus::Bool }+ | Expose {rect::Rect, count::Int}+ | NoExpose+ | VisibilityNotify Visibility+ | CreateNotify Window+ | DestroyNotify Window+ | UnmapNotify Window+ | MapNotify Window+ | MapRequest Window+ | ReparentNotify+ | ConfigureNotify Rect Int+ | ConfigureRequest+ | GravityNotify+ | ResizeRequest Point+ | CirculateNotify+ | CirculateRequest+ | PropertyNotify+ | SelectionClear Atom+ | SelectionRequest Time Window Selection+ | SelectionNotify Time Selection+ | ColormapNotify+ | ClientMessage Atom ClientData+ | MappingNotify+ -- Pseudo event below:+-- | IOResponse Response+--+-- | LayoutPlace Rect+-- | LayoutSize Size+-- | LayoutPos Point -- Position in parent window. Occationally useful.+ | YourWindowId Window+ | MenuPopupMode Bool -- used by buttonmachine to adjust its behaviour+ deriving (Show,Read)++type Event = XEvent++data XResponse+ = DisplayOpened Display+ | WindowCreated Window+ | GCCreated GCId+ | CursorCreated CursorId+ | PointerGrabbed GrabPointerResult+ | FontLoaded FontId+ | LMLFontQueried FontStruct+ | ColorAllocated (Maybe Color)+ | PixmapCreated PixmapId+ | BitmapRead BitmapReturn+ | RmDatabaseCreated RmDatabase+ | GotResource (Maybe (String, RmValue))+ | CoordinatesTranslated Point+ | GotAtom Atom+ | GotAtomName (Maybe String)+ | GotEvent (Window, XEvent)+ | GotWindowProperty Atom Int Int Int String+ | PointerQueried Bool Point Point ModState+ | FontQueried (Maybe FontStructList)+ | ColorQueried Color+ | TreeQueried Window Window [Window] -- root parent children+ | GotDefaultRootWindow Window+ | GotGeometry Rect Int Int+ | GotVisual Visual+ | Synced+ | TextExtents16Queried Int Int CharStruct -- ascent descent overall+ | GotFontList [FontName]+ | GotFontListWithInfo [(FontName,FontStructList)]+-- | GotFontListWithInfo [(FontStructList)]+ | DbeExtensionQueried Int Int Int -- status (/=0 means ok), major, minor+ | DbeBuffersSwapped Int -- status (useless?)+ | DbeBackBufferNameAllocated DbeBackBufferId+ deriving (Show,Read)++data BitmapReturn+ = BitmapBad+ | BitmapReturn Size (Maybe Point) PixmapId + deriving (Eq, Ord, Show, Read)+
+ hsrc/xtypes/EventMask.hs view
@@ -0,0 +1,37 @@+module EventMask where++-- Same order as in X+data EventMask = KeyPressMask |+ KeyReleaseMask |+ ButtonPressMask |+ ButtonReleaseMask |+ EnterWindowMask |+ LeaveWindowMask |+ PointerMotionMask |+ PointerMotionHintMask |+ Button1MotionMask |+ Button2MotionMask |+ Button3MotionMask |+ Button4MotionMask |+ Button5MotionMask |+ ButtonMotionMask |+ KeymapStateMask |+ ExposureMask |+ VisibilityChangeMask |+ StructureNotifyMask |+ ResizeRedirectMask |+ SubstructureNotifyMask |+ SubstructureRedirectMask |+ FocusChangeMask |+ PropertyChangeMask |+ ColormapChangeMask |+ OwnerGrabButtonMask + deriving (Eq, Ord, Show, Read, Bounded, Enum)++clEventMask =+ [KeyPressMask, KeyReleaseMask, ButtonPressMask, ButtonReleaseMask, EnterWindowMask,+ LeaveWindowMask, PointerMotionMask, PointerMotionHintMask, Button1MotionMask,+ Button2MotionMask, Button3MotionMask, Button4MotionMask, Button5MotionMask,+ ButtonMotionMask, KeymapStateMask, ExposureMask, VisibilityChangeMask, StructureNotifyMask,+ ResizeRedirectMask, SubstructureNotifyMask, SubstructureRedirectMask, FocusChangeMask,+ PropertyChangeMask, ColormapChangeMask, OwnerGrabButtonMask]
+ hsrc/xtypes/FRequest.hs view
@@ -0,0 +1,34 @@+-- | Fudget low-level message types+module FRequest(+ module FRequest,+ XCommand,XEvent,XRequest,XResponse,+ SocketRequest,SocketResponse,+ LayoutMessage,LayoutResponse+ --AsyncInput(..)+) where+import Command(XCommand,XRequest)+import Event(XEvent,XResponse)+import Sockets(SocketRequest,SocketResponse{-,AsyncInput-})+import DialogueIO(Request,Response)+import LayoutRequest(LayoutMessage(..),LayoutResponse)++data FRequest+ = XCmd XCommand+ | LCmd LayoutMessage+ -- asynchronous above, synchronous below, but see ../internal/IsRequest.hs+ | XReq XRequest+ | SReq SocketRequest+ | DReq Request+ deriving Show++data FResponse+ = XEvt XEvent+ | LEvt LayoutResponse+-- | SEvt AsyncInput -- still represented as DResp (AsyncInput ...)+ -- asynchronous above, synchronous below, but see ../internal/IsRequest.hs+ | XResp XResponse+ | SResp SocketResponse+ | DResp Response+ deriving Show++layoutRequestCmd = LCmd . LayoutRequest
+ hsrc/xtypes/Image.hs view
@@ -0,0 +1,7 @@+module Image where++newtype ImageFormat = ImageFormat Int deriving (Eq, Ord, Read, Show)++xyBitmap = ImageFormat 0+xyPixmap = ImageFormat 1+zPixmap = ImageFormat 2
+ hsrc/xtypes/ResourceIds.hs view
@@ -0,0 +1,44 @@+module ResourceIds where+--import Data.Word(Word32)++newtype XID = XID Int deriving (Eq,Ord)++instance Show XID where showsPrec d (XID w32) = showsPrec d w32+instance Read XID where readsPrec d s = [(XID w,r)|(w,r)<-readsPrec d s]++newtype WindowId = WindowId XID deriving (Eq, Ord, Show, Read)++type Window = WindowId+type XWId = WindowId++rootWindow = WindowId (XID 0)+noWindow = WindowId (XID (-1))+windowNone = WindowId (XID 0)++newtype PixmapId = PixmapId XID deriving (Eq, Ord, Show, Read)+newtype DbeBackBufferId = DbeBackBufferId XID deriving (Eq, Ord, Show, Read)+newtype FontId = FontId XID deriving (Eq, Ord, Read, Show)+newtype GCId = GCId Int deriving (Eq, Ord, Read, Show)+newtype CursorId = CursorId XID deriving (Eq, Ord, Read, Show)+newtype ColormapId = ColormapId XID deriving (Eq, Ord, Read, Show)++defaultColormap = ColormapId (XID 0)+cursorNone = CursorId (XID 0)++newtype Atom = Atom Int deriving (Eq, Ord, Show, Read)+++type ColorName = String+type FontName = String++type Time = Int+currentTime = 0::Time++type Depth = Int++copyFromParent = 0 :: Depth+parentRelative = PixmapId (XID 1)+none = PixmapId (XID 0)++rootGC = GCId 0+
+ hsrc/xtypes/Sockets.hs view
@@ -0,0 +1,68 @@+module Sockets(DLValue,module Sockets) where+import Event(XEvent)+import Xtypes(WindowId,Display)+import PackedString(PackedString)+import DLValue+import System.Posix.DynamicLinker(DL)++-- NOTE: Matching definitions for the C world appear in xlib/sockets.h --------++data SocketRequest = OpenLSocket Port -- -> SR LSocket+ | OpenSocket Host Port -- -> SR Socket+ | WriteSocket Socket String -- -> SR Success+ | CloseSocket Socket -- -> SR Success+ | CloseLSocket LSocket -- -> SR Success+ | GetStdinSocket -- -> SR Socket+ | CreateTimer Int Int -- -> SR Timer+ | DestroyTimer Timer -- -> Success+ | GetLSocketName LSocket -- -> Str+ | GetSocketName Socket -- -> Str+ | StartProcess String Bool Bool Bool -- -> ProcessSockets+ | DLOpen String -- -> SR DLHandle+ | DLClose DLHandle -- -> Success+ | DLSym DLHandle String -- -> SR DLValue+ | OpenFileAsSocket String String -- -> SR Socket+ -- name, mode (as in fopen(name,mode))+ | WriteSocketPS Socket PackedString -- -> SR Wrote+ | GetStdoutSocket -- -> SR Socket+ deriving (Show,Read)++data SocketResponse = LSocket LSocket+ | Socket Socket+ | Timer Timer+ | ProcessSockets (Maybe Socket) (Maybe Socket) (Maybe Socket)+ | DLHandle DLHandle+ | DLVal DLValue+ | Wrote Int+ deriving (Show,Read) --(Eq, Ord, Text)++type Port = Int+type Host = String+type Peer = Host++newtype Socket = So Int deriving (Eq,Ord,Show,Read)+newtype LSocket = LSo Int deriving (Eq,Ord,Show,Read)++newtype Timer = Ti Int deriving (Eq,Ord,Show,Read)++type AsyncInput = (Descriptor, AEvent)++data Descriptor+ = LSocketDe LSocket+ | SocketDe Socket+ | OutputSocketDe Socket+ | TimerDe Timer+ | DisplayDe Display + deriving (Eq, Ord, Read, Show)++data AEvent+ = SocketAccepted Socket Peer+ | SocketRead String+ | SocketWritable+ | TimerAlarm+ | XEvent (WindowId, XEvent) + deriving (Show,Read)++newtype DLHandle = DL DL deriving Show++instance Read DLHandle
+ hsrc/xtypes/Visual.hs view
@@ -0,0 +1,19 @@+module Visual where+import HbcWord++data DisplayClass+ = StaticGray | GrayScale+ | StaticColor | PseudoColor+ | TrueColor | DirectColor+ deriving (Eq,Show,Read,Bounded,Enum)++newtype VisualID = VisualID Int deriving (Eq,Show,Read)++data Visual+ = Visual { visualid :: VisualID,+ visualClass :: DisplayClass,+ red_mask,green_mask,blue_mask :: Word,+ bits_per_rgb :: Int,+ map_entries :: Int+ }+ deriving (Show,Read)
+ hsrc/xtypes/XDraw.hs view
@@ -0,0 +1,20 @@+module XDraw(module DrawTypes,module XDraw) where+import Command(XCommand(Draw,DrawMany,ClearArea,ClearWindow))+import FRequest+import Geometry(Rect(..),Point(..))+import DrawTypes++draw d gc dcmd = XCmd (Draw d gc dcmd)+drawMany d dcmds = XCmd (DrawMany d dcmds)++wDraw = draw MyWindow+wDrawMany = drawMany MyWindow++pmDraw = draw . Pixmap +pmDrawMany = drawMany . Pixmap++clearArea r b = XCmd (ClearArea r b)+clearWindow = XCmd ClearWindow++fillCircle p r = FillArc (Rect p (Point r r)) 0 (64 * 360)+drawCircle p r = DrawArc (Rect p (Point r r)) 0 (64 * 360)
+ hsrc/xtypes/XStuff.hs view
@@ -0,0 +1,8 @@+module XStuff(XCommand,XEvent,XWId(..),WindowId,XRequest,XResponse,AsyncInput(..),AEvent,SocketRequest,Descriptor,SocketResponse,XDisplay(..),Display) where+import Command+import Event+import Sockets+import Xtypes++-- This file part is NOT part of the Fudget library. It is used+-- to create an interface file for use in the Prelude construction.
+ hsrc/xtypes/XTypesModules.hs view
@@ -0,0 +1,11 @@+module XTypesModules (-- * X types+ module FRequest,module Command,module Event,module Sockets ,module Xtypes,module Visual,module XDraw,module DrawInPixmap, module DrawInWindow) where+import FRequest+import Command+import Event+import Sockets+import Xtypes+import Visual+import XDraw+import DrawInPixmap+import DrawInWindow
+ hsrc/xtypes/Xtypes.hs view
@@ -0,0 +1,164 @@+module Xtypes(module Xtypes,module EventMask,module AuxTypes,module ResourceIds,module Image) where+--import Geometry(Line, Point, Rect)+import EventMask+import AuxTypes+import ResourceIds+import Image+import Data.Ix+import HbcWord++-- #ifdef __NHC__+-- Bug in export of newtype+-- #define newtype data+-- #endif++newtype Display = Display Int deriving (Eq, Ord, Show, Read)+type XDisplay = Display++noDisplay = Display (-1)++type KeyLookup = String+type Width = Int++newtype Pixel = Pixel Word deriving (Eq, Ord, Show, Read)++type PlaneMask = Pixel++pixel0 = Pixel 0+pixel1 = Pixel 1+--black = Pixel 0 -- not always true !!+--white = Pixel 1 -- not always true !!++data RGB = RGB Int Int Int deriving ( Eq, Ord, Show, Read, Ix )+data Color = Color { colorPixel::Pixel, colorRGB::RGB }+ deriving (Eq, Ord, Show, Read)++maxRGB :: Int -- for hugs+maxRGB = 65535+grayRGB x = RGB x x x+whiteRGB = grayRGB maxRGB+blackRGB = grayRGB 0++data Selection = Selection Atom Atom Atom deriving (Eq, Ord, Show, Read)+++newtype PropertyMode = PropertyMode Int deriving (Eq, Ord, Show, Read)++propModeReplace = PropertyMode 0+propModePrepend = PropertyMode 1+propModeAppend = PropertyMode 2++--data EventMask -- moved to EventMask.hs++data BackingStore+ = NotUseful | WhenMapped | Always + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data GrabPointerResult+ = GrabSuccess+ | AlreadyGrabbed+ | GrabInvalidTime+ | GrabNotViewable+ | GrabFrozen + deriving (Eq, Ord, Show, Read, Bounded, Enum)++-- Same order as in X.h+data GCFunction+ = GXclear+ | GXand+ | GXandReverse+ | GXcopy+ | GXandInverted+ | GXnoop+ | GXxor+ | GXor+ | GXnor+ | GXequiv+ | GXinvert+ | GXorReverse+ | GXCopyInverted+ | GXorInverted+ | GXnand+ | GXset + deriving (Eq, Ord, Show, Read, Bounded, Enum)+++-- Same order as in X.h+data GCLineStyle+ = LineSolid | LineDoubleDash | LineOnOffDash + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data GCCapStyle+ = CapNotLast | CapButt | CapRound | CapProjecting + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data GCJoinStyle+ = JoinMiter | JoinRound | JoinBevel+ deriving (Eq, Ord, Show, Read, Bounded, Enum)+ +data GCSubwindowMode+ = ClipByChildren | IncludeInferiors + deriving (Eq, Ord, Show, Read, Bounded, Enum)++data GCFillStyle+ = FillSolid | FillTiled | FillStippled | FillOpaqueStippled+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++data GCAttributes a b+ = GCFunction GCFunction+ | GCForeground a+ | GCBackground a+ | GCLineWidth Width+ | GCLineStyle GCLineStyle+ | GCFont b+ | GCCapStyle GCCapStyle+ | GCSubwindowMode GCSubwindowMode+ | GCGraphicsExposures Bool+ | GCFillStyle GCFillStyle+ | GCTile PixmapId+ | GCStipple PixmapId+ | GCJoinStyle GCJoinStyle+ deriving (Eq, Ord, Show, Read)++type GCAttributeList = [GCAttributes Pixel FontId]++--invertGCattrs = invertColorGCattrs white black++invertColorGCattrs bgcol fgcol =+ [GCFunction GXxor, GCForeground (invcol bgcol fgcol)]++invcol (Pixel bg) (Pixel fg) = Pixel (bitXor bg fg)++data WindowAttributes+ = CWEventMask [EventMask]+ | CWBackingStore BackingStore+ | CWSaveUnder Bool+ | CWDontPropagate [EventMask]+ | CWOverrideRedirect Bool+ | CWBackPixel Pixel+ | CWCursor CursorId+ | CWBitGravity Gravity+ | CWWinGravity Gravity+ | CWBackPixmap PixmapId+ | CWBorderPixmap PixmapId+ | CWBorderPixel Pixel+ deriving (Eq, Ord, Show, Read)++data WindowChanges+ = CWX Int+ | CWY Int+ | CWWidth Int+ | CWHeight Int+ | CWBorderWidth Int+ | CWStackMode StackMode + deriving (Eq, Ord, Show, Read)++data StackMode+ = StackAbove | StackBelow | TopIf | BottomIf | Opposite + deriving (Eq, Ord, Read, Show, Bounded, Enum)+++-- DBE (double buffering extension):+data SwapAction+ = DbeUndefined | DbeBackground | DbeUntouched | DbeCopied+ deriving (Eq, Ord, Show, Read, Bounded, Enum)
+ xlib/fdzero.c view
@@ -0,0 +1,53 @@+#include <sys/types.h>+#include <errno.h>+#include <stdio.h>+#include <X11/Xlib.h>+#include <X11/Xutil.h>+#ifdef __MACH__+#include <sys/time.h>+#endif++/* For use in ghc-dialogue/AsyncInput.hs since+ calling FD_ZERO from _casm_ doesn't work with ghc on Linux-386. gcc+ compilains about a spilled register. /TH 2000-03-17++ Used for more functions after getting rid of _casm_/_ccall_ for GHC 6.2... + /TH 2004-03-25+*/++void fdzero(fd_set *s) { FD_ZERO(s); }+void fdset(int fd,fd_set *s) { FD_SET(fd,s); }+int fdisset(int fd,fd_set *s) { return FD_ISSET(fd,s); }+/* void bcopy_fdset(fd_set *src,fd_set *dst) { bcopy(src,dst,sizeof(fd_set)); } */+void bcopy_fdset(fd_set *src,fd_set *dst) { *dst=*src; }++int get_errno(void) { return errno; }+long get_stdin(void) { return (long)stdin; }+int get_fileno(long f) { return fileno((FILE *)f); }++void xDestroyImage(XImage *ximage) { XDestroyImage(ximage); }+void setXImage_data(XImage *ximage,char *data) { ximage->data=data; }++int default_bpp(Display *d,int depth) {+ int i,cnt,bpp;+ XPixmapFormatValues *ps=XListPixmapFormats(d,&cnt);+ bpp=depth; /* Hmm. Something is wrong if depth isn't found. */+ for(i=0;i<cnt;i++)+ if(ps[i].depth==depth) {+ bpp=ps[i].bits_per_pixel;+ break;+ }+ XFree(ps);+ /*fprintf(stderr,"default_bpp(%d,%d)=%d\n",(int)d,depth,bpp);*/+ return bpp;+}++void disable_timers(void) {+#ifdef __MACH__+ /* Disable timers set up by the GHC RTS. */+ struct itimerval zero;+ timerclear(&zero.it_interval);+ timerclear(&zero.it_value);+ setitimer(ITIMER_VIRTUAL,&zero,NULL);+#endif+}
+ xlib/socketlib/defs.h view
@@ -0,0 +1,18 @@+/*+ * (c) Copyright 1991 by Panagiotis Tsirigotis+ * Read the file COPYRIGHT for more details.+ * + */+/*+ * $Header: /home/magnus/cvs/Fudgets/xlib/socketlib/defs.h,v 1.1.1.1 1996-03-10 16:56:13 magnus Exp $+ */++#define SYSCALL_ERROR -1+#define RESOLVER_ERROR -2+#define OPTION_ERROR -3++/*+ * How many times to try gethostbyname+ */+#define MAX_TRIES 3+
+ xlib/socketlib/inet.c view
@@ -0,0 +1,404 @@+/*+ * (c) Copyright 1991 by Panagiotis Tsirigotis+ * Read the file COPYRIGHT for more details.+ * + */+/*+ * Internet support library.+ *+ * INTERFACE:+ *+ * in_address : form an internet address+ * in_bind : bind a socket to an internet address+ * in_bind_opt : bind a socket to an internet address and+ * set (for now, binary) options+ * in_connect : connect to an internet address+ * in_connect_opt : connect to an internet address and+ * set (for now, binary) options+ *+ */+++#include <sys/types.h>+#include <sys/socket.h>+#include <netinet/in.h>+#include <arpa/inet.h>+#include <netdb.h>+/* #include <stdarg.h> */+#include <stdio.h>+#include <ctype.h>+#include <string.h>+#include <unistd.h>+#include <errno.h> /* on some systems, errno is not a variable */+/* extern int errno ; */++#include <sys/param.h>+#ifdef MAXHOSTNAMELEN+#define HOST_NAME_LEN MAXHOSTNAMELEN+#else+#define HOST_NAME_LEN 32+#endif++#include "defs.h"++#if defined(__NetBSD__) || defined(_HPUX_SOURCE)+extern int h_errno;+#endif++/*+ * $Header: /home/magnus/cvs/Fudgets/xlib/socketlib/inet.c,v 1.7 2013-07-28 12:09:13 hallgren Exp $+ */++#define PRIVATE static++static char *version = VERSION ;++enum status_e { OK, ERROR } ;+++/*+ * Close a file descriptor without destroying errno+ */+#define CLOSE( sd, t ) t = errno ; \+ (void) close( sd ) ; \+ errno = t+#ifndef FALSE+#define FALSE 0+#define TRUE 1+#endif+++/*+ * Returns TRUE if the host argument has the form:+ * <num>.<num>+ * <num>.<num>.<num>+ * <num>.<num>.<num>.<num>+ */+PRIVATE int is_number_address( host )+ char *host ;+{+ register int dot_count = 0 ;+ register char *p ;++ if ( host == NULL )+ return( FALSE ) ;+ + for ( p = host ; *p ; p++ )+ if ( isascii( *p ) && isdigit( *p ) ) /* skip digits */+ continue ;+ else if ( *p == '.' ) /* count dots */+ {+ dot_count++ ;+ if ( dot_count > 3 )+ return( FALSE ) ;+ }+ else /* reject everything else */+ return( FALSE ) ;+ return( dot_count > 0 ) ;+}++++/*+ * Form an Internet address.+ * If host is NULL, the current host is assumed (but this does not+ * guarantee the use of the loopback address)+ *+ * Return value:+ * 0 : if successful+ * RESOLVER_ERROR : if an error occurs+ *+ * In case of error, errno is set to the value of h_errno, if the OS+ * supports h_errno; if not, the value of errno is undefined.+ */+int in_address( host, port, address )+ char *host ;+ short port ;+ struct sockaddr_in *address ;+{+ char host_name[ HOST_NAME_LEN ] ;+ char *the_host ;+ struct hostent *hp ;++ bzero( (char *) address, sizeof( *address ) ) ;++ /*+ * Determine the host name+ */+ if ( host == NULL )+ {+ (void) gethostname( host_name, HOST_NAME_LEN ) ;+ the_host = host_name ;+ }+ else+ the_host = host ;+ + /*+ * Get host address+ */+ if ( is_number_address( host ) )+ address->sin_addr.s_addr = inet_addr( host ) ;+ else+ {++#ifndef HAS_H_ERRNO+ if ( ( hp = gethostbyname( the_host ) ) == NULL )+ return( RESOLVER_ERROR ) ;+#else+ int tries = 0 ;++ while ( ( hp = gethostbyname( the_host ) ) == NULL &&+ (h_errno == TRY_AGAIN+#if __FreeBSD__ == 2+ /* Needed because of FreeBSD 2.2-961014-SNAP bug? */+ || h_errno == NETDB_INTERNAL+#endif+ ) &&+ tries < MAX_TRIES )+ tries++ ;+ if ( hp == NULL )+ {+ errno = h_errno ;+ return( RESOLVER_ERROR ) ;+ }+#endif /* HAS_H_ERRNO */++ bcopy( hp->h_addr, (char *) &address->sin_addr, hp->h_length ) ;+ }++ address->sin_family = AF_INET ;+ address->sin_port = htons( port ) ;++ return( 0 ) ;+}++++/*+ * Bind an internet address. Port is the port that will be used; the+ * address is that of the machine the program runs on.+ * Type is the type of socket; this also defines the protocol+ * that will be used (i.e. for SOCK_STREAM use TCP etc)+ *+ * Return value:+ * a file descriptor : if the operation is successful+ * SYSCALL_ERROR : if there is a system call error+ * RESOLVER_ERROR : if there is a resolver error+ * In case of error, errno contains a description of the error+ */+PRIVATE int bind_address() ;++int in_bind( port, type )+ short port ;+ int type ;+{+ int sd ;++ if ( ( sd = socket( AF_INET, type, 0 ) ) == -1 )+ return( SYSCALL_ERROR ) ;+ + return( bind_address( sd, port ) ) ;+}++#if 0+PRIVATE va_list apply_options() ;+#endif++/*+ * Same as in_bind but also sets socket-level options.+ * The option list is a list of pairs (option, option_value) terminated+ * by NULL.+ */+#if 0+int in_bind_opt( port, type, va_alist )+ short port ;+ int type ;+ va_dcl+{+ int sd ;+ enum status_e status ;+ va_list ap ;+ + if ( ( sd = socket( AF_INET, type, 0 ) ) == -1 )+ return( SYSCALL_ERROR ) ;+ + va_start( ap ) ;+ ap = apply_options( sd, ap, &status );+ va_end( ap ) ;+ if ( status == ERROR )+ return( OPTION_ERROR ) ;++ return( bind_address( sd, port ) ) ;+}+#endif++++/*+ * bind_address binds the address <INADDR_ANY,port> to a socket.+ * Return value:+ * socket : if successful+ * SYSCALL_ERROR : if bind fails+ * RESOLVER_ERROR : if it can't get the address of the local host+ */+PRIVATE int bind_address( sd, port )+ int sd ;+ short port ;+{+ struct sockaddr_in sin ;+ int errno_save ;++ sin.sin_family = AF_INET ;+ sin.sin_addr.s_addr = INADDR_ANY ;+ sin.sin_port = htons( port ) ;++ if ( bind( sd, (struct sockaddr *) &sin, sizeof( sin ) ) == -1 )+ {+ CLOSE( sd, errno_save ) ;+ return( SYSCALL_ERROR ) ;+ }+ return( sd ) ;+}+++/*+ * Apply the options in the option_list.+ * Return value:+ * The remaining part of the argument list+ *+ * The status argument shows if there has been an error.+ * In case of error, the socket is closed.+ */+#if 0+PRIVATE va_list apply_options( sd, option_list, status )+ int sd ;+ va_list option_list ;+ enum status_e *status ;+{+ register int option ;+ int errno_save ;++ /*+ * Apply the options+ */+ while ( ( option = va_arg( option_list, int ) ) != NULL )+ {+ int option_value ;++ /*+ * For the moment accept only boolean options+ */+ switch ( option )+ {+ case SO_DEBUG:+ case SO_REUSEADDR:+ case SO_KEEPALIVE:+ case SO_DONTROUTE:+ case SO_BROADCAST:+ case SO_OOBINLINE:+ option_value = va_arg( option_list, int ) ;+ if ( setsockopt( sd, SOL_SOCKET, option,+ &option_value, sizeof( option_value ) ) == -1 )+ {+ CLOSE( sd, errno_save ) ;+ *status = ERROR ;+ return( option_list ) ;+ }+ break ;++ default:+ break ;+ }+ }+ *status = OK ;+ return( option_list ) ;+}+#endif++PRIVATE int connect_to_host() ;++/*+ * Connect to an internet address. The address is specified by the+ * host, port arguments. Type is the type of the socket which+ * defines the type of the protocol to be used.+ * If host is NULL, then the local host is implied.+ *+ * Return value:+ * a file descriptor : if the operation is successful+ * SYSCALL_ERROR : if there is a system call error+ * RESOLVER_ERROR : if there is a resolver error+ * In case of error errno contains a description of the error+ */+int in_connect( host, port, type )+ char *host ;+ short port ;+ int type ;+{+ int sd ;++ if ( ( sd = socket( AF_INET, type, 0 ) ) == -1 )+ return( SYSCALL_ERROR ) ;+ + return( connect_to_host( sd, host, port ) ) ;+}++++/*+ * Same as in_connect but also sets socket-level options+ */+#if 0+int in_connect_opt( host, port, type, va_alist )+ char *host ;+ short port ;+ int type ;+ va_dcl+{+ int sd ;+ enum status_e status ;+ va_list ap ;+ int connect_to_host() ;+ va_list apply_options() ;++ if ( ( sd = socket( AF_INET, type, 0 ) ) == -1 )+ return( SYSCALL_ERROR ) ;+ + va_start( ap ) ;+ ap = apply_options( sd, ap, &status ) ;+ va_end( ap ) ;+ if ( status == ERROR )+ return( OPTION_ERROR ) ;+ + return( connect_to_host( sd, host, port ) ) ;+}+#endif++/*+ * connect_to_host tries to connect socket sd to the address <host,port>+ * Return value:+ * socket : if the operation is successful+ * RESOLVER_ERROR : if there is a resolver error+ * SYSCALL_ERROR : if connect(2) fails+ */+PRIVATE int connect_to_host( sd, host, port )+ int sd ;+ char *host ;+ short port ;+{+ struct sockaddr_in sin ;+ int errno_save ;++ if ( in_address( host, port, &sin ) == RESOLVER_ERROR )+ {+ CLOSE( sd, errno_save ) ;+ return( RESOLVER_ERROR ) ;+ }++ if ( connect( sd, (struct sockaddr *) &sin, sizeof( sin ) ) == -1 )+ {+ CLOSE( sd, errno_save ) ;+ return( SYSCALL_ERROR ) ;+ }+ return( sd ) ;+}+