{-# LANGUAGE CPP #-} -- -*-haskell-*- -- GIMP Toolkit (GTK) Display - a description of a keyboard/mouse/monitors combination -- -- Author : Axel Simon -- -- Created: 22 October 2009 -- -- Copyright (C) 2009 Axel Simon -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- | -- Maintainer : gtk2hs-users@lists.sourceforge.net -- Stability : provisional -- Portability : portable (depends on GHC) -- -- Controls the keyboard\/mouse\/monitors combination. -- -- * Module available since Gdk version 2.2 -- module Graphics.UI.Gtk.Gdk.Display ( -- * Detail -- -- | 'Display' objects purpose are two fold: -- -- * To grab\/ungrab keyboard focus and mouse pointer -- -- * To manage and provide information about the 'Screen'(s) available for -- this 'Display' -- -- 'Display' objects are the GDK representation of the X Display which can -- be described as /a workstation consisting of a keyboard a pointing device -- (such as a mouse) and one or more screens/. It is used to open and keep -- track of various 'Screen' objects currently instanciated by the application. -- It is also used to grab and release the keyboard and the mouse pointer. -- * Class Hierarchy -- -- | -- @ -- | 'GObject' -- | +----Display -- @ #if GTK_CHECK_VERSION(2,2,0) -- * Types Display, DisplayClass, castToDisplay, gTypeDisplay, toDisplay, -- * Methods displayOpen, displayGetDefault, displayGetName, displayGetNScreens, displayGetScreen, displayGetDefaultScreen, displayPointerUngrab, displayKeyboardUngrab, displayPointerIsGrabbed, displayBeep, displaySync, #if GTK_CHECK_VERSION(2,4,0) displayFlush, #endif displayClose, displayListDevices, displaySetDoubleClickTime, #if GTK_CHECK_VERSION(2,4,0) displaySetDoubleClickDistance, #endif displayGetPointer, displayGetWindowAtPointer, #if GTK_CHECK_VERSION(2,8,0) displayWarpPointer, #endif #if GTK_CHECK_VERSION(2,4,0) displaySupportsCursorColor, displaySupportsCursorAlpha, displayGetDefaultCursorSize, displayGetMaximalCursorSize, displayGetDefaultGroup, #if GTK_CHECK_VERSION(2,6,0) displaySupportsSelectionNotification, displayRequestSelectionNotification, displaySupportsClipboardPersistence, displayStoreClipboard, #if GTK_CHECK_VERSION(2,10,0) displaySupportsShapes, displaySupportsInputShapes, #if GTK_CHECK_VERSION(2,12,0) displaySupportsComposite, #endif #endif #endif #endif -- * Signals displayClosed, #endif ) where import Control.Monad (liftM) import System.Glib.FFI import System.Glib.UTFString import System.Glib.Flags import System.Glib.GList {#import Graphics.UI.Gtk.Types#} import Graphics.UI.Gtk.Signals import Graphics.UI.Gtk.Gdk.EventM import Graphics.UI.Gtk.Gdk.Enums (Modifier(..)) import Graphics.UI.Gtk.General.DNDTypes (SelectionTag, TargetTag, Atom(..)) {# context lib="gdk" prefix="gdk" #} #if GTK_CHECK_VERSION(2,2,0) -------------------- -- Methods -- | Opens a display. -- displayOpen :: GlibString string => string -- ^ @displayName@ - the name of the display to open -> IO (Maybe Display) -- ^ returns a 'Display', or @Nothing@ if the display -- could not be opened. displayOpen displayName = maybeNull (wrapNewGObject mkDisplay) $ withUTFString displayName $ \displayNamePtr -> {# call gdk_display_open #} displayNamePtr -- | Gets the default 'Display'. This is a convenience function for -- @displayManagerGetDefaultDisplay displayManagerGet@. -- displayGetDefault :: IO (Maybe Display) -- ^ returns a 'Display', or @Nothing@ if there is no -- default display. displayGetDefault = maybeNull (makeNewGObject mkDisplay) $ {# call gdk_display_get_default #} -- | Gets the name of the display. -- displayGetName :: GlibString string => Display -> IO string -- ^ returns a string representing the display name displayGetName self = {# call gdk_display_get_name #} self >>= peekUTFString -- | Gets the number of screen managed by the @display@. -- displayGetNScreens :: Display -> IO Int -- ^ returns number of screens. displayGetNScreens self = liftM fromIntegral $ {# call gdk_display_get_n_screens #} self -- | Returns a screen object for one of the screens of the display. -- displayGetScreen :: Display -> Int -- ^ @screenNum@ - the screen number -> IO Screen -- ^ returns the 'Screen' object displayGetScreen self screenNum = makeNewGObject mkScreen $ {# call gdk_display_get_screen #} self (fromIntegral screenNum) -- | Get the default 'Screen' for @display@. -- displayGetDefaultScreen :: Display -> IO Screen -- ^ returns the default 'Screen' object for @display@ displayGetDefaultScreen self = makeNewGObject mkScreen $ {# call gdk_display_get_default_screen #} self -- | Release any pointer grab. -- displayPointerUngrab :: Display -> TimeStamp -- ^ @time@ - a timestap (e.g. 'currentTime'). -> IO () displayPointerUngrab self time = {# call gdk_display_pointer_ungrab #} self (fromIntegral time) -- | Release any keyboard grab -- displayKeyboardUngrab :: Display -> TimeStamp -- ^ @time@ - a timestap (e.g 'currentTime'). -> IO () displayKeyboardUngrab self time = {# call gdk_display_keyboard_ungrab #} self (fromIntegral time) -- | Test if the pointer is grabbed. -- displayPointerIsGrabbed :: Display -> IO Bool -- ^ returns @True@ if an active X pointer grab is in effect displayPointerIsGrabbed self = liftM toBool $ {# call gdk_display_pointer_is_grabbed #} self -- | Emits a short beep on @display@ -- displayBeep :: Display -> IO () displayBeep self = {# call gdk_display_beep #} self -- | Flushes any requests queued for the windowing system and waits until all -- requests have been handled. This is often used for making sure that the -- display is synchronized with the current state of the program. Calling -- 'displaySync' before 'errorTrapPop' makes sure that any errors generated -- from earlier requests are handled before the error trap is removed. -- -- This is most useful for X11. On windowing systems where requests are -- handled synchronously, this function will do nothing. -- displaySync :: Display -> IO () displaySync self = {# call gdk_display_sync #} self #if GTK_CHECK_VERSION(2,4,0) -- | Flushes any requests queued for the windowing system; this happens -- automatically when the main loop blocks waiting for new events, but if your -- application is drawing without returning control to the main loop, you may -- need to call this function explicitely. A common case where this function -- needs to be called is when an application is executing drawing commands from -- a thread other than the thread where the main loop is running. -- -- This is most useful for X11. On windowing systems where requests are -- handled synchronously, this function will do nothing. -- -- * Available since Gdk version 2.4 -- displayFlush :: Display -> IO () displayFlush self = {# call gdk_display_flush #} self #endif -- | Closes the connection to the windowing system for the given display, and -- cleans up associated resources. -- displayClose :: Display -> IO () displayClose self = {# call gdk_display_close #} self -- | Returns the list of available input devices attached to @display@. -- displayListDevices :: Display -> IO [Device] -- ^ returns a list of 'Device' displayListDevices self = {# call gdk_display_list_devices #} self >>= readGList >>= mapM (makeNewGObject mkDevice . return) -- | Sets the double click time (two clicks within this time interval count as -- a double click and result in an 'eventButton' where 'eventClick' is -- 'DoubleClick'). Applications should /not/ set this, it is a global -- user-configured setting. -- displaySetDoubleClickTime :: Display -> Int -- ^ @msec@ - double click time in milliseconds (thousandths of a -- second) -> IO () displaySetDoubleClickTime self msec = {# call gdk_display_set_double_click_time #} self (fromIntegral msec) #if GTK_CHECK_VERSION(2,4,0) -- | Sets the double click distance (two clicks within this distance count as -- a double click and result in an 'eventButton' where 'eventClick' is -- 'DoubleClick'). See also 'displaySetDoubleClickTime'. Applications should -- /not/ set this, it is a global user-configured setting. -- -- * Available since Gdk version 2.4 -- displaySetDoubleClickDistance :: Display -> Int -- ^ @distance@ - distance in pixels -> IO () displaySetDoubleClickDistance self distance = {# call gdk_display_set_double_click_distance #} self (fromIntegral distance) #endif -- | Gets the current location of the pointer and the current modifier mask -- for a given display. -- displayGetPointer :: Display -> IO (Screen, [Modifier], Int, Int) -- ^ @(s, m, x, y)@ - the screen @s@, the modifier mask @m@ and the @x@ and -- @y@ coordinates of the pointer displayGetPointer self = alloca $ \sPtr -> alloca $ \xPtr -> alloca $ \yPtr -> alloca $ \mPtr -> {# call gdk_display_get_pointer #} self (castPtr sPtr) xPtr yPtr mPtr >> makeNewGObject mkScreen (peek sPtr) >>= \s -> peek xPtr >>= \x -> peek yPtr >>= \y -> peek mPtr >>= \m -> return (s, toFlags (fromIntegral m), fromIntegral x, fromIntegral y) -- | Obtains the window underneath the mouse pointer, returning the location -- of the pointer in that window in @winX@, @winY@ for @screen@. Returns -- @Nothing@ if -- the window under the mouse pointer is not known to GDK (for example, belongs -- to another application). -- displayGetWindowAtPointer :: Display -> IO (Maybe (DrawWindow, Int, Int)) -- ^ @(screen, winX, winY)@ returns the window under the mouse -- pointer, or @Nothing@. The @winX@ and @winY@ denote the pointer location -- relative to the window origin displayGetWindowAtPointer self = alloca $ \winXPtr -> alloca $ \winYPtr -> do wPtr <- {# call gdk_display_get_window_at_pointer #} self winXPtr winYPtr if wPtr==nullPtr then return Nothing else peek winXPtr >>= \winX -> peek winYPtr >>= \winY -> makeNewGObject mkDrawWindow (return wPtr) >>= \win -> return (Just (win, fromIntegral winX, fromIntegral winY)) {- not worth the trouble -- | This function allows for hooking into the operation of getting the -- current location of the pointer on a particular display. This is only useful -- for such low-level tools as an event recorder. Applications should never -- have any reason to use this facility. -- displaySetPointerHooks :: Display -> {-const-GdkDisplayPointerHooks*-} -- ^ @newHooks@ - a table of pointers to -- functions for getting quantities -- related to the current pointer -- position, or {@NULL@, FIXME: this -- should probably be converted to a -- Maybe data type} to restore the -- default table. -> IO {-GdkDisplayPointerHooks*-} -- ^ returns the previous pointer hook -- table displaySetPointerHooks self newHooks = {# call gdk_display_set_pointer_hooks #} self {-newHooks-} -} #if GTK_CHECK_VERSION(2,8,0) -- | Moves the pointer of @display@ to the point @x@,@y@ on the screen -- @screen@, unless the pointer is confined to a window by a grab, in which -- case it will be moved as far as allowed by the grab. Warping the pointer -- creates events as if the user had moved the mouse instantaneously to the -- destination. -- -- Note that the pointer should normally be under the control of the user. -- This function was added to cover some rare use cases like keyboard -- navigation support for the color picker in the 'ColorSelectionDialog'. -- -- * Available since Gdk version 2.8 -- displayWarpPointer :: Display -> Screen -- ^ @screen@ - the screen of @display@ to warp the pointer to -> Int -- ^ @x@ - the x coordinate of the destination -> Int -- ^ @y@ - the y coordinate of the destination -> IO () displayWarpPointer self screen x y = {# call gdk_display_warp_pointer #} self screen (fromIntegral x) (fromIntegral y) #endif #if GTK_CHECK_VERSION(2,4,0) -- | Returns @True@ if multicolored cursors are supported on @display@. -- Otherwise, cursors have only a forground and a background color. -- -- * Available since Gdk version 2.4 -- displaySupportsCursorColor :: Display -> IO Bool -- ^ returns whether cursors can have multiple colors. displaySupportsCursorColor self = liftM toBool $ {# call gdk_display_supports_cursor_color #} self -- | Returns @True@ if cursors can use an 8bit alpha channel on @display@. -- Otherwise, cursors are restricted to bilevel alpha (i.e. a mask). -- -- * Available since Gdk version 2.4 -- displaySupportsCursorAlpha :: Display -> IO Bool -- ^ returns whether cursors can have alpha channels. displaySupportsCursorAlpha self = liftM toBool $ {# call gdk_display_supports_cursor_alpha #} self -- | Returns the default size to use for cursors on @display@. -- -- * Available since Gdk version 2.4 -- displayGetDefaultCursorSize :: Display -> IO Int -- ^ returns the default cursor size. displayGetDefaultCursorSize self = liftM fromIntegral $ {# call gdk_display_get_default_cursor_size #} self -- | Gets the maximal size to use for cursors on @display@. -- -- * Available since Gdk version 2.4 -- displayGetMaximalCursorSize :: Display -> IO (Int, Int) -- ^ @(width, height)@ -- maximal @width@ and @height@ of the cursor displayGetMaximalCursorSize self = alloca $ \widthPtr -> alloca $ \heightPtr -> {# call gdk_display_get_maximal_cursor_size #} self widthPtr heightPtr >> peek widthPtr >>= \width -> peek heightPtr >>= \height -> return (fromIntegral width, fromIntegral height) -- | Returns the default group leader window for all toplevel windows on -- @display@. This window is implicitly created by GDK. See 'windowSetGroup'. -- -- * Available since Gdk version 2.4 -- displayGetDefaultGroup :: Display -> IO DrawWindow -- ^ returns The default group leader window for @display@ displayGetDefaultGroup self = makeNewGObject mkDrawWindow $ {# call gdk_display_get_default_group #} self #if GTK_CHECK_VERSION(2,6,0) -- | Returns whether 'EOwnerChange' events will be -- sent when the owner of a selection changes. -- -- * Available since Gdk version 2.6 -- displaySupportsSelectionNotification :: Display -> IO Bool -- ^ returns whether 'EOwnerChange' -- events will be sent. displaySupportsSelectionNotification self = liftM toBool $ {# call gdk_display_supports_selection_notification #} self -- | Request 'EOwnerChange' events for ownership -- changes of the selection named by the given atom. -- -- * Available since Gdk version 2.6 -- displayRequestSelectionNotification :: Display -> SelectionTag -- ^ @selection@ - the 'Atom' naming -- the selection for which ownership change notification is -- requested -> IO Bool -- ^ returns whether 'EOwnerChange' -- events will be sent. displayRequestSelectionNotification self (Atom selection) = liftM toBool $ {# call gdk_display_request_selection_notification #} self selection -- | Returns whether the speicifed display supports clipboard persistance; -- i.e. if it's possible to store the clipboard data after an application has -- quit. On X11 this checks if a clipboard daemon is running. -- -- * Available since Gdk version 2.6 -- displaySupportsClipboardPersistence :: Display -> IO Bool -- ^ returns @True@ if the display supports clipboard persistance. displaySupportsClipboardPersistence self = liftM toBool $ {# call gdk_display_supports_clipboard_persistence #} self -- | Issues a request to the clipboard manager to store the clipboard data. On -- X11, this is a special program that works according to the freedesktop -- clipboard specification, available at -- http:\/\/www.freedesktop.org\/Standards\/clipboard-manager-spec. -- -- * Available since Gdk version 2.6 -- displayStoreClipboard :: Display -> DrawWindow -- ^ @clipboardWindow@ - a 'DrawWindow' belonging to -- the clipboard owner -> Word32 -- ^ @time@ - a timestamp -> (Maybe [TargetTag]) -- ^ @targets@ - an array of targets that should be -- saved, or @Nothing@ if all available -- targets should be saved. -> IO () displayStoreClipboard self clipboardWindow time (Just targets) = withArrayLen (map (\(Atom a) -> a) targets) $ \nTargets tPtr -> {# call gdk_display_store_clipboard #} self clipboardWindow (fromIntegral time) tPtr (fromIntegral nTargets) displayStoreClipboard self clipboardWindow time Nothing = {# call gdk_display_store_clipboard #} self clipboardWindow (fromIntegral time) nullPtr 0 #if GTK_CHECK_VERSION(2,10,0) -- | Returns @True@ if 'windowShapeCombineMask' can be used to create shaped -- windows on @display@. -- -- * Available since Gdk version 2.10 -- displaySupportsShapes :: Display -> IO Bool -- ^ returns @True@ if shaped windows are supported displaySupportsShapes self = liftM toBool $ {# call gdk_display_supports_shapes #} self -- | Returns @True@ if 'windowInputShapeCombineMask' can be used to modify the -- input shape of windows on @display@. -- -- * Available since Gdk version 2.10 -- displaySupportsInputShapes :: Display -> IO Bool -- ^ returns @True@ if windows with modified input shape are -- supported displaySupportsInputShapes self = liftM toBool $ {# call gdk_display_supports_input_shapes #} self #if GTK_CHECK_VERSION(2,12,0) -- | Returns @True@ if 'windowSetComposited' can be used to redirect drawing -- on the window using compositing. -- -- Currently this only works on X11 with XComposite and XDamage extensions -- available. -- -- * Available since Gdk version 2.12 -- displaySupportsComposite :: Display -> IO Bool -- ^ returns @True@ if windows may be composited. displaySupportsComposite self = liftM toBool $ {# call gdk_display_supports_composite #} self #endif #endif #endif #endif -------------------- -- Signals -- | The 'displayClosed' signal is emitted when the connection to the windowing -- system for @display@ is closed. -- displayClosed :: DisplayClass self => Signal self (Bool -> IO ()) displayClosed = Signal (connect_BOOL__NONE "closed") #endif