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
9 * Authors: Pierre d'Herbemont <pdherbemont # videolan.org >
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
34 #include <vlc_common.h>
38 #include <vlc_events.h>
39 #include <vlc_arrays.h>
41 /*****************************************************************************
42 * Documentation : Read vlc_events.h
43 *****************************************************************************/
45 /*****************************************************************************
47 *****************************************************************************/
49 typedef struct vlc_event_listener_t
52 vlc_event_callback_t pf_callback
;
53 } vlc_event_listener_t
;
55 /*****************************************************************************
57 *****************************************************************************/
59 #undef vlc_event_manager_init
61 * Initialize event manager object
62 * p_obj is the object that contains the event manager. But not
63 * necessarily a vlc_object_t (an input_item_t is not a vlc_object_t
66 void vlc_event_manager_init( vlc_event_manager_t
* p_em
, void * p_obj
)
69 /* This is an unsafe work-around for a long-standing playlist bug.
70 * Do not rely on this. */
71 vlc_mutex_init_recursive( &p_em
->lock
);
73 for( size_t i
= 0; i
< ARRAY_SIZE(p_em
->events
); i
++ )
74 ARRAY_INIT( p_em
->events
[i
].listeners
);
78 * Destroy the event manager
80 void vlc_event_manager_fini( vlc_event_manager_t
* p_em
)
82 struct vlc_event_listener_t
* listener
;
84 vlc_mutex_destroy( &p_em
->lock
);
86 for( size_t i
= 0; i
< ARRAY_SIZE(p_em
->events
); i
++ )
88 struct vlc_event_listeners_group_t
*slot
= p_em
->events
+ i
;
90 FOREACH_ARRAY( listener
, slot
->listeners
)
93 ARRAY_RESET( slot
->listeners
);
98 * Send an event to the listener attached to this p_em.
100 void vlc_event_send( vlc_event_manager_t
* p_em
,
101 vlc_event_t
* p_event
)
103 vlc_event_listeners_group_t
*slot
= &p_em
->events
[p_event
->type
];
104 vlc_event_listener_t
* listener
;
106 /* Fill event with the sending object now */
107 p_event
->p_obj
= p_em
->p_obj
;
109 vlc_mutex_lock( &p_em
->lock
) ;
111 FOREACH_ARRAY( listener
, slot
->listeners
)
112 listener
->pf_callback( p_event
, listener
->p_user_data
);
115 vlc_mutex_unlock( &p_em
->lock
);
118 #undef vlc_event_attach
120 * Add a callback for an event.
122 int vlc_event_attach( vlc_event_manager_t
* p_em
,
123 vlc_event_type_t event_type
,
124 vlc_event_callback_t pf_callback
,
127 vlc_event_listener_t
* listener
;
128 vlc_event_listeners_group_t
*slot
= &p_em
->events
[event_type
];
130 listener
= malloc(sizeof(vlc_event_listener_t
));
134 listener
->p_user_data
= p_user_data
;
135 listener
->pf_callback
= pf_callback
;
137 vlc_mutex_lock( &p_em
->lock
);
138 ARRAY_APPEND( slot
->listeners
, listener
);
139 vlc_mutex_unlock( &p_em
->lock
);
144 * Remove a callback for an event.
147 void vlc_event_detach( vlc_event_manager_t
*p_em
,
148 vlc_event_type_t event_type
,
149 vlc_event_callback_t pf_callback
,
152 vlc_event_listeners_group_t
*slot
= &p_em
->events
[event_type
];
153 struct vlc_event_listener_t
* listener
;
155 vlc_mutex_lock( &p_em
->lock
);
157 FOREACH_ARRAY( listener
, slot
->listeners
)
158 if( listener
->pf_callback
== pf_callback
&&
159 listener
->p_user_data
== p_user_data
)
161 /* that's our listener */
162 ARRAY_REMOVE( slot
->listeners
,
163 fe_idx
/* This comes from the macro (and that's why
165 vlc_mutex_unlock( &p_em
->lock
);
171 vlc_assert_unreachable();