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;
95 RAISEVOID (" Callback function is null ");
97 /* malloc/free strategy:
98 * - alloc-ded in libvlc_event_add_callback
99 * - free-ed by libvlc_event_add_callback on error
100 * - free-ed by libvlc_event_remove_callback
101 * - free-ed in libvlc_destroy threw libvlc_event_remove_callback
102 * when entry is destroyed
104 entry = malloc( sizeof( struct libvlc_callback_entry_t ) );
105 entry->f_callback = f_callback;
106 entry->i_event_type = i_event_type;
107 entry->p_user_data = user_data;
109 switch ( i_event_type )
112 callback_name = "volume-change";
114 case INPUT_POSITION_CHANGED:
118 RAISEVOID( "Unsupported event." );
121 res = var_AddCallback( p_instance->p_libvlc_int,
126 if (res != VLC_SUCCESS)
129 RAISEVOID("Internal callback registration was not successful. Callback not registered.");
132 add_callback_entry( entry, &p_instance->p_callback_list );
137 void libvlc_event_remove_all_callbacks( libvlc_instance_t *p_instance,
138 libvlc_exception_t *p_e )
140 struct libvlc_callback_entry_list_t *p_listitem = p_instance->p_callback_list;
144 libvlc_event_remove_callback( p_instance,
145 p_listitem->elmt->i_event_type,
146 p_listitem->elmt->f_callback,
147 p_listitem->elmt->p_user_data,
149 /* libvlc_event_remove_callback will reset the p_callback_list */
150 p_listitem = p_instance->p_callback_list;
154 void libvlc_event_remove_callback( libvlc_instance_t *p_instance,
155 libvlc_event_type_t i_event_type,
156 libvlc_callback_t f_callback,
158 libvlc_exception_t *p_e )
160 struct libvlc_callback_entry_list_t *p_listitem = p_instance->p_callback_list;
164 if( p_listitem->elmt->f_callback == f_callback
165 && ( p_listitem->elmt->i_event_type == i_event_type )
166 && ( p_listitem->elmt->p_user_data == p_user_data )
170 const char * callback_name = NULL;
173 if( p_listitem->prev )
174 p_listitem->prev->next = p_listitem->next;
176 p_instance->p_callback_list = p_listitem->next;
178 p_listitem->next->prev = p_listitem->prev;
180 switch ( i_event_type )
183 callback_name = "volume-change";
185 case INPUT_POSITION_CHANGED:
188 RAISEVOID( "Unsupported event." );
191 res = var_DelCallback( p_instance->p_libvlc_int,
192 callback_name, handle_event,
195 if (res != VLC_SUCCESS)
197 RAISEVOID("Internal callback unregistration was not successful. Callback not unregistered.");
200 free( p_listitem->elmt ); /* FIXME: need some locking here */
204 p_listitem = p_listitem->next;