/*1* ALSA sequencer Ports2* Copyright (c) 1998 by Frank van de Pol <[email protected]>3*4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with this program; if not, write to the Free Software17* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18*19*/20#ifndef __SND_SEQ_PORTS_H21#define __SND_SEQ_PORTS_H2223#include <sound/seq_kernel.h>24#include "seq_lock.h"2526/* list of 'exported' ports */2728/* Client ports that are not exported are still accessible, but are29anonymous ports.3031If a port supports SUBSCRIPTION, that port can send events to all32subscribersto a special address, with address33(queue==SNDRV_SEQ_ADDRESS_SUBSCRIBERS). The message is then send to all34recipients that are registered in the subscription list. A typical35application for these SUBSCRIPTION events is handling of incoming MIDI36data. The port doesn't 'know' what other clients are interested in this37message. If for instance a MIDI recording application would like to receive38the events from that port, it will first have to subscribe with that port.3940*/4142struct snd_seq_subscribers {43struct snd_seq_port_subscribe info; /* additional info */44struct list_head src_list; /* link of sources */45struct list_head dest_list; /* link of destinations */46atomic_t ref_count;47};4849struct snd_seq_port_subs_info {50struct list_head list_head; /* list of subscribed ports */51unsigned int count; /* count of subscribers */52unsigned int exclusive: 1; /* exclusive mode */53struct rw_semaphore list_mutex;54rwlock_t list_lock;55int (*open)(void *private_data, struct snd_seq_port_subscribe *info);56int (*close)(void *private_data, struct snd_seq_port_subscribe *info);57};5859struct snd_seq_client_port {6061struct snd_seq_addr addr; /* client/port number */62struct module *owner; /* owner of this port */63char name[64]; /* port name */64struct list_head list; /* port list */65snd_use_lock_t use_lock;6667/* subscribers */68struct snd_seq_port_subs_info c_src; /* read (sender) list */69struct snd_seq_port_subs_info c_dest; /* write (dest) list */7071int (*event_input)(struct snd_seq_event *ev, int direct, void *private_data,72int atomic, int hop);73void (*private_free)(void *private_data);74void *private_data;75unsigned int callback_all : 1;76unsigned int closing : 1;77unsigned int timestamping: 1;78unsigned int time_real: 1;79int time_queue;8081/* capability, inport, output, sync */82unsigned int capability; /* port capability bits */83unsigned int type; /* port type bits */8485/* supported channels */86int midi_channels;87int midi_voices;88int synth_voices;8990};9192struct snd_seq_client;9394/* return pointer to port structure and lock port */95struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client, int num);9697/* search for next port - port is locked if found */98struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *client,99struct snd_seq_port_info *pinfo);100101/* unlock the port */102#define snd_seq_port_unlock(port) snd_use_lock_free(&(port)->use_lock)103104/* create a port, port number is returned (-1 on failure) */105struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port_index);106107/* delete a port */108int snd_seq_delete_port(struct snd_seq_client *client, int port);109110/* delete all ports */111int snd_seq_delete_all_ports(struct snd_seq_client *client);112113/* set port info fields */114int snd_seq_set_port_info(struct snd_seq_client_port *port,115struct snd_seq_port_info *info);116117/* get port info fields */118int snd_seq_get_port_info(struct snd_seq_client_port *port,119struct snd_seq_port_info *info);120121/* add subscriber to subscription list */122int snd_seq_port_connect(struct snd_seq_client *caller,123struct snd_seq_client *s, struct snd_seq_client_port *sp,124struct snd_seq_client *d, struct snd_seq_client_port *dp,125struct snd_seq_port_subscribe *info);126127/* remove subscriber from subscription list */128int snd_seq_port_disconnect(struct snd_seq_client *caller,129struct snd_seq_client *s, struct snd_seq_client_port *sp,130struct snd_seq_client *d, struct snd_seq_client_port *dp,131struct snd_seq_port_subscribe *info);132133/* subscribe port */134int snd_seq_port_subscribe(struct snd_seq_client_port *port,135struct snd_seq_port_subscribe *info);136137/* get matched subscriber */138struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,139struct snd_seq_addr *dest_addr);140141#endif142143144