1 /*****************************************************************************
2 * events.c: events interface
3 * This library provides an interface to the send and receive events.
4 * It is more lightweight than variable based callback.
5 *****************************************************************************
6 * Copyright (C) 1998-2005 VLC authors and VideoLAN
8 * Authors: Pierre d'Herbemont <pdherbemont # videolan.org >
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
33 #include <vlc_common.h>
37 #include <vlc_events.h>
38 #include <vlc_arrays.h>
40 /*****************************************************************************
41 * Documentation : Read vlc_events.h
42 *****************************************************************************/
44 /*****************************************************************************
46 *****************************************************************************/
48 typedef struct vlc_event_listener_t
51 vlc_event_callback_t pf_callback
;
52 } vlc_event_listener_t
;
54 /*****************************************************************************
56 *****************************************************************************/
58 #undef vlc_event_manager_init
60 * Initialize event manager object
61 * p_obj is the object that contains the event manager. But not
62 * necessarily a vlc_object_t (an input_item_t is not a vlc_object_t
65 void vlc_event_manager_init( vlc_event_manager_t
* p_em
, void * p_obj
)
68 /* This is an unsafe work-around for a long-standing playlist bug.
69 * Do not rely on this. */
70 vlc_mutex_init_recursive( &p_em
->lock
);
72 for( size_t i
= 0; i
< ARRAY_SIZE(p_em
->events
); i
++ )
73 ARRAY_INIT( p_em
->events
[i
].listeners
);
77 * Destroy the event manager
79 void vlc_event_manager_fini( vlc_event_manager_t
* p_em
)
81 struct vlc_event_listener_t
* listener
;
83 for( size_t i
= 0; i
< ARRAY_SIZE(p_em
->events
); i
++ )
85 struct vlc_event_listeners_group_t
*slot
= p_em
->events
+ i
;
87 ARRAY_FOREACH( listener
, slot
->listeners
)
90 ARRAY_RESET( slot
->listeners
);
95 * Send an event to the listener attached to this p_em.
97 void vlc_event_send( vlc_event_manager_t
* p_em
,
98 vlc_event_t
* p_event
)
100 vlc_event_listeners_group_t
*slot
= &p_em
->events
[p_event
->type
];
101 vlc_event_listener_t
* listener
;
103 /* Fill event with the sending object now */
104 p_event
->p_obj
= p_em
->p_obj
;
106 vlc_mutex_lock( &p_em
->lock
) ;
108 ARRAY_FOREACH( listener
, slot
->listeners
)
109 listener
->pf_callback( p_event
, listener
->p_user_data
);
111 vlc_mutex_unlock( &p_em
->lock
);
114 #undef vlc_event_attach
116 * Add a callback for an event.
118 int vlc_event_attach( vlc_event_manager_t
* p_em
,
119 vlc_event_type_t event_type
,
120 vlc_event_callback_t pf_callback
,
123 vlc_event_listener_t
* listener
;
124 vlc_event_listeners_group_t
*slot
= &p_em
->events
[event_type
];
126 listener
= malloc(sizeof(vlc_event_listener_t
));
130 listener
->p_user_data
= p_user_data
;
131 listener
->pf_callback
= pf_callback
;
133 vlc_mutex_lock( &p_em
->lock
);
134 ARRAY_APPEND( slot
->listeners
, listener
);
135 vlc_mutex_unlock( &p_em
->lock
);
140 * Remove a callback for an event.
143 void vlc_event_detach( vlc_event_manager_t
*p_em
,
144 vlc_event_type_t event_type
,
145 vlc_event_callback_t pf_callback
,
148 vlc_event_listeners_group_t
*slot
= &p_em
->events
[event_type
];
150 vlc_mutex_lock( &p_em
->lock
);
152 for (int i
= 0; i
< slot
->listeners
.i_size
; ++i
)
154 struct vlc_event_listener_t
*listener
= slot
->listeners
.p_elems
[i
];
155 if( listener
->pf_callback
== pf_callback
&&
156 listener
->p_user_data
== p_user_data
)
158 /* that's our listener */
159 ARRAY_REMOVE( slot
->listeners
, i
);
160 vlc_mutex_unlock( &p_em
->lock
);
166 vlc_assert_unreachable();