using System; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Collections.ObjectModel; namespace DMX2 { public static partial class AlsaSeqLib { static SeqHandleWrapper seq_handle=null; static int clientId; static int inport; static int outport; public class Client { int id; snd_seq_client_type_t type; string name; List ports = new List(); public int Id { get { return id; } } public snd_seq_client_type_t Type { get { return type; } } public string Name { get { return name; } } public ReadOnlyCollection Ports { get { return ports.AsReadOnly(); } } internal Client(PointerWrapper clientInfo){ id = Invoke.snd_seq_client_info_get_client(clientInfo.Pointer); IntPtr nameptr = Invoke.snd_seq_client_info_get_name(clientInfo.Pointer); name = nameptr.PtrToString(); type = (snd_seq_client_type_t)Invoke.snd_seq_client_info_get_type(clientInfo.Pointer); using (PointerWrapper portInfo = new PointerWrapper(GetPortInfoSize ())) { Invoke.snd_seq_port_info_set_client (portInfo.Pointer, id); Invoke.snd_seq_port_info_set_port (portInfo.Pointer, -1); while(Invoke.snd_seq_query_next_port(seq_handle.Handle, portInfo.Pointer) >= 0) { ports.Add(new Port(portInfo)); } } } public override bool Equals (object obj) { return ((Client)obj).id == id; } } public class Port { int portId; int clientId; string name; uint caps; uint type; public int ClientId { get { return clientId; } } public int PortId { get { return portId; } } public string Name { get { return name; } } public uint Caps { get { return caps; } } public uint Type { get { return type; } } internal Port(PointerWrapper portInfo){ clientId = Invoke.snd_seq_port_info_get_client(portInfo.Pointer); portId = Invoke.snd_seq_port_info_get_port(portInfo.Pointer); IntPtr namePtr = Invoke.snd_seq_port_info_get_name(portInfo.Pointer); caps = Invoke.snd_seq_port_info_get_capability (portInfo.Pointer); type = Invoke.snd_seq_port_info_get_type(portInfo.Pointer); name = namePtr.PtrToString(); } } public static void Init () { if(seq_handle!=null) return; seq_handle = new SeqHandleWrapper(); clientId = Invoke.snd_seq_client_id(seq_handle.Handle); inport= Invoke.snd_seq_create_simple_port(seq_handle.Handle,"dmx_ctrl_in", SND_SEQ_PORT_CAP_WRITE + SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); outport= Invoke.snd_seq_create_simple_port(seq_handle.Handle,"dmx_ctrl_out", SND_SEQ_PORT_CAP_READ + SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION); } public static bool GetEvent(out snd_seq_event_t ev){ if(seq_handle==null) throw new InvalidOperationException(); ev = new snd_seq_event_t(); if(Invoke.snd_seq_event_input_pending(seq_handle.Handle,1)<=0) return false; IntPtr evPtr; // Recup du pointeur vers l'ev Invoke.snd_seq_event_input(seq_handle.Handle, out evPtr); // Copie de la zone mémoire dans une structure managee ev =(snd_seq_event_t) Marshal.PtrToStructure(evPtr,typeof(snd_seq_event_t)); // liberation du pointeur Invoke.snd_seq_free_event(evPtr); // TODO : Manage System Events here return true; } static PointerWrapper evOutPtr = new PointerWrapper(32); public static void SendEventToSubscribers (snd_seq_event_t ev) { if(seq_handle==null) throw new InvalidOperationException(); ev.queue = SND_SEQ_QUEUE_DIRECT; ev.source.port = (byte) outport; ev.dest.client=SND_SEQ_ADDRESS_SUBSCRIBERS; ev.dest.port= SND_SEQ_ADDRESS_UNKNOWN; Marshal.StructureToPtr(ev,evOutPtr.Pointer,false); Invoke.snd_seq_event_output(seq_handle.Handle,evOutPtr.Pointer); Invoke.snd_seq_drain_output(seq_handle.Handle); } public static IEnumerable EnumClients () { using (PointerWrapper clientInfo = new PointerWrapper(GetClientInfoSize())) { Invoke.snd_seq_client_info_set_client(clientInfo.Pointer, -1); while (Invoke.snd_seq_query_next_client(seq_handle.Handle,clientInfo.Pointer)>=0) { yield return new Client(clientInfo); } } } public static bool Connect(Port port) { // TODO : detecter le sens et se connecter au port. return false; } public static bool ConnectTo(int client, int port){ return Invoke.snd_seq_connect_to(seq_handle.Handle,outport,client,port)==0; } public static bool ConnectFrom(int client, int port){ return Invoke.snd_seq_connect_from(seq_handle.Handle,inport,client,port)==0; } } }