1 /* 2 * ALSA sequencer Ports 3 * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl> 4 * 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 #ifndef __SND_SEQ_PORTS_H 22 #define __SND_SEQ_PORTS_H 23 24 #include <sound/seq_kernel.h> 25 #include "seq_lock.h" 26 27 /* list of 'exported' ports */ 28 29 /* Client ports that are not exported are still accessible, but are 30 anonymous ports. 31 32 If a port supports SUBSCRIPTION, that port can send events to all 33 subscribersto a special address, with address 34 (queue==SNDRV_SEQ_ADDRESS_SUBSCRIBERS). The message is then send to all 35 recipients that are registered in the subscription list. A typical 36 application for these SUBSCRIPTION events is handling of incoming MIDI 37 data. The port doesn't 'know' what other clients are interested in this 38 message. If for instance a MIDI recording application would like to receive 39 the events from that port, it will first have to subscribe with that port. 40 41 */ 42 43 struct snd_seq_subscribers { 44 struct snd_seq_port_subscribe info; /* additional info */ 45 struct list_head src_list; /* link of sources */ 46 struct list_head dest_list; /* link of destinations */ 47 atomic_t ref_count; 48 }; 49 50 struct snd_seq_port_subs_info { 51 struct list_head list_head; /* list of subscribed ports */ 52 unsigned int count; /* count of subscribers */ 53 unsigned int exclusive: 1; /* exclusive mode */ 54 struct rw_semaphore list_mutex; 55 rwlock_t list_lock; 56 int (*open)(void *private_data, struct snd_seq_port_subscribe *info); 57 int (*close)(void *private_data, struct snd_seq_port_subscribe *info); 58 }; 59 60 struct snd_seq_client_port { 61 62 struct snd_seq_addr addr; /* client/port number */ 63 struct module *owner; /* owner of this port */ 64 char name[64]; /* port name */ 65 struct list_head list; /* port list */ 66 snd_use_lock_t use_lock; 67 68 /* subscribers */ 69 struct snd_seq_port_subs_info c_src; /* read (sender) list */ 70 struct snd_seq_port_subs_info c_dest; /* write (dest) list */ 71 72 int (*event_input)(struct snd_seq_event *ev, int direct, void *private_data, 73 int atomic, int hop); 74 void (*private_free)(void *private_data); 75 void *private_data; 76 unsigned int callback_all : 1; 77 unsigned int closing : 1; 78 unsigned int timestamping: 1; 79 unsigned int time_real: 1; 80 int time_queue; 81 82 /* capability, inport, output, sync */ 83 unsigned int capability; /* port capability bits */ 84 unsigned int type; /* port type bits */ 85 86 /* supported channels */ 87 int midi_channels; 88 int midi_voices; 89 int synth_voices; 90 91 }; 92 93 struct snd_seq_client; 94 95 /* return pointer to port structure and lock port */ 96 struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client, int num); 97 98 /* search for next port - port is locked if found */ 99 struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *client, 100 struct snd_seq_port_info *pinfo); 101 102 /* unlock the port */ 103 #define snd_seq_port_unlock(port) snd_use_lock_free(&(port)->use_lock) 104 105 /* create a port, port number is returned (-1 on failure) */ 106 struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port_index); 107 108 /* delete a port */ 109 int snd_seq_delete_port(struct snd_seq_client *client, int port); 110 111 /* delete all ports */ 112 int snd_seq_delete_all_ports(struct snd_seq_client *client); 113 114 /* set port info fields */ 115 int snd_seq_set_port_info(struct snd_seq_client_port *port, 116 struct snd_seq_port_info *info); 117 118 /* get port info fields */ 119 int snd_seq_get_port_info(struct snd_seq_client_port *port, 120 struct snd_seq_port_info *info); 121 122 /* add subscriber to subscription list */ 123 int snd_seq_port_connect(struct snd_seq_client *caller, 124 struct snd_seq_client *s, struct snd_seq_client_port *sp, 125 struct snd_seq_client *d, struct snd_seq_client_port *dp, 126 struct snd_seq_port_subscribe *info); 127 128 /* remove subscriber from subscription list */ 129 int snd_seq_port_disconnect(struct snd_seq_client *caller, 130 struct snd_seq_client *s, struct snd_seq_client_port *sp, 131 struct snd_seq_client *d, struct snd_seq_client_port *dp, 132 struct snd_seq_port_subscribe *info); 133 134 /* subscribe port */ 135 int snd_seq_port_subscribe(struct snd_seq_client_port *port, 136 struct snd_seq_port_subscribe *info); 137 138 /* get matched subscriber */ 139 struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp, 140 struct snd_seq_addr *dest_addr); 141 142 #endif 143