H Andy, a few comment:
- you make your SerializedEvent an instance of Storable. That could work, but you really have to ensure that the size of the C structure you allocated is big enough. At the moment, you have instance Storable SerializedEvent where sizeOf _ = #{const sizeof (GdkEventKey)} This should be sizeOf _ = maximum [#{const sizeof (GdkEventKey)}, #{const sizeof (GdkEventButton)}] i.e. the maximum of any event you event want to marshal. The next problem I see is with pointers in the event structure. Data structures that the event structure reference must be serialized as well (which is not too hard and which you've done). However, when you deserialize these you need to re-create these structures. At the moment you have: pokeSerializedEventKey ptr (SerializedEvent (SerializedEventKeyValue { [..] ,sEventString = string_ }) window_) = do str <- newCString string_ [..] #{poke GdkEventKey, string} ptr str Here, you leak the space of str. To fix this, you need to revamp the whole code. Instead of using with event $ \eventPtr -> runReaderT fun (castPtr eventPtr) you need to write your own function that allocates space not only for the event structure but also for the referenced structures, e.g. the string. All of these structures must be freed afterwards. Thus, instead of 'with' you need to write your own function using 'alloca'. So I wonder if making you SerializedEvent an instance of Storable is really helpful as the 'sizeOf' and the 'with' function that uses the 'poke' method need to be spacial. Also, since you're not using the time field, why have it in SerializedEvent? Cheers, Axel On Jul 3, 2010, at 20:06, Andy Stewart wrote: > Hi Axel, > > Axel Simon <axel.si...@in.tum.de> writes: > >> On 30.06.2010, at 17:34, Andy Stewart wrote: >>>>> >>>>> So my question is how to binding gtk_main_do_event ? >>>>> Looks I should use Graphics.UI.Gtk.Gdk.Events.Event and not >>>>> EventM. >>>>> >>>> >>>> Event is deprecated and will be removed soon. The problem with >>>> the C >>>> Event structure is that it can contains pointers and varying >>>> fields. >>>> Event did not mangage to translate all of them, also because new >>>> event >>>> are being added to Gtk+ occasionally. If you want to convert a C >>>> Event >>>> structure completely to Haskell, send it over the network and then >>>> reemit the event inside a different application, I suggest that you >>>> start with the Event module and create an opaque but serializable >>>> data >>>> type. This data type should contain some events of interest (keys, >>>> mouse) but not all events. You would probably need to re-insert the >>>> time stamp of the event when you reemit it in the other >>>> application. >>>> >>>> If you implement this, then the extraction of an event should be a >>>> function >>>> >>>> serializeEvent :: EventM t SerializedEvent >>>> >>>> that runs in the EventM monad. It should throw an exception if it >>>> is >>>> applied to an event that it can't handle. >>>> >>>> Then at the client side, we can implement gtk_main_do_event as >>>> >>>> mainDoEvent :: EventM t () >>>> >>>> and have >>>> >>>> deserializeEvent :: SerializedEvent -> (EventM t a) -> IO a >>>> >>>> which executes any EventM function with the serialized event. >>>> >>>> Let me know if you need further help. The functions in Event.hs may >>>> help you to get started with marshalling the events, but you should >>>> use the EventM interface as described above. >>> For make problem simpler, let us just think GdkEventKey. >>> >>> I have below SerializedEventKey for serialized the value of >>> GdkEventKey >>> on *Server* side. >>> >>> data SerializedEventKey = >>> -- sEventType :: Int -- >>> get EventType when deserialize >> >> No, you need to get the event type from the event itself. You don't >> know what the event type is at the deserialisation point. >> >>> -- ,sEventWindow :: DrawWindow -- >>> get DrawWindow when deserialize >>> -- ,sEventTime :: TimeStamp -- >>> get TimeStamp when deserialize >>> >>> SerializedEventKey {sEventSent :: Bool >>> ,sEventState :: [Modifier] >>> ,sEventKeyval :: KeyVal >>> ,sEventLength :: Int >>> ,sEventString :: String >>> ,sEventKeycode :: Word16 >>> ,sEventGroup :: Word8 >>> ,sEventIsModifier :: Bool} >>> >>> I use below function to pick-up SerializeEventKey value from EventM >>> monad at *Server* side: >>> >>> serializedEventKey :: EventM EKey SerializedEventKey >>> serializedEventKey = do >>> sent <- eventSent >>> state <- eventModifier >>> keyval <- eventKeyVal >>> string <- eventKeyName >>> keycode <- eventHardwareKeycode >>> group <- eventKeyboardGroup >>> liftIO $ return $ >>> SerializedEventKey sent >>> state >>> keyval >>> (length string) >>> string >>> keycode >>> group >>> False >>> >> >> Ok. I was suggesting a function that can deal with several, different >> events. You could copy and paste code from the deprecated Event >> module. >> >>> Now we can send SerializedEventKey value to *client* side through >>> DBus-system. >>> >>> When *client* receive the value of SerializedEventKey, >>> We can use >>> >>> "deserializeEvent :: SerializedEventKey -> IO EventKey" >>> >>> add three new values: >>> >>> sEventType : GDK_KEY_RELEASE or GDK_KEY_PRESS >>> sEventWindow : The DrawWindow of *client* that event focus >>> sEventTime : The TimeStamp when *client* process re-emit >>> key event >>> >>> to re-build EventKey. >>> >>> Because gtk_main_do_event need GdkEvent, so we transfer EventKey to >>> is okay. >>> >> >> What is EventKey? >> >> What EventM is doing is to wrap a pointer to a C event struct. So >> your >> EventKey could be a ForeignPtr to a C event struct and mainDoEvent >> could take this ForeignPtr and call the main_do_event function with >> it. >> >> Or you could provide a function >> >>>> deserializeEvent :: SerializedEvent -> (EventM t a) -> IO a >> >> that executes the action with a pointer to a C event struct (and >> destroys the memory associated with this pointer after the action has >> finished). The mainDoEvent can send this event by reading this >> pointer. >> >> The advantages: >> >> - you can use mainDoEvent not only on deserialized events, but also >> on >> local events in any event callback >> - you can use other functions to query a deserialized event, e.g., >> you >> could check if the deserialized event is a left-mouse-button click >> and >> only call mainDoEvent on those >> >> It's more consistent with the rest of the interface. > I success! > > Code at > https://patch-tag.com/r/AndyStewart/gtk-serialized-event/snapshot/current/content/pretty/Graphics/UI/Gtk/Gdk/SerializedEvent.hsc > > Can you help me review it? > > In EventM, > > sEvent <- serializedEvent > > will got SerializedEventValue, you can pass SerializedEventValue > over the network. > > When client receive SerializedEventValue from network, client can use > below code propagate same event at child process: > > drawWindow <- widgetGetDrawWindow targetWidget > postGUIAsync $ deserializeEvent event drawWindow (widgetEvent > targetWidget) >> return () > > Demo at > https://patch-tag.com/r/AndyStewart/gtk-serialized-event/snapshot/current/content/pretty/demo/Main.hs > > To test demo program, you need install below packages: > > dbus-core, dbus-client, webkit > > and apply the patch i send. > > Here is demo screenshot : > http://farm5.static.flickr.com/4080/4758242386_5230d3d54d_b.jpg > > Since Events.hsc has deprecated, i guess you don't like > SerializedEvent style. > I need merge SerializedEvent.hsc into gtk2hs or release it as > individual package? > > Cheers, > > -- Andy > > > > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by Sprint > What will you do first with EVO, the first 4G phone? > Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first > _______________________________________________ > Gtk2hs-devel mailing list > Gtk2hs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel ------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first _______________________________________________ Gtk2hs-devel mailing list Gtk2hs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel