From cd6d499b13eefc3a2598ff0e53da744227cf4404 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sat, 20 Oct 2007 15:24:39 +0000 Subject: [PATCH] Embryonic CIL bindings for libvlc-control --- bindings/cil/Makefile | 27 +++++ bindings/cil/exception.cs | 132 +++++++++++++++++++++++++ bindings/cil/libvlc.cs | 170 ++++++++++++++++++++++++++++++++ bindings/cil/marshal.cs | 200 ++++++++++++++++++++++++++++++++++++++ bindings/cil/testvlc.cs | 47 +++++++++ 5 files changed, 576 insertions(+) create mode 100644 bindings/cil/Makefile create mode 100644 bindings/cil/exception.cs create mode 100644 bindings/cil/libvlc.cs create mode 100644 bindings/cil/marshal.cs create mode 100644 bindings/cil/testvlc.cs diff --git a/bindings/cil/Makefile b/bindings/cil/Makefile new file mode 100644 index 0000000000..4b7fe2954f --- /dev/null +++ b/bindings/cil/Makefile @@ -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 index 0000000000..388858de62 --- /dev/null +++ b/bindings/cil/exception.cs @@ -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 index 0000000000..78e809a114 --- /dev/null +++ b/bindings/cil/libvlc.cs @@ -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 index 0000000000..bac4f88ce3 --- /dev/null +++ b/bindings/cil/marshal.cs @@ -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 index 0000000000..596bc8752b --- /dev/null +++ b/bindings/cil/testvlc.cs @@ -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; + } + }; +}; -- 2.20.1