summaryrefslogtreecommitdiff
path: root/src/xine-engine/events.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine/events.c')
-rw-r--r--src/xine-engine/events.c239
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();
+ }
}