loupiottes/DMX-2.0/AlsaSeqLib.cs
2017-06-30 10:00:38 +02:00

340 lines
9.3 KiB
C#

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<Port> ports = new List<Port> ();
public int Id {
get {
return id;
}
}
public snd_seq_client_type_t Type {
get {
return type;
}
}
public string Name {
get {
return name;
}
}
public ReadOnlyCollection<Port> 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 static int ClientId {
get {
return clientId;
}
}
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);
}
public static int CreatePort(string portname){
return Invoke.snd_seq_create_simple_port (seq_handle.Handle,
portname,
SND_SEQ_PORT_CAP_WRITE
+ SND_SEQ_PORT_CAP_SUBS_WRITE
+ SND_SEQ_PORT_CAP_READ
+ SND_SEQ_PORT_CAP_SUBS_READ
,
SND_SEQ_PORT_TYPE_APPLICATION
);
}
public static void DeletePort(int port){
Invoke.snd_seq_delete_simple_port (seq_handle.Handle,
port);
}
public static void Close ()
{
if (seq_handle == null)
return;
seq_handle.Dispose ();
seq_handle = null;
}
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 SendEvent (snd_seq_event_t ev)
{
if (seq_handle == null)
throw new InvalidOperationException ();
ev.queue = SND_SEQ_QUEUE_DIRECT;
ev.source.client = (byte)clientId;
//ev.source.port = (byte)outport;
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 void SendEventToSubscribers (snd_seq_event_t ev)
{
if (seq_handle == null)
throw new InvalidOperationException ();
ev.dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS;
ev.dest.port = SND_SEQ_ADDRESS_UNKNOWN;
SendEvent (ev);
}
public static IEnumerable<Client> EnumClients ()
{
if (seq_handle == null)
throw new InvalidOperationException ();
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 Client GetClientByID (int client)
{
if (seq_handle == null)
throw new InvalidOperationException ();
using (PointerWrapper clientInfo = new PointerWrapper(GetClientInfoSize())) {
if (Invoke.snd_seq_get_any_client_info (seq_handle.Handle, client, clientInfo.Pointer) >= 0) {
return new Client (clientInfo);
} else
return null;
}
}
public static Port GetPortByIDs (int client, int port)
{
if (seq_handle == null)
throw new InvalidOperationException ();
using (PointerWrapper portInfo = new PointerWrapper(GetPortInfoSize ())) {
if (Invoke.snd_seq_get_any_port_info (seq_handle.Handle, client, port, portInfo.Pointer) >= 0) {
return new Port (portInfo);
} else
return null;
}
}
public static bool Connect (int localport, Port port)
{
if (seq_handle == null)
throw new InvalidOperationException ();
bool isInput = (port.Caps & SND_SEQ_PORT_CAP_WRITE) == SND_SEQ_PORT_CAP_WRITE;
bool isOutput = (port.Caps & SND_SEQ_PORT_CAP_READ) == SND_SEQ_PORT_CAP_READ;
if (isInput)
if (!ConnectTo (localport,port.ClientId, port.PortId))
return false;
if (isOutput)
if (!ConnectFrom (localport,port.ClientId, port.PortId))
return false;
return true;
}
public static bool ConnectTo (int localoutport, int client, int port)
{
if (seq_handle == null)
throw new InvalidOperationException ();
return Invoke.snd_seq_connect_to (seq_handle.Handle, localoutport, client, port) == 0;
}
public static bool ConnectFrom (int localinport, int client, int port)
{
if (seq_handle == null)
throw new InvalidOperationException ();
return Invoke.snd_seq_connect_from (seq_handle.Handle, localinport, client, port) == 0;
}
public static void Deconnecte (int localport, int client, int port)
{
if (seq_handle == null)
throw new InvalidOperationException ();
snd_seq_addr_t local = new snd_seq_addr_t ();
local.client = (byte)clientId;
local.port = (byte)localport;
snd_seq_addr_t addr;
using (PointerWrapper subqueryInfo = new PointerWrapper(GetQuerySubscribeInfoSize()))
using (PointerWrapper localAddr =new PointerWrapper(local.SndSeqAddrToPtr())) {
Invoke.snd_seq_query_subscribe_set_root (subqueryInfo.Pointer, localAddr.Pointer);
Invoke.snd_seq_query_subscribe_set_type (subqueryInfo.Pointer, SND_SEQ_QUERY_SUBS_WRITE);
for (Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,0);
Invoke.snd_seq_query_port_subscribers (seq_handle.Handle,subqueryInfo.Pointer)>=0;
Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,
Invoke.snd_seq_query_subscribe_get_index(subqueryInfo.Pointer) +1)
) {
//root = Invoke.snd_seq_query_subscribe_get_root(subqueryInfo.Pointer).PtrToSndSeqAddr();
addr = Invoke.snd_seq_query_subscribe_get_addr (subqueryInfo.Pointer).PtrToSndSeqAddr ();
if (addr.client != client || addr.port != port)
continue;
Invoke.snd_seq_disconnect_from (seq_handle.Handle, localport, client, port);
}
Invoke.snd_seq_query_subscribe_set_type (subqueryInfo.Pointer, SND_SEQ_QUERY_SUBS_READ);
for (Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,0);
Invoke.snd_seq_query_port_subscribers (seq_handle.Handle,subqueryInfo.Pointer)>=0;
Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,
Invoke.snd_seq_query_subscribe_get_index(subqueryInfo.Pointer) +1)
) {
//root = Invoke.snd_seq_query_subscribe_get_root(subqueryInfo.Pointer).PtrToSndSeqAddr();
addr = Invoke.snd_seq_query_subscribe_get_addr (subqueryInfo.Pointer).PtrToSndSeqAddr ();
if (addr.client != client || addr.port != port)
continue;
Invoke.snd_seq_disconnect_to (seq_handle.Handle, localport, client, port);
}
}
}
/*
public static void GetConnections()
{
using(PointerWrapper subscribeInfo = new PointerWrapper(GetQuerySubscribeInfoSize())){
int index=0;
Invoke.snd_seq_query_subscribe_set_client (subscribeInfo.Pointer,clientId);
Invoke.snd_seq_query_subscribe_set_port (subscribeInfo.Pointer,inport);
Invoke.snd_seq_query_subscribe_set_index(subscribeInfo.Pointer,index++);
Invoke.snd_seq_query_subscribe_set_type(subscribeInfo.Pointer,SND_SEQ_QUERY_SUBS_WRITE);
while (Invoke.snd_seq_query_port_subscribers(seq_handle.Handle,subscribeInfo.Pointer) ==0){
//Console.WriteLine("Remote => {0}:{1}",rclient,rport);
Invoke.snd_seq_query_subscribe_set_index(subscribeInfo.Pointer,index++);
}
}
}*/
}
}