22 struct xmms_output_plugin_St {
32 gboolean write_running;
35 GThread *write_thread;
50 static gpointer xmms_output_plugin_writer (gpointer data);
58 g_mutex_free (plugin->api_mutex);
59 g_mutex_free (plugin->write_mutex);
60 g_cond_free (plugin->write_cond);
62 g_cond_free (plugin->status_cond);
63 g_mutex_free (plugin->status_mutex);
75 res->api_mutex = g_mutex_new ();
76 res->write_mutex = g_mutex_new ();
77 res->write_cond = g_cond_new ();
79 res->status_cond = g_cond_new ();
80 res->status_mutex = g_mutex_new ();
90 g_return_if_fail (plugin);
106 g_return_val_if_fail (plugin, FALSE);
109 if (!(plugin->methods.new &&
110 plugin->methods.destroy &&
111 plugin->methods.flush)) {
112 XMMS_DBG (
"Missing: new, destroy or flush!");
116 w = !!plugin->methods.write;
117 s = !!plugin->methods.status;
120 XMMS_DBG (
"Plugin needs to provide either write or status.");
124 o = !!plugin->methods.open;
125 c = !!plugin->methods.close;
130 XMMS_DBG (
"Write type misses open or close.");
136 XMMS_DBG (
"Status type has open or close.");
148 const gchar *default_value,
165 g_return_val_if_fail (output, FALSE);
166 g_return_val_if_fail (plugin, FALSE);
168 if (plugin->methods.new) {
169 ret = plugin->methods.new (output);
172 if (ret && !plugin->methods.status) {
173 plugin->write_running = TRUE;
174 plugin->write_thread = g_thread_create (xmms_output_plugin_writer,
188 g_return_if_fail (output);
189 g_return_if_fail (plugin);
191 if (plugin->write_thread) {
192 xmms_output_plugin_writer_status_wait (plugin, output,
195 plugin->write_running = FALSE;
197 g_cond_signal (plugin->write_cond);
198 g_thread_join (plugin->write_thread);
199 plugin->write_thread = NULL;
202 if (plugin->methods.destroy) {
203 g_mutex_lock (plugin->api_mutex);
204 plugin->methods.destroy (output);
205 g_mutex_unlock (plugin->api_mutex);
214 g_return_if_fail (output);
215 g_return_if_fail (plugin);
217 if (plugin->methods.flush) {
218 g_mutex_lock (plugin->api_mutex);
219 plugin->methods.flush (output);
220 g_mutex_unlock (plugin->api_mutex);
228 g_return_val_if_fail (plugin, FALSE);
230 if (plugin->methods.format_set_always) {
244 g_return_val_if_fail (output, FALSE);
245 g_return_val_if_fail (plugin, FALSE);
247 if (plugin->methods.format_set) {
248 g_mutex_lock (plugin->api_mutex);
249 res = plugin->methods.format_set (output, st);
250 g_mutex_unlock (plugin->api_mutex);
251 }
else if (plugin->methods.format_set_always) {
252 g_mutex_lock (plugin->api_mutex);
253 res = plugin->methods.format_set_always (output, st);
254 g_mutex_unlock (plugin->api_mutex);
267 g_return_val_if_fail (output, FALSE);
268 g_return_val_if_fail (plugin, FALSE);
270 if (plugin->methods.status) {
271 res = plugin->methods.status (output, st);
272 }
else if (plugin->write_thread) {
273 XMMS_DBG (
"Running status changed... %d", st);
274 res = xmms_output_plugin_writer_status (plugin, output, st);
286 g_return_val_if_fail (output, FALSE);
287 g_return_val_if_fail (plugin, FALSE);
289 if (plugin->methods.latency_get) {
290 ret = plugin->methods.latency_get (output);
300 g_return_val_if_fail (plugin, FALSE);
302 return !!plugin->methods.volume_set;
309 const gchar *chan, guint val)
311 gboolean res = FALSE;
313 g_return_val_if_fail (output, FALSE);
314 g_return_val_if_fail (plugin, FALSE);
316 if (plugin->methods.volume_set) {
317 res = plugin->methods.volume_set (output, chan, val);
327 g_return_val_if_fail (plugin, FALSE);
329 return !!plugin->methods.volume_get;
336 const gchar **n, guint *x, guint *y)
338 gboolean res = FALSE;
340 g_return_val_if_fail (output, FALSE);
341 g_return_val_if_fail (plugin, FALSE);
343 if (plugin->methods.volume_get) {
344 res = plugin->methods.volume_get (output, n, x, y);
358 g_mutex_lock (plugin->write_mutex);
359 plugin->wanted_status = status;
360 plugin->write_output = output;
361 g_cond_signal (plugin->write_cond);
362 g_mutex_unlock (plugin->write_mutex);
372 g_mutex_lock (plugin->status_mutex);
374 if (plugin->wanted_status != status) {
375 xmms_output_plugin_writer_status (plugin, output, status);
378 while (plugin->status != status) {
379 g_cond_wait (plugin->status_cond, plugin->status_mutex);
382 g_mutex_unlock (plugin->status_mutex);
387 xmms_output_plugin_writer (gpointer data)
396 g_mutex_lock (plugin->write_mutex);
398 while (plugin->write_running) {
401 g_mutex_lock (plugin->api_mutex);
402 plugin->methods.close (output);
403 g_mutex_unlock (plugin->api_mutex);
408 g_mutex_lock (plugin->status_mutex);
409 plugin->status = plugin->wanted_status;
410 g_cond_signal (plugin->status_cond);
411 g_mutex_unlock (plugin->status_mutex);
414 g_cond_wait (plugin->write_cond, plugin->write_mutex);
420 g_mutex_lock (plugin->api_mutex);
421 plugin->methods.flush (output);
422 g_mutex_unlock (plugin->api_mutex);
425 g_mutex_lock (plugin->status_mutex);
426 plugin->status = plugin->wanted_status;
427 g_cond_signal (plugin->status_cond);
428 g_mutex_unlock (plugin->status_mutex);
430 g_cond_wait (plugin->write_cond, plugin->write_mutex);
435 output = plugin->write_output;
437 g_mutex_lock (plugin->api_mutex);
438 ret = plugin->methods.open (output);
439 g_mutex_unlock (plugin->api_mutex);
449 g_mutex_lock (plugin->status_mutex);
450 plugin->status = plugin->wanted_status;
451 g_cond_signal (plugin->status_cond);
452 g_mutex_unlock (plugin->status_mutex);
454 g_mutex_unlock (plugin->write_mutex);
460 xmms_error_reset (&err);
462 g_mutex_lock (plugin->api_mutex);
463 plugin->methods.write (output, buffer, ret, &err);
464 g_mutex_unlock (plugin->api_mutex);
467 XMMS_DBG (
"Write method set error bit");
469 g_mutex_lock (plugin->write_mutex);
471 g_mutex_unlock (plugin->write_mutex);
476 g_mutex_lock (plugin->write_mutex);
482 g_mutex_unlock (plugin->write_mutex);
484 XMMS_DBG (
"Output driving thread exiting!");
gboolean xmms_output_plugin_method_format_set(xmms_output_plugin_t *plugin, xmms_output_t *output, xmms_stream_type_t *st)
void xmms_set_thread_name(const gchar *name)
xmms_config_property_t * xmms_plugin_config_property_register(xmms_plugin_t *plugin, const gchar *name, const gchar *default_value, xmms_object_handler_t cb, gpointer userdata)
#define xmms_error_iserror(e)
struct xmms_stream_type_St xmms_stream_type_t
xmms_config_property_t * xmms_config_lookup(const gchar *path)
Look up a config key from the global config.
gboolean xmms_output_plugin_method_status(xmms_output_plugin_t *plugin, xmms_output_t *output, gint st)
gint xmms_output_read(xmms_output_t *output, char *buffer, gint len)
Read a number of bytes of data from the output buffer into a buffer.
const gchar * xmms_plugin_shortname_get(const xmms_plugin_t *plugin)
guint xmms_output_plugin_method_latency_get(xmms_output_plugin_t *plugin, xmms_output_t *output)
gboolean xmms_output_plugin_method_new(xmms_output_plugin_t *plugin, xmms_output_t *output)
Output functions that lets XMMS2 talk to the soundcard.
gboolean xmms_output_plugin_verify(xmms_plugin_t *_plugin)
void xmms_output_plugin_method_flush(xmms_output_plugin_t *plugin, xmms_output_t *output)
gint xmms_config_property_get_int(const xmms_config_property_t *prop)
Return the value of a config property as an int.
gboolean xmms_output_plugin_method_volume_set_available(xmms_output_plugin_t *plugin)
#define xmms_log_error(fmt,...)
struct xmms_output_St xmms_output_t
struct xmms_output_plugin_St xmms_output_plugin_t
gboolean xmms_output_plugin_methods_volume_set(xmms_output_plugin_t *plugin, xmms_output_t *output, const gchar *chan, guint val)
void xmms_plugin_destroy(xmms_plugin_t *plugin)
gboolean xmms_output_plugin_method_volume_get_available(xmms_output_plugin_t *plugin)
gboolean xmms_output_plugin_format_set_always(xmms_output_plugin_t *plugin)
Check if an output plugin needs format updates on each track change.
#define XMMS_DBG(fmt,...)
xmms_config_property_t * xmms_output_plugin_config_property_register(xmms_output_plugin_t *plugin, const gchar *name, const gchar *default_value, xmms_object_handler_t cb, gpointer userdata)
Register a configuration directive in the plugin setup function.
#define xmms_object_new(objtype, destroyfunc)
G_BEGIN_DECLS struct xmms_error_St xmms_error_t
struct xmms_config_property_St xmms_config_property_t
gboolean xmms_output_plugin_method_volume_get(xmms_output_plugin_t *plugin, xmms_output_t *output, const gchar **n, guint *x, guint *y)
void xmms_output_plugin_method_destroy(xmms_output_plugin_t *plugin, xmms_output_t *output)
xmms_plugin_t * xmms_output_plugin_new(void)
void xmms_output_plugin_methods_set(xmms_output_plugin_t *plugin, xmms_output_methods_t *methods)
Register the output plugin functions.
void(* xmms_object_handler_t)(xmms_object_t *object, xmmsv_t *data, gpointer userdata)
void xmms_output_set_error(xmms_output_t *output, xmms_error_t *error)
Set an error.