So, I have successfully added some of the missing bindings that I needed.

The code is so short that I embed it in this email. I'd be interested
to hear any comments on the way I did this, and what you would want to
change before committing it to wxhaskell.

1) Loading images from in-memory blocks

Stub C++ file to bind to the appropriate wxImage constructor:

#include "wx/wx.h"
#include "wx/image.h"
#include "wx/mstream.h"

extern "C"
{
   void * wxImage_CreateFromFileInMemory(void* data,int length,int type) {
     wxMemoryInputStream in(data,length);
     return (void*) new wxImage(in,type);
   }
}

You can compile this with "g++ -c `wx-config --cppflags` cstub.cpp"

Then a haskell stub file to wrap a Ptr version of this and two
bytestring versions:

{-# OPTIONS -fglasgow-exts #-}
module ImageExtras where

import qualified Data.ByteString.Lazy as LB
import qualified Data.ByteString as B
import Foreign
import Foreign.C
import Graphics.UI.WXCore.WxcTypes
import Graphics.UI.WXCore.WxcClassTypes

imageCreateFromPtrFile :: Ptr b -> Int -> Int -> IO (Image ())
imageCreateFromPtrFile ptr len typ
   = withManagedObjectResult $
     wxImage_CreateFromFileInMemory ptr (fromIntegral len) (fromIntegral 
typ)
foreign import ccall "wxImage_CreateFromFileInMemory"
   wxImage_CreateFromFileInMemory :: Ptr b -> CInt -> CInt -> IO (Ptr 
(TImage ()))
imageCreateFromLBytestringFile :: LB.ByteString -> Int -> IO (Image  ())
imageCreateFromLBytestringFile bs typ
   = withArray (LB.unpack bs) $ \ptr ->
   imageCreateFromPtrFile ptr (fromIntegral $ LB.length bs) typ

imageCreateFromBytestringFile :: B.ByteString -> Int -> IO (Image  ())
imageCreateFromBytestringFile bs typ
   = withArray (B.unpack bs) $ \ptr ->
   imageCreateFromPtrFile ptr (B.length bs) typ

I'm not sure if you can make these a bit more efficient by attacking
the underlying bytestring rep, but I didn't try.

It works, anyhow. I am able to load images from bytestreams (as it
happens, the cover art from an M4A file). The magic invocation to get
ghc to link it correctly seems to be:

ghc --make main.hs cstub.o -lstdc++ `wx-config --libs` -optl -fexceptions

2) GetOption / SetOption for Images

Slightly more fiddly. The C++ stub looks like this:

#include "wx/wx.h"
#include "wx/image.h"

extern "C"
{
   void wxImage_SetOption(void *_obj, void* key,void *value) {
     ((wxImage*)_obj)->SetOption((wxChar*)key,(wxChar*)value);
   }
   wxString* wxImage_GetOption(void *_obj, void* key) {
     return new wxString(((wxImage*)_obj)->GetOption((wxChar*)key));
   }
}

(it took me quite a while to understand why casting to wxChar* works
when the underlying type is WxString&; there is an implicit conversion
because of a constructor)

The haskell stub is this:

{-# OPTIONS -fglasgow-exts #-}
module ImageOptions where

import Graphics.UI.WXCore.WxcTypes
import Graphics.UI.WXCore.WxcClassTypes

imageSetOption :: Image a -> String -> String -> IO ()
imageSetOption _obj key value =
   withObjectRef "imageSetOption" _obj $ \cobj ->
   withCWString key $ \cstr_key ->
   withCWString value $ \cstr_value ->
   wxImage_SetOption cobj cstr_key cstr_value
foreign import ccall "wxImage_SetOption" wxImage_SetOption ::
   Ptr (TImage a) -> CWString -> CWString -> IO ()

imageGetOption :: Image a -> String -> IO String
imageGetOption _obj key =
   withManagedStringResult $
   withObjectRef "imageGetOption" _obj $ \cobj ->
   withCWString key $ \cstr_key ->
   wxImage_GetOption cobj cstr_key
foreign import ccall "wxImage_GetOption" wxImage_GetOption ::
   Ptr (TImage a) -> CWString -> IO (Ptr (TWxString ()))


3) Points of confusion:

For return types of type String, looking at the examples in elj*.cpp,
why does it sometimes use copyStrToBuf to unpack the WxString on the
C++ side in combination with withWStringResult on the haskell side,
and other times just pass back the a freshly allocated WxString* from
C++ in combination with withManagedStringResult?

For arguments of object types, why do some bindings use withObjectPtr
and some use withObjectRef?

What's the EXWXEXPORT() macro for? It didn't seem very useful to me...

Thanks,

Jules

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
wxhaskell-users mailing list
wxhaskell-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wxhaskell-users

Reply via email to