1 /*****************************************************************************
2 * event.c: New libvlc event control API
3 *****************************************************************************
4 * Copyright (C) 2007 the VideoLAN team
7 * Authors: Filippo Carone <filippo@carone.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #include "libvlc_internal.h"
25 #include <vlc/libvlc.h>
32 static int handle_event( vlc_object_t *p_this, char const *psz_cmd,
33 vlc_value_t oldval, vlc_value_t newval,
36 struct libvlc_callback_entry_t *entry = p_data; /* FIXME: we need some locking here */
38 event.type = entry->i_event_type;
42 event.value_type = BOOLEAN_EVENT;
44 case INPUT_POSITION_CHANGED:
49 event.old_value = oldval;
50 event.new_value = newval;
52 /* Call the client entry */
53 entry->f_callback( entry->p_instance, &event, entry->p_user_data );
58 static inline void add_callback_entry( struct libvlc_callback_entry_t *entry,
59 struct libvlc_callback_entry_list_t **list )
61 struct libvlc_callback_entry_list_t *new_listitem;
63 /* malloc/free strategy:
64 * - alloc-ded in add_callback_entry
65 * - free-ed by libvlc_event_remove_callback
66 * - free-ed in libvlc_destroy threw libvlc_event_remove_callback
67 * when entry is destroyed
69 new_listitem = malloc( sizeof( struct libvlc_callback_entry_list_t ) );
70 new_listitem->elmt = entry;
71 new_listitem->next = *list;
72 new_listitem->prev = NULL;
75 (*list)->prev = new_listitem;
81 * Public libvlc functions
84 void libvlc_event_add_callback( libvlc_instance_t *p_instance,
85 libvlc_event_type_t i_event_type,
86 libvlc_callback_t f_callback,
88 libvlc_exception_t *p_e )
90 struct libvlc_callback_entry_t *entry;
91 const char *callback_name = NULL;
94 RAISEVOID (" Callback function is null ");
96 /* malloc/free strategy:
97 * - alloc-ded in libvlc_event_add_callback
98 * - free-ed by libvlc_event_add_callback on error
99 * - free-ed by libvlc_event_remove_callback
100 * - free-ed in libvlc_destroy threw libvlc_event_remove_callback
101 * when entry is destroyed
103 entry = malloc( sizeof( struct libvlc_callback_entry_t ) );
104 entry->f_callback = f_callback;
105 entry->i_event_type = i_event_type;
106 entry->p_user_data = user_data;
108 switch ( i_event_type )
111 callback_name = "volume-change";
113 case INPUT_POSITION_CHANGED:
117 RAISEVOID( "Unsupported event." );
120 int res = var_AddCallback( p_instance->p_libvlc_int,
125 if (res != VLC_SUCCESS)
128 RAISEVOID("Internal callback registration was not successful. Callback not registered.");
131 add_callback_entry( entry, &p_instance->p_callback_list );
136 void libvlc_event_remove_all_callbacks( libvlc_instance_t *p_instance,
137 libvlc_exception_t *p_e )
139 struct libvlc_callback_entry_list_t *p_listitem = p_instance->p_callback_list;
143 libvlc_event_remove_callback( p_instance,
144 p_listitem->elmt->i_event_type,
145 p_listitem->elmt->f_callback,
146 p_listitem->elmt->p_user_data,
148 /* libvlc_event_remove_callback will reset the p_callback_list */
149 p_listitem = p_instance->p_callback_list;
153 void libvlc_event_remove_callback( libvlc_instance_t *p_instance,
154 libvlc_event_type_t i_event_type,
155 libvlc_callback_t f_callback,
157 libvlc_exception_t *p_e )
159 struct libvlc_callback_entry_list_t *p_listitem = p_instance->p_callback_list;
163 if( p_listitem->elmt->f_callback == f_callback
164 && ( p_listitem->elmt->i_event_type == i_event_type )
165 && ( p_listitem->elmt->p_user_data == p_user_data )
169 if( p_listitem->prev )
170 p_listitem->prev->next = p_listitem->next;
172 p_instance->p_callback_list = p_listitem->next;
174 p_listitem->next->prev = p_listitem->prev;
175 free( p_listitem->elmt ); /* FIXME: need some locking here */
179 p_listitem = p_listitem->next;