Embryonic CIL bindings for libvlc-control
authorRémi Denis-Courmont <rem@videolan.org>
Sat, 20 Oct 2007 15:24:39 +0000 (15:24 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Sat, 20 Oct 2007 15:24:39 +0000 (15:24 +0000)
bindings/cil/Makefile [new file with mode: 0644]
bindings/cil/exception.cs [new file with mode: 0644]
bindings/cil/libvlc.cs [new file with mode: 0644]
bindings/cil/marshal.cs [new file with mode: 0644]
bindings/cil/testvlc.cs [new file with mode: 0644]

diff --git a/bindings/cil/Makefile b/bindings/cil/Makefile
new file mode 100644 (file)
index 0000000..4b7fe29
--- /dev/null
@@ -0,0 +1,27 @@
+CS = gmcs
+CSFLAGS =
+
+TARGETS = VideoLAN.VLC.Control.dll testvlc.exe
+
+all: $(TARGETS)
+
+clean:
+       rm -f -- $(TARGETS) *.netmodule
+
+VideoLAN.VLC.Control.dll: marshal.cs libvlc.cs exception.cs
+testvlc.exe: testvlc.cs VideoLAN.VLC.Control.dll
+
+%.netmodule: %.cs Makefile
+       $(CS) -target:module -out:$@ $(CSFLAGS) $(filter %.cs,$^) \
+               $(patsubst %,-addmodule:%,$(filter %.netmodule,$^)) \
+
+%.dll: Makefile
+       $(CS) -target:library -out:$@ $(CSFLAGS) $(filter %.cs,$^) \
+               $(patsubst %,-addmodule:%,$(filter %.netmodule,$^)) \
+               $(patsubst %,-r:%,$(filter %.dll,$^))
+
+%.exe: Makefile
+       $(CS) -target:exe -out:$@ $(CSFLAGS) $(filter %.cs,$^) \
+               $(patsubst %,-addmodule:%,$(filter %.netmodule,$^)) \
+               $(patsubst %,-r:%,$(filter %.dll,$^))
+
diff --git a/bindings/cil/exception.cs b/bindings/cil/exception.cs
new file mode 100644 (file)
index 0000000..388858d
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * libvlc.cs - libvlc-control CIL bindings
+ *
+ * $Id$
+ */
+
+/**********************************************************************
+ *  Copyright (C) 2007 Rémi Denis-Courmont.                           *
+ *  This program is free software; you can redistribute and/or modify *
+ *  it under the terms of the GNU General Public License as published *
+ *  by the Free Software Foundation; version 2 of the license, or (at *
+ *  your option) any later version.                                   *
+ *                                                                    *
+ *  This program 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 General Public License for more details.              *
+ *                                                                    *
+ *  You should have received a copy of the GNU General Public License *
+ *  along with this program; if not, you can get it from:             *
+ *  http://www.gnu.org/copyleft/gpl.html                              *
+ **********************************************************************/
+
+using System;
+
+namespace VideoLAN.VLC
+{
+    /**
+     * Base class for managed LibVLC exceptions
+     */
+    public class MediaException : Exception
+    {
+        public MediaException ()
+        {
+        }
+
+        public MediaException (string message)
+            : base (message)
+        {
+        }
+
+        public MediaException (string message, Exception inner)
+           : base (message, inner)
+        {
+        }
+    };
+
+    public class PositionKeyNotSupportedException : MediaException
+    {
+        public PositionKeyNotSupportedException ()
+        {
+        }
+
+        public PositionKeyNotSupportedException (string message)
+            : base (message)
+        {
+        }
+
+        public PositionKeyNotSupportedException (string message, Exception inner)
+           : base (message, inner)
+        {
+        }
+    };
+
+    public class PositionOriginNotSupportedException : MediaException
+    {
+        public PositionOriginNotSupportedException ()
+        {
+        }
+
+        public PositionOriginNotSupportedException (string message)
+            : base (message)
+        {
+        }
+
+        public PositionOriginNotSupportedException (string message, Exception inner)
+           : base (message, inner)
+        {
+        }
+    };
+
+    public class InvalidPositionException : MediaException
+    {
+        public InvalidPositionException ()
+        {
+        }
+
+        public InvalidPositionException (string message)
+            : base (message)
+        {
+        }
+
+        public InvalidPositionException (string message, Exception inner)
+           : base (message, inner)
+        {
+        }
+    };
+
+    public class PlaylistException : MediaException
+    {
+        public PlaylistException ()
+        {
+        }
+
+        public PlaylistException (string message)
+            : base (message)
+        {
+        }
+
+        public PlaylistException (string message, Exception inner)
+           : base (message, inner)
+        {
+        }
+    };
+
+    public class InternalException : MediaException
+    {
+        public InternalException ()
+        {
+        }
+
+        public InternalException (string message)
+            : base (message)
+        {
+        }
+
+        public InternalException (string message, Exception inner)
+           : base (message, inner)
+        {
+        }
+    };
+};
diff --git a/bindings/cil/libvlc.cs b/bindings/cil/libvlc.cs
new file mode 100644 (file)
index 0000000..78e809a
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * libvlc.cs - libvlc-control CIL bindings
+ *
+ * $Id$
+ */
+
+/**********************************************************************
+ *  Copyright (C) 2007 Rémi Denis-Courmont.                           *
+ *  This program is free software; you can redistribute and/or modify *
+ *  it under the terms of the GNU General Public License as published *
+ *  by the Free Software Foundation; version 2 of the license, or (at *
+ *  your option) any later version.                                   *
+ *                                                                    *
+ *  This program 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 General Public License for more details.              *
+ *                                                                    *
+ *  You should have received a copy of the GNU General Public License *
+ *  along with this program; if not, you can get it from:             *
+ *  http://www.gnu.org/copyleft/gpl.html                              *
+ **********************************************************************/
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace VideoLAN.VLC
+{
+
+    public class MediaControl : IDisposable
+    {
+        /**
+         * Possible player status
+         */
+        enum PlayerStatus
+        {
+            PlayingStatus,
+            PauseStatus,
+            ForwardStatus,
+            BackwardStatus,
+            InitStatus,
+            EndStatus,
+            UndefinedStatus,
+        };
+
+        enum PositionOrigin
+        {
+            AbsolutePosition,
+            RelativePosition,
+            ModuloPosition,
+        };
+
+        enum PositionKey
+        {
+            ByteCount,
+            SampleCount,
+            MediaTime,
+        };
+
+        MediaControlHandle self;
+
+        private void CheckDisposed ()
+        {
+            if (self.IsInvalid)
+                throw new ObjectDisposedException ("Media controlled disposed");
+        }
+
+        /**
+         * Creates a MediaControl with a new LibVLC instance
+         */
+        public MediaControl (string[] args)
+        {
+            NativeException e = NativeException.Prepare ();
+
+            U8String[] argv = new U8String[args.Length];
+            for (int i = 0; i < args.Length; i++)
+                argv[i] = new U8String (args[i]);
+
+            self = MediaControlAPI.New (argv.Length, argv, ref e);
+            e.Consume ();
+        }
+
+        /**
+         * Creates a MediaControl from an existing LibVLC instance
+         */
+        /*public MediaControl (MediaControl instance)
+        {
+            NativeException e = NativeException.Prepare ();
+            IntPtr libvlc = mediacontrol_get_libvlc_instance (instance.self);
+
+            self = mediacontrol_new_from_instance (libvlc, ref e);
+            e.Consume ();
+        }*/
+
+        /*public void Play (from)
+        {
+            CheckDisposed ();
+            throw new NotImplementedException ();
+        }*/
+
+        public void Resume ()
+        {
+            CheckDisposed ();
+            NativeException e = NativeException.Prepare ();
+
+            MediaControlAPI.Resume (self, IntPtr.Zero, ref e);
+            e.Consume ();
+        }
+
+        public void Pause ()
+        {
+            CheckDisposed ();
+            NativeException e = NativeException.Prepare ();
+
+            MediaControlAPI.Pause (self, IntPtr.Zero, ref e);
+            e.Consume ();
+        }
+
+        public void Stop ()
+        {
+            CheckDisposed ();
+
+            NativeException e = NativeException.Prepare ();
+            MediaControlAPI.Stop (self, IntPtr.Zero, ref e);
+            e.Consume ();
+        }
+
+        public void AddItem (string mrl)
+        {
+            CheckDisposed ();
+
+            U8String nmrl = new U8String (mrl);
+            NativeException e = NativeException.Prepare ();
+            MediaControlAPI.PlaylistAddItem (self, nmrl, ref e);
+            e.Consume ();
+        }
+
+        public void Clear ()
+        {
+            CheckDisposed ();
+
+            NativeException e = NativeException.Prepare ();
+            MediaControlAPI.PlaylistClear (self, ref e);
+            e.Consume ();
+        }
+
+        public string[] Playlist
+        {
+            get
+            {
+                CheckDisposed ();
+                throw new NotImplementedException ();
+            }
+        }
+
+        public void NextItem ()
+        {
+            CheckDisposed ();
+
+            NativeException e = NativeException.Prepare ();
+            MediaControlAPI.PlaylistNextItem (self, ref e);
+            e.Consume ();
+        }
+
+        public void Dispose ()
+        {
+            self.Dispose ();
+        }
+    };
+};
diff --git a/bindings/cil/marshal.cs b/bindings/cil/marshal.cs
new file mode 100644 (file)
index 0000000..bac4f88
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * libvlc.cs - libvlc-control CIL bindings
+ *
+ * $Id$
+ */
+
+/**********************************************************************
+ *  Copyright (C) 2007 Rémi Denis-Courmont.                           *
+ *  This program is free software; you can redistribute and/or modify *
+ *  it under the terms of the GNU General Public License as published *
+ *  by the Free Software Foundation; version 2 of the license, or (at *
+ *  your option) any later version.                                   *
+ *                                                                    *
+ *  This program 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 General Public License for more details.              *
+ *                                                                    *
+ *  You should have received a copy of the GNU General Public License *
+ *  along with this program; if not, you can get it from:             *
+ *  http://www.gnu.org/copyleft/gpl.html                              *
+ **********************************************************************/
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace VideoLAN.VLC
+{
+    internal class MediaControlAPI
+    {
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_new")]
+        public static extern MediaControlHandle New (int argc, U8String[] argv, ref NativeException e);
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_exit")]
+        public static extern void Exit (IntPtr self);
+
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_start")]
+        public static extern void Start (MediaControlHandle self, IntPtr pos, ref NativeException e);
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_pause")]
+        public static extern void Pause (MediaControlHandle self, IntPtr dummy, ref NativeException e);
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_resume")]
+        public static extern void Resume (MediaControlHandle self, IntPtr dummy, ref NativeException e);
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_stop")]
+        public static extern void Stop (MediaControlHandle self, IntPtr dummy, ref NativeException e);
+
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_add_item")]
+        public static extern void PlaylistAddItem (MediaControlHandle self, U8String mrl, ref NativeException e);
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_clear")]
+        public static extern void PlaylistClear (MediaControlHandle self, ref NativeException e);
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_get_list")]
+        public static extern IntPtr PlaylistGetList (MediaControlHandle self, ref NativeException e);
+        [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_next_item")]
+        public static extern void PlaylistNextItem (MediaControlHandle self, ref NativeException e);
+    }
+
+    /**
+     * Abstract safe handle class for non-NULL pointers
+     * (Microsoft.* namespace has a similar class, but lets stick to System.*)
+     */
+    internal abstract class NonNullHandle : SafeHandle
+    {
+        protected NonNullHandle ()
+            : base (IntPtr.Zero, true)
+        {
+        }
+
+        public override bool IsInvalid
+        {
+            get
+            {
+                return IsClosed || (handle == IntPtr.Zero);
+            }
+        }
+    };
+
+    internal sealed class MediaControlHandle : NonNullHandle
+    {
+        private MediaControlHandle ()
+        {
+        }
+
+        protected override bool ReleaseHandle ()
+        {
+            MediaControlAPI.Exit (handle);
+            return true;
+        }
+    };
+
+    /**
+     * Wrapper around native UTF-8 nul-terminated character arrays
+     */
+    [StructLayout (LayoutKind.Sequential)]
+    internal sealed struct U8String
+    {
+        byte[] mb_str;
+
+        public U8String (string value)
+        {
+            byte[] bytes = System.Text.Encoding.UTF8.GetBytes (value);
+            mb_str = new byte[bytes.Length + 1];
+            Array.Copy (bytes, mb_str, bytes.Length);
+            mb_str[bytes.Length] = 0;
+        }
+
+        public U8String (IntPtr ptr)
+        {
+            if (ptr == IntPtr.Zero)
+                return;
+
+            int i = 0;
+            while (Marshal.ReadByte (ptr, i) != 0)
+                i++;
+            i++;
+
+            mb_str = new byte[i];
+            Marshal.Copy (ptr, mb_str, 0, i);
+        }
+
+        public override string ToString ()
+        {
+            if (mb_str == null)
+                return null;
+
+            byte[] bytes = new byte[mb_str.Length - 1];
+            Array.Copy (mb_str, bytes, bytes.Length);
+
+            return System.Text.Encoding.UTF8.GetString (bytes);
+        }
+    };
+
+
+    /**
+     * LibVLC native exception structure
+     */
+    [StructLayout (LayoutKind.Sequential)]
+    internal sealed struct NativeException
+    {
+        public int code;
+        public IntPtr message;
+
+        public string Message
+        {
+            get
+            {
+                return new U8String (message).ToString ();
+            }
+        }
+
+        [DllImport ("libvlc-control.dll")]
+        static extern void mediacontrol_exception_init (ref NativeException e);
+        [DllImport ("libvlc-control.dll")]
+        static extern void mediacontrol_exception_cleanup (ref NativeException e);
+
+        public static NativeException Prepare ()
+        {
+            NativeException e = new NativeException ();
+            mediacontrol_exception_init (ref e);
+            return e;
+        }
+
+        public void Consume ()
+        {
+            try
+            {
+                Exception e;
+                string m = Message;
+
+                switch (this.code)
+                {
+                    case 0:
+                        e = null;
+                        break;
+                    case 1:
+                        e = new PositionKeyNotSupportedException (m);
+                        break;
+                    case 2:
+                        e = new PositionOriginNotSupportedException (m);
+                        break;
+                    case 3:
+                        e = new InvalidPositionException (m);
+                        break;
+                    case 4:
+                        e = new PlaylistException (m);
+                        break;
+                    case 5:
+                        e = new InternalException (m);
+                        break;
+                    default:
+                        e = new MediaException (m);
+                        break;
+                }
+                if (e != null)
+                    throw e;
+            }
+            finally
+            {
+                mediacontrol_exception_cleanup (ref this);
+            }
+        }
+    };
+};
diff --git a/bindings/cil/testvlc.cs b/bindings/cil/testvlc.cs
new file mode 100644 (file)
index 0000000..596bc87
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * testvlc.cs - tests for libvlc-control CIL bindings
+ *
+ * $Id$
+ */
+
+/**********************************************************************
+ *  Copyright (C) 2007 Rémi Denis-Courmont.                           *
+ *  This program is free software; you can redistribute and/or modify *
+ *  it under the terms of the GNU General Public License as published *
+ *  by the Free Software Foundation; version 2 of the license, or (at *
+ *  your option) any later version.                                   *
+ *                                                                    *
+ *  This program 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 General Public License for more details.              *
+ *                                                                    *
+ *  You should have received a copy of the GNU General Public License *
+ *  along with this program; if not, you can get it from:             *
+ *  http://www.gnu.org/copyleft/gpl.html                              *
+ **********************************************************************/
+
+using System;
+
+namespace VideoLAN.VLC
+{
+    public sealed class Test
+    {
+        public static int Main (string[] args)
+        {
+            MediaControl mc = new MediaControl (args);
+
+            foreach (string s in args)
+                mc.AddItem (s);
+
+            /*mc.Play ();*/
+            Console.ReadLine ();
+
+            mc.Stop ();
+            mc.Clear ();
+
+            mc.Dispose ();
+            return 0;
+        }
+    };
+};