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 /* This is thread safe, as the var_*Callback already provide the locking
37 * facility for p_data */
38 struct libvlc_callback_entry_t *entry = p_data;
40 event.type = entry->i_event_type;
44 event.value_type = BOOLEAN_EVENT;
46 case INPUT_POSITION_CHANGED:
51 event.old_value = oldval;
52 event.new_value = newval;
54 /* Call the client entry */
55 entry->f_callback( entry->p_instance, &event, entry->p_user_data );
60 static inline void add_callback_to_list( struct libvlc_callback_entry_t *entry,
61 struct libvlc_callback_entry_list_t **list )
63 struct libvlc_callback_entry_list_t *new_listitem;
65 /* malloc/free strategy:
66 * - alloc-ded in add_callback_entry
67 * - free-ed by libvlc_event_remove_callback
68 * - free-ed in libvlc_destroy threw libvlc_event_remove_callback
69 * when entry is destroyed
71 new_listitem = malloc( sizeof( struct libvlc_callback_entry_list_t ) );
72 new_listitem->elmt = entry;
73 new_listitem->next = *list;
74 new_listitem->prev = NULL;
77 (*list)->prev = new_listitem;
82 static int remove_variable_callback( libvlc_instance_t *p_instance,
83 struct libvlc_callback_entry_t * p_entry )
85 const char * callback_name = NULL;
87 /* Note: Appropriate lock should be held by the caller */
89 switch ( p_entry->i_event_type )
92 callback_name = "volume-change";
94 case INPUT_POSITION_CHANGED:
101 return var_DelCallback( p_instance->p_libvlc_int,
102 callback_name, handle_event,
107 * Public libvlc functions
110 void libvlc_event_add_callback( libvlc_instance_t *p_instance,
111 libvlc_event_type_t i_event_type,
112 libvlc_callback_t f_callback,
114 libvlc_exception_t *p_e )
116 struct libvlc_callback_entry_t *entry;
117 const char * callback_name = NULL;
121 RAISEVOID (" Callback function is null ");
123 /* malloc/free strategy:
124 * - alloc-ded in libvlc_event_add_callback
125 * - free-ed by libvlc_event_add_callback on error
126 * - free-ed by libvlc_event_remove_callback
127 * - free-ed in libvlc_destroy threw libvlc_event_remove_callback
128 * when entry is destroyed
130 entry = malloc( sizeof( struct libvlc_callback_entry_t ) );
131 entry->f_callback = f_callback;
132 entry->i_event_type = i_event_type;
133 entry->p_user_data = user_data;
135 switch ( i_event_type )
138 callback_name = "volume-change";
140 case INPUT_POSITION_CHANGED:
144 RAISEVOID( "Unsupported event." );
147 res = var_AddCallback( p_instance->p_libvlc_int,
152 if (res != VLC_SUCCESS)
155 RAISEVOID("Internal callback registration was not successful. Callback not registered.");
158 vlc_mutex_lock( &p_instance->instance_lock );
159 add_callback_to_list( entry, &p_instance->p_callback_list );
160 vlc_mutex_unlock( &p_instance->instance_lock );
165 void libvlc_event_remove_all_callbacks( libvlc_instance_t *p_instance,
166 libvlc_exception_t *p_e )
168 struct libvlc_callback_entry_list_t *p_listitem;
170 vlc_mutex_lock( &p_instance->instance_lock );
172 p_listitem = p_instance->p_callback_list;
176 remove_variable_callback( p_instance, p_listitem->elmt ); /* FIXME: We could warn on error */
177 p_listitem = p_listitem->next;
180 p_instance->p_callback_list = NULL;
182 vlc_mutex_unlock( &p_instance->instance_lock );
185 void libvlc_event_remove_callback( libvlc_instance_t *p_instance,
186 libvlc_event_type_t i_event_type,
187 libvlc_callback_t f_callback,
189 libvlc_exception_t *p_e )
191 struct libvlc_callback_entry_list_t *p_listitem;
193 vlc_mutex_lock( &p_instance->instance_lock );
195 p_listitem = p_instance->p_callback_list;
199 if( p_listitem->elmt->f_callback == f_callback
200 && ( p_listitem->elmt->i_event_type == i_event_type )
201 && ( p_listitem->elmt->p_user_data == p_user_data )
205 remove_variable_callback( p_instance, p_listitem->elmt ); /* FIXME: We should warn on error */
207 if( p_listitem->prev )
208 p_listitem->prev->next = p_listitem->next;
210 p_instance->p_callback_list = p_listitem->next;
213 p_listitem->next->prev = p_listitem->prev;
215 free( p_listitem->elmt );
221 p_listitem = p_listitem->next;
223 vlc_mutex_unlock( &p_instance->instance_lock );