-- Change the root window background to a random solid colour. import System.Random import System.Environment (getArgs) import Control.Applicative import Data.Bits import Graphics.X11.Xlib.Window import Graphics.X11.Xlib.Display import Graphics.X11.Xlib.Types -- These are the bounds on the random generation of values. data Values = V { sat :: (Double, Double) -- ^ Saturation, valid values in [0..1] , hue :: (Double, Double) -- ^ Hue, valid values in [0..365] , val :: (Double, Double) -- ^ Value, valid values in [0..1] } -- Default bounds. defaultValues = V { sat = (0.12, 0.30) , hue = (0, 365) , val = (0.5, 0.7) } data HSV = HSV Double Double Double deriving Read instance Show HSV where show = hsv2hex data RGB = RGB Double Double Double instance Show RGB where show = rgb2hex -- Convert a HSV colour to its hexadecimal representation. hsv2hex :: HSV -> String hsv2hex = rgb2hex . hsv2rgb -- Convert a RGB colour value into its hexadecimal representation. rgb2hex :: RGB -> String rgb2hex (RGB r g b) = "#" ++ r' ++ g' ++ b' where r' = table !! (floor (r * 255)) g' = table !! (floor (g * 255)) b' = table !! (floor (b * 255)) table = [ x:y:[] | x <- "0123456789abcdef", y <- "0123456789abcdef" ] hsv2rgb :: HSV -> RGB hsv2rgb (HSV h s v) = case h' of 0 -> RGB v t p 1 -> RGB q v p 2 -> RGB p v t 3 -> RGB p q v 4 -> RGB t p v _ -> RGB v p q where p = v * (1 - s) q = v * (1 - f * s) t = v * (1 - (1 - f) * s) f = (h / 60) - (fromIntegral (floor (h / 60))) h' = floor (h / 60) `mod` 6 hsv2pixel :: HSV -> Pixel hsv2pixel hsv = sum $ map (\(pos, val) -> shiftL (floor (255 * val)) (8 * fromIntegral pos)) bits where (RGB r g b) = hsv2rgb hsv bits = zip [0,1,2] [b,g,r] randcolour :: Values -> IO HSV randcolour v = do h <- randomRIO (fst $ hue v, snd $ hue v) s <- randomRIO (fst $ sat v, snd $ sat v) v <- randomRIO (fst $ val v, snd $ val v) return $ HSV h s v randsolid :: Values -> IO () randsolid v = do dpy <- openDisplay "" root <- rootWindow dpy $ defaultScreen dpy setWindowBackground dpy root . hsv2pixel =<< randcolour v clearWindow dpy root closeDisplay dpy main = do args <- getArgs if args == ["-p"] || args == ["--print"] then putStrLn . show =<< randcolour defaultValues else randsolid defaultValues