public static extern
MediaListHandle MediaSubItems (MediaHandle media, NativeException ex);*/
- /*[DllImport ("libvlc.dll", EntryPoint="libvlc_media_event_manager")]
+ [DllImport ("libvlc.dll", EntryPoint="libvlc_media_event_manager")]
public static extern
- EventManagerHandle MediaGetEventManager (MediaHandle media,
- NativeException ex);*/
+ EventManagerHandle MediaEventManager (MediaHandle media,
+ NativeException ex);
[DllImport ("libvlc.dll", EntryPoint="libvlc_media_get_duration")]
public static extern
MediaHandle PlayerGetMedia (PlayerHandle player,
NativeException ex);*/
- /*[DllImport ("libvlc.dll",
+ [DllImport ("libvlc.dll",
EntryPoint="libvlc_media_player_event_manager")]
public static extern
- EventManagerHandle PlayerGetEventManager (PlayerHandle media,
- NativeException ex);*/
+ EventManagerHandle PlayerEventManager (PlayerHandle media,
+ NativeException ex);
+
[DllImport ("libvlc.dll",
EntryPoint="libvlc_media_player_is_playing")]
public static extern
public static extern
int PlayerCanPause (PlayerHandle player, NativeException ex);
+
+ /* TODO: video, audio */
+
+ /* event.c */
+ [DllImport ("libvlc.dll", EntryPoint="libvlc_event_attach")]
+ public static extern
+ void EventAttach (EventManagerHandle manager, EventType type,
+ IntPtr callback, IntPtr user_data,
+ NativeException ex);
+
+ [DllImport ("libvlc.dll", EntryPoint="libvlc_event_detach")]
+ public static extern
+ void EventDetach (EventManagerHandle manager, EventType type,
+ IntPtr callback, IntPtr user_data,
+ NativeException ex);
+
+ /* libvlc_event_type_name */
+ };
+
+ /**
+ * @brief EventCallback: LibVLC event handler
+ * @ingroup Internals
+ */
+ internal delegate void EventCallback (IntPtr ev, IntPtr data);
+
+ /**
+ * @brief EventType: LibVLC event types
+ * @ingroup Internals
+ */
+ internal enum EventType
+ {
+ MediaMetaChanged,
+ MediaSubItemAdded,
+ MediaDurationChanged,
+ MediaPreparsedChanged,
+ MediaFreed,
+ MediaStateChanged,
+
+ PlayerNothingSpecial,
+ PlayerOpening,
+ PlayerBuffering,
+ PlayerPlaying,
+ PlayerPaused,
+ PlayerStopped,
+ PlayerForward,
+ PlayerBackward,
+ PlayerEndReached,
+ PlayerEncounteredError,
+ PlayerTimeChanged,
+ PlayerPositionChanged,
+ PlayerSeekableChanged,
+ PlayerPausableChanged,
+
+ ListItemAdded,
+ ListWillAddItem,
+ ListItemDeleted,
+ ListWillDeleteItem,
+
+ ListViewItemAdded,
+ ListViewWillAddItem,
+ ListViewItemDeleted,
+ ListViewWillDeleteItem,
+
+ ListPlayerPlayed,
+ ListPlayerNextItemSet,
+ ListPlayerStopped,
+
+ DiscovererStarted,
+ DiscovererEnded,
+
+ PlayerTitleChanged,
};
};
**********************************************************************/
using System;
+using System.Collections;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace VideoLAN.LibVLC
Destroy ();
return true;
}
-
};
/**
*
* This is the baseline for all managed LibVLC objects. It wraps:
* - an unmanaged LibVLC pointer,
- * - a native exception structure, and
- * - the object's native event manager.
+ * - a native exception structure.
*/
public class BaseObject : IDisposable
{
handle = null;
}
};
+
+ internal class EventManagerHandle : NonNullHandle
+ {
+ protected override void Destroy ()
+ {
+ }
+ };
+
+
+ /**
+ * @brief EventingObject: wrapper around an eventing LibVLC handle.
+ * @ingroup Internals
+ *
+ * This is the base class for all managed LibVLC objects which do have an
+ * event manager.
+ */
+ public abstract class EventingObject : BaseObject
+ {
+ /**
+ * @brief Managed to unmanaged event handler mapping
+ * @ingroup Internals
+ *
+ * The CLR cannot do reference counting for unmanaged callbacks.
+ * We keep track of handled events here instead.
+ */
+ private class Event
+ {
+ public EventCallback managed;
+ public IntPtr unmanaged;
+
+ public Event (EventCallback managed, IntPtr unmanaged)
+ {
+ this.managed = managed;
+ this.unmanaged = unmanaged;
+ }
+ };
+ private Dictionary<EventType, Event> events;
+ /**< references to our unmanaged function pointers */
+
+ internal EventingObject () : base ()
+ {
+ events = new Dictionary<EventType, Event> ();
+ }
+
+ /**
+ * Releases unmanaged resources associated with the object.
+ * @param disposing true if the disposing the object explicitly,
+ * false if finalizing the object inside the GC.
+ */
+ protected override void Dispose (bool disposing)
+ {
+ events = null;
+ base.Dispose (disposing);
+ }
+
+ /**
+ * @return the unmanaged event manager for this object
+ */
+ internal abstract EventManagerHandle GetManager ();
+
+ /**
+ * Registers an event handler.
+ * @param type event type to register to
+ * @param callback callback to invoke when the event occurs
+ *
+ * @note
+ * For simplicity, we only allow one handler per type.
+ * Multicasting can be implemented higher up with managed code.
+ */
+ internal void Attach (EventType type, EventCallback callback)
+ {
+ EventManagerHandle manager;
+ IntPtr cb = Marshal.GetFunctionPointerForDelegate (callback);
+ Event ev = new Event (callback, cb);
+ bool unref = false;
+
+ if (events.ContainsKey (type))
+ throw new ArgumentException ("Duplicate event");
+
+ try
+ {
+ handle.DangerousAddRef (ref unref);
+ manager = GetManager ();
+ LibVLC.EventAttach (manager, type, cb, IntPtr.Zero, ex);
+ }
+ finally
+ {
+ if (unref)
+ handle.DangerousRelease ();
+ }
+ Raise ();
+ events.Add (type, ev);
+ }
+
+ private void Detach (EventType type, IntPtr callback)
+ {
+ EventManagerHandle manager;
+ bool unref = false;
+
+ try
+ {
+ handle.DangerousAddRef (ref unref);
+ manager = GetManager ();
+ LibVLC.EventDetach (manager, type, callback, IntPtr.Zero, ex);
+ }
+ finally
+ {
+ if (unref)
+ handle.DangerousRelease ();
+ }
+ Raise ();
+ events.Remove (type);
+ }
+
+ internal void Detach (EventType type)
+ {
+ Detach(type, events[type].unmanaged);
+ }
+ };
};