Jack2 1.9.12

JackLibAPI.cpp
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (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 of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #include "JackDebugClient.h"
22 #include "JackLibClient.h"
23 #include "JackChannel.h"
24 #include "JackLibGlobals.h"
25 #include "JackGlobals.h"
26 #include "JackCompilerDeps.h"
27 #include "JackTools.h"
28 #include "JackSystemDeps.h"
29 #include "JackServerLaunch.h"
30 #include <assert.h>
31
32 using namespace Jack;
33
34 #ifdef __cplusplus
35 extern "C"
36 {
37 #endif
38
39 jack_client_t * jack_client_new_aux (const char *client_name,
40 jack_options_t options,
41 jack_status_t *status);
42
43 LIB_EXPORT jack_client_t * jack_client_open (const char *client_name,
44 jack_options_t options,
45 jack_status_t *status, ...);
46 LIB_EXPORT int jack_client_close (jack_client_t *client);
47 LIB_EXPORT int jack_get_client_pid (const char *name);
48
49
50 #ifdef __cplusplus
51 }
52 #endif
53
54 static jack_client_t * jack_client_open_aux (const char *client_name,
55 jack_options_t options,
56 jack_status_t *status, va_list ap);
57
58 JackLibGlobals* JackLibGlobals::fGlobals = NULL;
59 int JackLibGlobals::fClientCount = 0;
60
61 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
62 {
63 jack_varargs_t va; /* variable arguments */
64 jack_status_t my_status;
65 JackClient* client;
66
67 if (client_name == NULL) {
68 jack_error("jack_client_new called with a NULL client_name");
69 return NULL;
70 }
71
72 jack_log("jack_client_new %s", client_name);
73
74 if (status == NULL) /* no status from caller? */
75 status = &my_status; /* use local status word */
76 *status = (jack_status_t)0;
77
78 /* validate parameters */
79 if ((options & ~JackOpenOptions)) {
80 int my_status1 = *status | (JackFailure | JackInvalidOption);
81 *status = (jack_status_t)my_status1;
82 return NULL;
83 }
84
85 /* parse variable arguments */
86 jack_varargs_init(&va);
87
88 JackLibGlobals::Init(); // jack library initialisation
89
90 if (try_start_server(&va, options, status)) {
91 jack_error("jack server is not running or cannot be started");
92 JackLibGlobals::Destroy(); // jack library destruction
93 return 0;
94 }
95
96 if (JACK_DEBUG) {
97 client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
98 } else {
99 client = new JackLibClient(GetSynchroTable());
100 }
101
102 int res = client->Open(va.server_name, client_name, va.session_id, options, status);
103 if (res < 0) {
104 delete client;
105 JackLibGlobals::Destroy(); // jack library destruction
106 int my_status1 = (JackFailure | JackServerError);
107 *status = (jack_status_t)my_status1;
108 return NULL;
109 } else {
110 return (jack_client_t*)client;
111 }
112 }
113
114 static jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
115 {
116 jack_varargs_t va; /* variable arguments */
117 jack_status_t my_status;
118 JackClient* client;
119
120 if (client_name == NULL) {
121 jack_error("jack_client_open called with a NULL client_name");
122 return NULL;
123 }
124
125 jack_log("jack_client_open %s", client_name);
126
127 if (status == NULL) /* no status from caller? */
128 status = &my_status; /* use local status word */
129 *status = (jack_status_t)0;
130
131 /* validate parameters */
132 if ((options & ~JackOpenOptions)) {
133 int my_status1 = *status | (JackFailure | JackInvalidOption);
134 *status = (jack_status_t)my_status1;
135 return NULL;
136 }
137
138 /* parse variable arguments */
139 jack_varargs_parse(options, ap, &va);
140
141 JackLibGlobals::Init(); // jack library initialisation
142
143 if (try_start_server(&va, options, status)) {
144 jack_error("jack server is not running or cannot be started");
145 JackLibGlobals::Destroy(); // jack library destruction
146 return 0;
147 }
148
149 if (JACK_DEBUG) {
150 client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
151 } else {
152 client = new JackLibClient(GetSynchroTable());
153 }
154
155 int res = client->Open(va.server_name, client_name, va.session_id, options, status);
156 if (res < 0) {
157 delete client;
158 JackLibGlobals::Destroy(); // jack library destruction
159 int my_status1 = (JackFailure | JackServerError);
160 *status = (jack_status_t)my_status1;
161 return NULL;
162 } else {
163 return (jack_client_t*)client;
164 }
165 }
166
167 LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
168 {
169 JackGlobals::CheckContext("jack_client_open");
170
171 try {
172 assert(JackGlobals::fOpenMutex);
173 JackGlobals::fOpenMutex->Lock();
174 va_list ap;
175 va_start(ap, status);
176 jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
177 va_end(ap);
178 JackGlobals::fOpenMutex->Unlock();
179 return res;
180 } catch (std::bad_alloc& e) {
181 jack_error("Memory allocation error...");
182 return NULL;
183 } catch (...) {
184 jack_error("Unknown error...");
185 return NULL;
186 }
187 }
188
189 LIB_EXPORT int jack_client_close(jack_client_t* ext_client)
190 {
191 JackGlobals::CheckContext("jack_client_close");
192
193 assert(JackGlobals::fOpenMutex);
194 JackGlobals::fOpenMutex->Lock();
195 int res = -1;
196 jack_log("jack_client_close");
197 JackClient* client = (JackClient*)ext_client;
198 if (client == NULL) {
199 jack_error("jack_client_close called with a NULL client");
200 } else {
201 res = client->Close();
202 delete client;
203 JackLibGlobals::Destroy(); // jack library destruction
204 jack_log("jack_client_close res = %d", res);
205 }
206 JackGlobals::fOpenMutex->Unlock();
207 return res;
208 }
209
210 LIB_EXPORT int jack_get_client_pid(const char *name)
211 {
212 jack_error("jack_get_client_pid : not implemented on library side");
213 return 0;
214 }
215
jack_varargs_t
Definition: varargs.h:34
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
jack_client_open
LIB_EXPORT jack_client_t * jack_client_open(const char *client_name, jack_options_t options, jack_status_t *status,...)
Definition: JackLibAPI.cpp:167
Jack::JackLibGlobals
Global library static structure: singleton kind of pattern.
Definition: JackLibGlobals.h:53
jack_get_client_pid
LIB_EXPORT int jack_get_client_pid(const char *name)
Definition: JackLibAPI.cpp:210
Jack::JackDebugClient
A "decorator" debug client to validate API use.
Definition: JackDebugClient.h:49
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108
Jack::JackClient
The base class for clients: share part of the implementation for JackInternalClient and JackLibClient...
Definition: JackClient.h:47
Jack::JackLibClient
Client on the library side.
Definition: JackLibClient.h:35
jack_client_close
LIB_EXPORT int jack_client_close(jack_client_t *client)
Definition: JackLibAPI.cpp:189