Hi Andreas,

Andreas Baldeau <andr...@baldeau.net> writes:

> Hi,
>
> I would like to bind some of libsoup's functionality. 
> So I had a look
> at apiGen (this is the tool to use, right?), but couldn't find any
> useful documentation. So I looked into the Makefile and tried to do
> the same for libsoup. The problem is, that I ran into a whole bunch
> of difficulties (I guess because of doing things the wrong way). Is
> there any guide or at least an example on how to create bindings and
> which tool to use for which step?
1) First, Gtk2HsSetup.hs and Setup.hs are template files to generate binding
code, you don't need touch, just copy them to your cabal directory.

2) Copy hierarchy.list and add GObject *type* information in it.

hierarchy.list use to generate GObject type code in Types.chs

Example, we binding SoupAuth module
(http://library.gnome.org/devel/libsoup/stable/SoupAuth.html)

You can find GObject hierarchy information at
http://library.gnome.org/devel/libsoup/stable/SoupAuth.html#SoupAuth.object-hierarchy

  GObject
   +----SoupAuth
   
Because GObject is indent 4 space in hierarchy.list, so we need indent
below code with 8 space:

        SoupAuth, soup_auth_get_type if libsoup
        
"SoupAuth" is GObject type you need binding, 
"soup_auth_get_type" (libsoup/soup-auth.h) for generate correct GType code in 
Types.chs 

"if libsoup" is type tag, mean just generate those type code when your
"x-Types-Tag" is "libsoup" (x-Types-Tag in .cabal file, we talk later)

Then Types.chs will generate SoupAuth code like below:

------------------------------> WebFrame code start 
<------------------------------
{#pointer *SoupAuth foreign newtype #} deriving (Eq,Ord)

mkSoupAuth = (SoupAuth, objectUnrefFromMainloop)
unSoupAuth (SoupAuth o) = o

class GObjectClass o => SoupAuthClass o
toSoupAuth :: SoupAuthClass o => o -> SoupAuth
toSoupAuth = unsafeCastGObject . toGObject

instance SoupAuthClass SoupAuth
instance GObjectClass SoupAuth where
  toGObject = GObject . castForeignPtr . unSoupAuth
  unsafeCastGObject = SoupAuth . castForeignPtr . unGObject

castToSoupAuth :: GObjectClass obj => obj -> SoupAuth
castToSoupAuth = castTo gTypeSoupAuth "SoupAuth"

gTypeSoupAuth :: GType
gTypeSoupAuth =
  {# call fun unsafe soup_auth_get_type #}
------------------------------> WebFrame code end   
<------------------------------

Then you can do 

   {#import ModuleName.Soup.Types#}   (note need # wrap import code)
   
to use those functions in your module.

3) Copy marshal.list and add *signal* information in it:

Example, "save-password" signal in SoupAuth:

void                user_function                      (SoupAuth *auth,
                                                        gchar    *username,
                                                        gchar    *password,
                                                        gpointer  user_data)

so you need add 

NONE:STRING,STRING 

in marshal.list, it will generate connect_STRING_STRING__NONE define in 
Signals.chs

Then you can do 

   {#import ModuleName.Soup.Signals#}   (note need # wrap import code)
   
to define signal in your module, such as:   

savePassword :: SoupAuthClass self => Signal self (String -> String -> IO ())
savePassword = Signal (connect_STRING_STRING__NONE "save-password")

4) Create libsoup.cabal and modified below field in libsoup.cabal:

------------------------------> .cabal template start 
<------------------------------
Build-Type:     Custom

Extra-Source-Files: Gtk2HsSetup.hs
                    marshal.list
                                        hierarchy.list
                    
x-Types-File:       ModuleName/Soup/Types.chs
x-Types-Tag:        libsoup
x-Types-ModName:    ModuleName.Soup.Types
x-Types-Forward:    *Graphics.UI.GtkInternals
x-Types-Destructor: objectUnrefFromMainloop
x-Types-Hierarchy:  hierarchy.list

Library
        build-depends:  base >= 4 && < 5, array, containers, haskell98, mtl,
                        glib  >= 0.12 && < 0.13, 

        build-tools:    gtk2hsC2hs, gtk2hsHookGenerator, gtk2hsTypeGen

        exposed-modules:
             ModuleName.Soup.SoupAuth
        other-modules:
             ModuleName.Soup.Types
             ModuleName.Soup.Signals
             
        extensions:     ForeignFunctionInterface

        x-Signals-File:  ModuleName/Soup/Signals.chs
        x-Signals-Modname: ModuleName.Soup.Signals
        x-Signals-Types: marshal.list
        x-Signals-Import: Graphics.UI.GtkInternals
                
        pkgconfig-depends: libsoup-2.4 >= 2.31.92
------------------------------> .cabal template end   
<------------------------------
        
"x-Types-*" is type information you need fill

"x-Signals-*" is signal information you need fill

"pkgconfig-depends: libsoup-2.4 >= 2.31.92" 
tell cabal how to find libsoup header files by pkg-config

Example, you can use command
   "pkg-config --cflags libsoup-2.4" 
list the header files.

use command
   "pkg-config --modversion libsoup-2.4" 
to check version of libsoup

5) Create Soup modules:

Example, ModuleName/Soup/SoupAuth.chs

First, you need add 

{-# LANGUAGE CPP #-}
-- -*-haskell-*-

at beginning of file.

And add some import:

import Control.Monad            (liftM)
import System.Glib.FFI
{#import ModuleName.Soup.Types#}
{#import ModuleName.Soup.Signals#}


Ok, that's all, write libsoup code and "cabal install"!

If you have any problem, post here, we will try to help you.

Thanks for your patienceļ¼

  -- Andy


------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
Gtk2hs-devel mailing list
Gtk2hs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel

Reply via email to