diff options
Diffstat (limited to 'src/xine-engine/events.c')
-rw-r--r-- | src/xine-engine/events.c | 239 |
1 files changed, 168 insertions, 71 deletions
diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c index c41486550..1e2c11965 100644 --- a/src/xine-engine/events.c +++ b/src/xine-engine/events.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: + * $Id: events.c,v 1.10 2002/10/14 15:47:33 guenter Exp $ * * Event handling functions * @@ -29,88 +29,185 @@ #include "xine_internal.h" -int xine_register_event_listener (xine_t *this, - xine_event_listener_cb_t listener, - void *user_data) { - /* Ensure the listener is non-NULL */ - if(listener == NULL) { - return 0; +xine_event_t *xine_event_get (xine_event_queue_t *queue) { + + xine_event_t *event; + + pthread_mutex_lock (&queue->lock); + + event = (xine_event_t *) xine_list_first_content (queue->events); + if (event) + xine_list_delete_current (queue->events); + + pthread_mutex_unlock (&queue->lock); + + return event; +} + +xine_event_t *xine_event_wait (xine_event_queue_t *queue) { + + xine_event_t *event; + + pthread_mutex_lock (&queue->lock); + + while (!(event = (xine_event_t *) xine_list_first_content (queue->events))) { + pthread_cond_wait (&queue->new_event, &queue->lock); } - pthread_mutex_lock(&this->event_lock); - /* Check we hava a slot free */ - if(this->num_event_listeners < XINE_MAX_EVENT_LISTENERS) { + xine_list_delete_current (queue->events); + + pthread_mutex_unlock (&queue->lock); + + return event; +} + +void xine_event_free (xine_event_t *event) { + free (event->data); + free (event); +} + +void xine_event_send (xine_stream_t *stream, const xine_event_t *event) { + + xine_event_queue_t *queue; + + pthread_mutex_lock (&stream->event_queues_lock); + + queue = (xine_event_queue_t *)xine_list_first_content (stream->event_queues); + + while (queue) { + + xine_event_t *cevent; + + cevent = malloc (sizeof (xine_event_t)); + cevent->type = event->type; + cevent->stream = event->stream; + cevent->data_length = event->data_length; + cevent->data = malloc (event->data_length); + memcpy (cevent->data, event->data, event->data_length); - this->event_listeners[this->num_event_listeners] = listener; - this->event_listener_user_data[this->num_event_listeners] = user_data; + pthread_mutex_lock (&queue->lock); + xine_list_append_content (queue->events, cevent); + pthread_cond_signal (&queue->new_event); + pthread_mutex_unlock (&queue->lock); + + queue=(xine_event_queue_t *)xine_list_next_content (stream->event_queues); + } + + pthread_mutex_unlock (&stream->event_queues_lock); +} + + +xine_event_queue_t *xine_event_new_queue (xine_stream_t *stream) { + + xine_event_queue_t *queue; - this->num_event_listeners++; + queue = malloc (sizeof (xine_event_queue_t)); - pthread_mutex_unlock(&this->event_lock); - return 1; - } + pthread_mutex_init (&queue->lock, NULL); + pthread_cond_init (&queue->new_event, NULL); + queue->events = xine_list_new (); + queue->stream = stream; - pthread_mutex_unlock(&this->event_lock); - return 0; + pthread_mutex_lock (&stream->event_queues_lock); + xine_list_append_content (stream->event_queues, queue); + pthread_mutex_unlock (&stream->event_queues_lock); + + return queue; } -void xine_send_event(xine_t *this, xine_event_t *event) { - uint16_t i; +void xine_event_dispose_queue (xine_event_queue_t *queue) { + + xine_stream_t *stream = queue->stream; + xine_event_t *event; + xine_event_t qevent; + xine_event_queue_t *q; + + pthread_mutex_lock (&stream->event_queues_lock); + + q = (xine_event_queue_t *) xine_list_first_content (stream->event_queues); + + while (q && (q != queue)) + q = (xine_event_queue_t *) xine_list_next_content (stream->event_queues); + + if (!q) { + printf ("events: tried to dispose queue which is not in list\n"); + + pthread_mutex_unlock (&stream->event_queues_lock); + return; + } + + xine_list_delete_current (stream->event_queues); + pthread_mutex_unlock (&stream->event_queues_lock); + + /* + * send quit event + */ - pthread_mutex_lock(&this->event_lock); - while (this->event_pending[event->type]) - /* there is already one event of that type around */ - pthread_cond_wait(&this->event_handled, &this->event_lock); - this->event_pending[event->type] = 1; - pthread_mutex_unlock(&this->event_lock); + qevent.type = XINE_EVENT_QUIT; + qevent.data_length = 0; + + pthread_mutex_lock (&queue->lock); + xine_list_append_content (queue->events, &event); + pthread_cond_signal (&queue->new_event); + pthread_mutex_unlock (&queue->lock); + + /* + * join listener thread, if any + */ - /* Iterate through all event handlers */ - for(i=0; i < this->num_event_listeners; i++) { - (this->event_listeners[i]) ((void *)this->event_listener_user_data[i], event); + if (queue->listener_thread) { + void *p; + pthread_join (*queue->listener_thread, &p); } - this->event_pending[event->type] = 0; - pthread_cond_signal(&this->event_handled); + /* + * clean up pending events + */ + + while ( (event = xine_event_get (queue)) ) { + xine_event_free (event); + } + + free (queue); } -int xine_remove_event_listener(xine_t *this, - xine_event_listener_cb_t listener) { - uint16_t i, found, pending; - - found = 1; - - pthread_mutex_lock(&this->event_lock); - /* wait for any pending events */ - do { - pending = 0; - for (i = 0; i < XINE_MAX_EVENT_TYPES; i++) - pending += this->event_pending[i]; - if (pending) - pthread_cond_wait(&this->event_handled, &this->event_lock); - } while (pending); - - i = 0; - /* Attempt to find the listener */ - while((found == 1) && (i < this->num_event_listeners)) { - if(this->event_listeners[i] == listener) { - /* Set found flag */ - found = 0; - - this->event_listeners[i] = NULL; - - /* If possible, move the last listener to the hole thats left */ - if(this->num_event_listeners > 1) { - this->event_listeners[i] = this->event_listeners[this->num_event_listeners - 1]; - this->event_listener_user_data[i] = this->event_listener_user_data[this->num_event_listeners - 1]; - this->event_listeners[this->num_event_listeners - 1] = NULL; - } - - this->num_event_listeners --; - } - - i++; + +static void *listener_loop (void *queue_gen) { + + xine_event_queue_t *queue = (xine_event_queue_t *) queue_gen; + int running = 1; + + while (running) { + + xine_event_t *event; + + event = xine_event_wait (queue); + + if (event->type == XINE_EVENT_QUIT) + running = 0; + else + queue->callback (queue->user_data, event); + + xine_event_free (event); } - pthread_mutex_unlock(&this->event_lock); - return found; + pthread_exit(NULL); +} + + +void xine_event_create_listener_thread (xine_event_queue_t *queue, + xine_event_listener_cb_t callback, + void *user_data) { + int err; + + queue->listener_thread = malloc (sizeof (pthread_t)); + queue->callback = callback; + queue->user_data = user_data; + + if ((err = pthread_create (queue->listener_thread, + NULL, listener_loop, queue)) != 0) { + fprintf (stderr, "events: can't create new thread (%s)\n", + strerror(err)); + abort(); + } } |