fudgets-0.18.4: hsrc/ghc-dialogue/DoXCommand.hs
{-# 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