packages feed

gtk-0.11.0: Graphics/UI/Gtk/Abstract/Object.chs

{-# LANGUAGE CPP #-}
-- -*-haskell-*-
--  GIMP Toolkit (GTK) Object
--
--  Author : Axel Simon
--
--  Created: 9 April 2001
--
--  Copyright (C) 2001-2005 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)
--
-- The base class of the Gtk+ type hierarchy.
--
-- * Each widget is a represented as a purely abstract data type. It can only 
--   be accessed through and the special access functions that are defined
--   in each widget file.
--
module Graphics.UI.Gtk.Abstract.Object (
-- * Detail
-- 
-- | 'Object' is the base class for all widgets, and for a few non-widget
-- objects such as 'Adjustment'. 'Object' predates 'GObject'; non-widgets that
-- derive from 'Object' rather than 'GObject' do so for backward compatibility
-- reasons.
--

-- * Class Hierarchy
-- |
-- @
-- |  'GObject'
-- |   +----Object
-- |         +----'Widget'
-- |         +----'Adjustment'
-- |         +----'CellRenderer'
-- |         +----'FileFilter'
-- |         +----'ItemFactory'
-- |         +----'Tooltips'
-- |         +----'TreeViewColumn'
-- @

-- * Types
  Object,
  ObjectClass,
  castToObject, gTypeObject,
  toObject,

-- * Methods
  makeNewObject,

-- * Weak references
  GWeakNotify,
  objectWeakref,
  objectWeakunref,

-- * Signals
  objectDestroy
  ) where

import Control.Monad (when)

import System.Glib.FFI
import System.Glib.GObject	(objectUnref)
#if GLIB_CHECK_VERSION(2,10,0)
import System.Glib.GObject	(objectRefSink)
#else
import System.Glib.GObject      (objectRef)
#endif
{#import Graphics.UI.Gtk.Types#}
{#import Graphics.UI.Gtk.Signals#}
import Data.IORef

{# context lib="gtk" prefix="gtk" #}

--------------------
-- Methods

-- turn the initial floating state to sunk
--
-- * The floating\/sunk concept of a GTK object is not very useful to us.
--   The following procedure circumvents the whole subject and ensures 
--   proper cleanup:
--     on creation:      objectRef, objectSink
--     on finalization:  objectUnref
--
-- * This function cannot be bound by c2hs because it is not possible to
--   override the pointer hook.
#if !GLIB_CHECK_VERSION(2,10,0)
foreign import ccall unsafe "gtk_object_sink"
  objectSink :: Ptr obj -> IO ()
#endif

-- This is a convenience function to generate a new widget. It adds the
-- finalizer with the method described under objectSink.
--
-- * The constr argument is the contructor of the specific object.
--
makeNewObject :: ObjectClass obj => 
  (ForeignPtr obj -> obj, FinalizerPtr obj) -> IO (Ptr obj) -> IO obj
makeNewObject (constr, objectUnref) generator = do
  objPtr <- generator
  when (objPtr == nullPtr) (fail "makeNewObject: object is NULL")
#if GLIB_CHECK_VERSION(2,10,0)
  objectRefSink objPtr
#else
  objectRef objPtr
  objectSink objPtr
#endif
  obj <- newForeignPtr objPtr objectUnref
  return $! constr obj

{#pointer GWeakNotify#}

foreign import ccall "wrapper" mkDestructor :: IO () -> IO GWeakNotify

-- | Attach a callback that will be called after the
-- destroy hooks have been called
--
objectWeakref :: ObjectClass o => o -> IO () -> IO GWeakNotify
objectWeakref obj uFun = do
  funPtrContainer <- newIORef nullFunPtr
  uFunPtr <- mkDestructor $ do
    uFun
    funPtr <- readIORef funPtrContainer
    freeHaskellFunPtr funPtr
  writeIORef funPtrContainer uFunPtr
  {#call unsafe g_object_weak_ref#} (toGObject obj) uFunPtr nullPtr
  return uFunPtr

-- | Detach a weak destroy callback function
--
objectWeakunref :: ObjectClass o => o -> GWeakNotify -> IO ()
objectWeakunref obj fun = 
  {#call unsafe g_object_weak_unref#} (toGObject obj) fun nullPtr


--------------------
-- Signals

-- | Signals that all holders of a reference to the 'Object' should release
-- the reference that they hold. May result in finalization of the object if
-- all references are released.
--
objectDestroy :: ObjectClass self => Signal self (IO ())
objectDestroy = Signal (connect_NONE__NONE "destroy")