Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
sound
core
seq
seq_system.c
Go to the documentation of this file.
1
/*
2
* ALSA sequencer System services Client
3
* Copyright (c) 1998-1999 by Frank van de Pol <
[email protected]
>
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
22
#include <
linux/init.h
>
23
#include <linux/export.h>
24
#include <linux/slab.h>
25
#include <
sound/core.h
>
26
#include "
seq_system.h
"
27
#include "
seq_timer.h
"
28
#include "
seq_queue.h
"
29
30
/* internal client that provide system services, access to timer etc. */
31
32
/*
33
* Port "Timer"
34
* - send tempo /start/stop etc. events to this port to manipulate the
35
* queue's timer. The queue address is specified in
36
* data.queue.queue.
37
* - this port supports subscription. The received timer events are
38
* broadcasted to all subscribed clients. The modified tempo
39
* value is stored on data.queue.value.
40
* The modifier client/port is not send.
41
*
42
* Port "Announce"
43
* - does not receive message
44
* - supports supscription. For each client or port attaching to or
45
* detaching from the system an announcement is send to the subscribed
46
* clients.
47
*
48
* Idea: the subscription mechanism might also work handy for distributing
49
* synchronisation and timing information. In this case we would ideally have
50
* a list of subscribers for each type of sync (time, tick), for each timing
51
* queue.
52
*
53
* NOTE: the queue to be started, stopped, etc. must be specified
54
* in data.queue.addr.queue field. queue is used only for
55
* scheduling, and no longer referred as affected queue.
56
* They are used only for timer broadcast (see above).
57
* -- iwai
58
*/
59
60
61
/* client id of our system client */
62
static
int
sysclient = -1;
63
64
/* port id numbers for this client */
65
static
int
announce_port = -1;
66
67
68
69
/* fill standard header data, source port & channel are filled in */
70
static
int
setheader(
struct
snd_seq_event
* ev,
int
client
,
int
port
)
71
{
72
if
(announce_port < 0)
73
return
-
ENODEV
;
74
75
memset
(ev, 0,
sizeof
(
struct
snd_seq_event
));
76
77
ev->
flags
&= ~
SNDRV_SEQ_EVENT_LENGTH_MASK
;
78
ev->
flags
|=
SNDRV_SEQ_EVENT_LENGTH_FIXED
;
79
80
ev->
source
.client = sysclient;
81
ev->
source
.port = announce_port;
82
ev->
dest
.client =
SNDRV_SEQ_ADDRESS_SUBSCRIBERS
;
83
84
/* fill data */
85
/*ev->data.addr.queue = SNDRV_SEQ_ADDRESS_UNKNOWN;*/
86
ev->
data
.
addr
.client =
client
;
87
ev->
data
.
addr
.port =
port
;
88
89
return
0;
90
}
91
92
93
/* entry points for broadcasting system events */
94
void
snd_seq_system_broadcast
(
int
client,
int
port,
int
type
)
95
{
96
struct
snd_seq_event
ev;
97
98
if
(setheader(&ev, client, port) < 0)
99
return
;
100
ev.
type
=
type
;
101
snd_seq_kernel_client_dispatch
(sysclient, &ev, 0, 0);
102
}
103
104
/* entry points for broadcasting system events */
105
int
snd_seq_system_notify
(
int
client,
int
port,
struct
snd_seq_event
*ev)
106
{
107
ev->
flags
=
SNDRV_SEQ_EVENT_LENGTH_FIXED
;
108
ev->
source
.client = sysclient;
109
ev->
source
.port = announce_port;
110
ev->
dest
.client =
client
;
111
ev->
dest
.port =
port
;
112
return
snd_seq_kernel_client_dispatch
(sysclient, ev, 0, 0);
113
}
114
115
/* call-back handler for timer events */
116
static
int
event_input_timer(
struct
snd_seq_event
* ev,
int
direct
,
void
*
private_data
,
int
atomic,
int
hop)
117
{
118
return
snd_seq_control_queue
(ev, atomic, hop);
119
}
120
121
/* register our internal client */
122
int
__init
snd_seq_system_client_init
(
void
)
123
{
124
struct
snd_seq_port_callback
pcallbacks;
125
struct
snd_seq_port_info
*
port
;
126
127
port = kzalloc(
sizeof
(*port),
GFP_KERNEL
);
128
if
(!port)
129
return
-
ENOMEM
;
130
131
memset
(&pcallbacks, 0,
sizeof
(pcallbacks));
132
pcallbacks.
owner
=
THIS_MODULE
;
133
pcallbacks.
event_input
= event_input_timer;
134
135
/* register client */
136
sysclient =
snd_seq_create_kernel_client
(
NULL
, 0,
"System"
);
137
138
/* register timer */
139
strcpy
(port->
name
,
"Timer"
);
140
port->
capability
=
SNDRV_SEQ_PORT_CAP_WRITE
;
/* accept queue control */
141
port->
capability
|=
SNDRV_SEQ_PORT_CAP_READ
|
SNDRV_SEQ_PORT_CAP_SUBS_READ
;
/* for broadcast */
142
port->
kernel
= &pcallbacks;
143
port->
type
= 0;
144
port->
flags
=
SNDRV_SEQ_PORT_FLG_GIVEN_PORT
;
145
port->
addr
.client = sysclient;
146
port->
addr
.port =
SNDRV_SEQ_PORT_SYSTEM_TIMER
;
147
snd_seq_kernel_client_ctl
(sysclient,
SNDRV_SEQ_IOCTL_CREATE_PORT
, port);
148
149
/* register announcement port */
150
strcpy
(port->
name
,
"Announce"
);
151
port->
capability
=
SNDRV_SEQ_PORT_CAP_READ
|
SNDRV_SEQ_PORT_CAP_SUBS_READ
;
/* for broadcast only */
152
port->
kernel
=
NULL
;
153
port->
type
= 0;
154
port->
flags
=
SNDRV_SEQ_PORT_FLG_GIVEN_PORT
;
155
port->
addr
.client = sysclient;
156
port->
addr
.port =
SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE
;
157
snd_seq_kernel_client_ctl
(sysclient,
SNDRV_SEQ_IOCTL_CREATE_PORT
, port);
158
announce_port = port->
addr
.port;
159
160
kfree
(port);
161
return
0;
162
}
163
164
165
/* unregister our internal client */
166
void
__exit
snd_seq_system_client_done
(
void
)
167
{
168
int
oldsysclient = sysclient;
169
170
if
(oldsysclient >= 0) {
171
sysclient = -1;
172
announce_port = -1;
173
snd_seq_delete_kernel_client
(oldsysclient);
174
}
175
}
Generated on Thu Jan 10 2013 15:04:07 for Linux Kernel by
1.8.2