]> git.sesse.net Git - vlc/commitdiff
mozilla: rework events
authorJean-Paul Saman <jean-paul.saman@m2x.nl>
Fri, 30 Jul 2010 09:51:12 +0000 (11:51 +0200)
committerJean-Paul Saman <jean-paul.saman@m2x.nl>
Tue, 7 Sep 2010 08:26:27 +0000 (10:26 +0200)
The mozilla webplugin events do not support arguments and expose all events available in libvlc. Most
of these events are not usefull for the webplugins and not being able to pass arguments is another limiting
issue. This patch addresses both problems at the same time.

The mozilla webplugin limits supports to the libvlc_MediaPlayer* events just like the ActiveX webplugin does.
These events are usefull in the context of a webplugin.

Ommit the 'libvlc_' prefix from the libvlc_MediaPlayer* events to obtain the events name that must be
used from JavaScript to listen on the event. Example:

- libvlc_MediaPlayerOpening becomes 'MediaPlayerOpening'
- libvlc_MediaPlayerNothingSpecial becoms 'MediaPlayerNothingSpecial'

Signed-off-by: Jean-Paul Saman <jean-paul.saman@m2x.nl>
Conflicts:

projects/mozilla/vlcplugin.cpp
projects/mozilla/vlcplugin.h

projects/mozilla/control/npolibvlc.cpp
projects/mozilla/control/nporuntime.cpp
projects/mozilla/vlcplugin.cpp
projects/mozilla/vlcplugin.h
projects/mozilla/vlcshell.h

index 2e6440ec06840e8bbf39432e3d664f6db4a40382..8e1b130610a1b1280ac5ac4c299734b073af9923 100644 (file)
@@ -194,17 +194,26 @@ RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
             return INVOKERESULT_GENERIC_ERROR;
         }
 
-        NPObject *listener = NPVARIANT_TO_OBJECT(args[1]);
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
 
         bool b;
-        if(ID_root_removeeventlistener!=index)
-            b = p_plugin->events.insert(NPVARIANT_TO_STRING(args[0]),
-                                     listener, NPVARIANT_TO_BOOLEAN(args[2]));
+        if( ID_root_addeventlistener == index )
+        {
+            NPN_RetainObject( NPVARIANT_TO_OBJECT(args[1]) );
+            b = p_plugin->events.insert( NPVARIANT_TO_STRING(args[0]),
+                                         NPVARIANT_TO_OBJECT(args[1]),
+                                         NPVARIANT_TO_BOOLEAN(args[2]) );
+            if( !b )
+                NPN_ReleaseObject( NPVARIANT_TO_OBJECT(args[1]) );
+        }
         else
-            b = p_plugin->events.remove(NPVARIANT_TO_STRING(args[0]),
-                                     listener, NPVARIANT_TO_BOOLEAN(args[2]));
-
+        {
+            b = p_plugin->events.remove( NPVARIANT_TO_STRING(args[0]),
+                                         NPVARIANT_TO_OBJECT(args[1]),
+                                         NPVARIANT_TO_BOOLEAN(args[2]) );
+            if( b )
+                NPN_ReleaseObject( NPVARIANT_TO_OBJECT(args[1]) );
+        }
         VOID_TO_NPVARIANT(result);
 
         return b ? INVOKERESULT_NO_ERROR : INVOKERESULT_GENERIC_ERROR;
@@ -1927,4 +1936,3 @@ LibvlcDeinterlaceNPObject::invoke(int index, const NPVariant *args,
     }
     return INVOKERESULT_NO_ERROR;
 }
-
index 396bbb9fb6f0a77ef90073f014d01c8a8d499e14..f60e1ae07ccaa99397aa3371350d7ec9b96a05ac 100644 (file)
@@ -125,4 +125,3 @@ RuntimeNPObject::invokeResultString(const char *psz, NPVariant &result)
     }
     return INVOKERESULT_NO_ERROR;
 }
-
index dea87e6a8ef98256f1c131057f1afab7d7220b66..320b19005c92ca3e2d1c912c21f07f7abc6e2a7b 100644 (file)
@@ -29,6 +29,7 @@
 #include "config.h"
 
 #include "vlcplugin.h"
+
 #include "control/npolibvlc.h"
 
 #include <ctype.h>
@@ -102,56 +103,84 @@ static void plugin_unlock(plugin_lock_t *lock)
 }
 
 /*****************************************************************************
- * VlcPlugin constructor and destructor
+ * Event Object
  *****************************************************************************/
-#if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) < 20)
-VlcPlugin::VlcPlugin( NPP instance, uint16 mode ) :
-#else
-VlcPlugin::VlcPlugin( NPP instance, uint16_t mode ) :
-#endif
-    i_npmode(mode),
-    b_stream(0),
-    b_autoplay(1),
-    b_toolbar(0),
-    psz_text(NULL),
-    psz_target(NULL),
-    playlist_index(-1),
-    libvlc_instance(NULL),
-    libvlc_media_list(NULL),
-    libvlc_media_player(NULL),
-    p_scriptClass(NULL),
-    p_browser(instance),
-    psz_baseURL(NULL)
-#if defined(XP_WIN)
-    ,pf_wndproc(NULL)
-#endif
-#if defined(XP_UNIX)
-    ,i_width((unsigned)-1)
-    ,i_height((unsigned)-1)
-    ,i_tb_width(0)
-    ,i_tb_height(0)
-    ,i_last_position(0)
-    ,p_btnPlay(NULL)
-    ,p_btnPause(NULL)
-    ,p_btnStop(NULL)
-    ,p_btnMute(NULL)
-    ,p_btnUnmute(NULL)
-    ,p_btnFullscreen(NULL)
-    ,p_btnTime(NULL)
-    ,p_timeline(NULL)
-#endif
+static void handle_input_event(const libvlc_event_t* event, void *param);
+static void handle_changed_event(const libvlc_event_t* event, void *param);
+
+static vlcplugin_event_t vlcevents[] = {
+    { "MediaPlayerMediaChanged", libvlc_MediaPlayerMediaChanged, handle_input_event },
+    { "MediaPlayerNothingSpecial", libvlc_MediaPlayerNothingSpecial, handle_input_event },
+    { "MediaPlayerOpening", libvlc_MediaPlayerOpening, handle_input_event },
+    { "MediaPlayerBuffering", libvlc_MediaPlayerBuffering, handle_input_event },
+    { "MediaPlayerPlaying", libvlc_MediaPlayerPlaying, handle_input_event },
+    { "MediaPlayerPaused", libvlc_MediaPlayerPaused, handle_input_event },
+    { "MediaPlayerStopped", libvlc_MediaPlayerStopped, handle_input_event },
+    { "MediaPlayerForward", libvlc_MediaPlayerForward, handle_input_event },
+    { "MediaPlayerBackward", libvlc_MediaPlayerBackward, handle_input_event },
+    { "MediaPlayerEndReached", libvlc_MediaPlayerEndReached, handle_input_event },
+    { "MediaPlayerEncounteredError", libvlc_MediaPlayerEncounteredError, handle_input_event },
+    { "MediaPlayerTimeChanged", libvlc_MediaPlayerTimeChanged, handle_changed_event },
+    { "MediaPlayerPositionChanged", libvlc_MediaPlayerPositionChanged, handle_changed_event },
+    { "MediaPlayerSeekableChanged", libvlc_MediaPlayerSeekableChanged, handle_changed_event },
+    { "MediaPlayerPausableChanged", libvlc_MediaPlayerPausableChanged, handle_changed_event },
+    { "MediaPlayerTitleChanged", libvlc_MediaPlayerTitleChanged, handle_changed_event },
+    { "MediaPlayerLengthChanged", libvlc_MediaPlayerLengthChanged, handle_changed_event },
+};
+
+static void handle_input_event(const libvlc_event_t* event, void *param)
 {
-    memset(&npwindow, 0, sizeof(NPWindow));
-#if defined(XP_UNIX)
-    memset(&npvideo, 0, sizeof(Window));
-    memset(&npcontrol, 0, sizeof(Window));
-#endif
+    VlcPlugin *plugin = (VlcPlugin*)param;
+    switch( event->type )
+    {
+        case libvlc_MediaPlayerNothingSpecial:
+        case libvlc_MediaPlayerOpening:
+        case libvlc_MediaPlayerBuffering:
+        case libvlc_MediaPlayerPlaying:
+        case libvlc_MediaPlayerPaused:
+        case libvlc_MediaPlayerStopped:
+        case libvlc_MediaPlayerForward:
+        case libvlc_MediaPlayerBackward:
+        case libvlc_MediaPlayerEndReached:
+        case libvlc_MediaPlayerEncounteredError:
+            plugin->event_callback(event, NULL, 0, param);
+            break;
+        default: /* ignore all other libvlc_event_type_t */
+            break;
+    }
 }
 
-static bool boolValue(const char *value) {
-    return ( !strcmp(value, "1") ||
-             !strcasecmp(value, "true") ||
-             !strcasecmp(value, "yes") );
+static void handle_changed_event(const libvlc_event_t* event, void *param)
+{
+    uint32_t   npcount = 1;
+    NPVariant *npparam = (NPVariant *) NPN_MemAlloc( sizeof(NPVariant) * npcount );
+
+    VlcPlugin *plugin = (VlcPlugin*)param;
+    switch( event->type )
+    {
+        case libvlc_MediaPlayerTimeChanged:
+            DOUBLE_TO_NPVARIANT(event->u.media_player_time_changed.new_time, npparam[0]);
+            break;
+        case libvlc_MediaPlayerPositionChanged:
+            DOUBLE_TO_NPVARIANT(event->u.media_player_position_changed.new_position, npparam[0]);
+            break;
+        case libvlc_MediaPlayerSeekableChanged:
+            BOOLEAN_TO_NPVARIANT(event->u.media_player_seekable_changed.new_seekable, npparam[0]);
+            break;
+        case libvlc_MediaPlayerPausableChanged:
+            BOOLEAN_TO_NPVARIANT(event->u.media_player_pausable_changed.new_pausable, npparam[0]);
+            break;
+        case libvlc_MediaPlayerTitleChanged:
+            BOOLEAN_TO_NPVARIANT(event->u.media_player_title_changed.new_title, npparam[0]);
+            break;
+        case libvlc_MediaPlayerLengthChanged:
+            DOUBLE_TO_NPVARIANT(event->u.media_player_length_changed.new_length, npparam[0]);
+            break;
+        default: /* ignore all other libvlc_event_type_t */
+            NPN_MemFree( npparam );
+            return;
+    }
+    plugin->event_callback(event, npparam, npcount, param);
 }
 
 bool EventObj::init()
@@ -167,25 +196,36 @@ EventObj::~EventObj()
 
 void EventObj::deliver(NPP browser)
 {
-    NPVariant result;
-    NPVariant params[1];
-
     plugin_lock(&lock);
 
-    for( ev_l::iterator i=_elist.begin();i!=_elist.end();++i )
+    for( ev_l::iterator iter = _elist.begin(); iter != _elist.end(); ++iter )
     {
-        libvlc_event_type_t event = *i;
-        STRINGZ_TO_NPVARIANT(libvlc_event_type_name(event), params[0]);
-
-        // Invalid events aren't supposed to be queued up.
-        // if( !have_event(event) ) continue;
-
-        for( lr_l::iterator j=_llist.begin();j!=_llist.end();++j )
+        for( lr_l::iterator j = _llist.begin(); j != _llist.end(); ++j )
         {
-            if (j->get(event))
+            if( j->event_type() == iter->event_type() )
             {
-                NPN_InvokeDefault(browser, j->listener(), params, 1, &result);
-                NPN_ReleaseVariantValue(&result);
+                NPVariant result;
+                NPVariant *params = iter->params();
+                uint32_t   count  = iter->count();
+                assert( params );
+
+                NPObject *listener = j->listener();
+                assert( listener );
+
+                NPN_InvokeDefault( browser, listener, params, count, &result );
+                NPN_ReleaseVariantValue( &result );
+
+                for( uint32_t n = 0; n < count; n++ )
+                {
+                    if( NPVARIANT_IS_STRING(params[n]) )
+                        NPN_MemFree( (void*) NPVARIANT_TO_STRING(params[n]).UTF8Characters );
+                    else if( NPVARIANT_IS_OBJECT(params[n]) )
+                    {
+                        NPN_ReleaseObject( NPVARIANT_TO_OBJECT(params[n]) );
+                        NPN_MemFree( (void*)NPVARIANT_TO_OBJECT(params[n]) );
+                    }
+                }
+                NPN_MemFree( params );
             }
         }
     }
@@ -194,129 +234,175 @@ void EventObj::deliver(NPP browser)
     plugin_unlock(&lock);
 }
 
-void VlcPlugin::eventAsync(void *param)
-{
-    VlcPlugin *plugin = (VlcPlugin*)param;
-    plugin->events.deliver(plugin->getBrowser());
-}
-
-void EventObj::callback(const libvlc_event_t* event)
+void EventObj::callback(const libvlc_event_t* event,
+                        NPVariant *npparams, uint32_t count)
 {
     plugin_lock(&lock);
-
-    if( have_event(event->type) )
-        _elist.push_back(event->type);
-
+    _elist.push_back(VLCEvent(event->type, npparams, count));
     plugin_unlock(&lock);
 }
 
-void VlcPlugin::event_callback(const libvlc_event_t* event, void *param)
+vlcplugin_event_t *EventObj::find_event(const char *s) const
 {
-    VlcPlugin *plugin = (VlcPlugin*)param;
-#if defined(XP_UNIX)
-    plugin->events.callback(event);
-    NPN_PluginThreadAsyncCall(plugin->getBrowser(), eventAsync, plugin);
-#else
-#warning NPN_PluginThreadAsyncCall not implemented yet.
-    printf("No NPN_PluginThreadAsyncCall(), doing nothing.");
-#endif
+    for( int i = 0; i < ARRAY_SIZE(vlcevents); i++ )
+    {
+        if( strncmp(vlcevents[i].name, s, strlen(vlcevents[i].name)) == 0 )
+            return &vlcevents[i];
+    }
+    return NULL;
 }
 
-inline EventObj::event_t EventObj::find_event(const char *s) const
+const char *EventObj::find_name(const libvlc_event_t *event)
 {
-    event_t i;
-    for(i=0;i<maxbit();++i)
-        if(!strcmp(s,libvlc_event_type_name(i)))
-            break;
-    return i;
+    for( int i = 0; i < ARRAY_SIZE(vlcevents); i++ )
+    {
+        if( vlcevents[i].libvlc_type == event->type )
+            return vlcevents[i].name;
+    }
+    return NULL;
 }
 
-bool EventObj::insert(const NPString &s, NPObject *l, bool b)
+bool EventObj::insert(const NPString &name, NPObject *listener, bool bubble)
 {
-    event_t e = find_event(s.UTF8Characters);
-    if( e>=maxbit() )
-        return false;
-
-    if( !have_event(e) && !ask_for_event(e) )
+    vlcplugin_event_t *event = find_event(name.UTF8Characters);
+    if( !event )
         return false;
 
-    lr_l::iterator i;
-    for(i=_llist.begin();i!=_llist.end();++i)
-        if(i->listener()==l && i->bubble()==b)
+    lr_l::iterator iter;
+    for( iter = _llist.begin(); iter != _llist.end(); ++iter )
+        if( iter->listener() == listener && iter->bubble() == bubble )
             break;
 
-    if( i == _llist.end() ) {
-        _llist.push_back(Listener(e,l,b));
-    } else {
-        if( i->get(e) )
-            return false;
-        i->get(e);
+    if( iter == _llist.end() )
+    {
+        _llist.push_back(Listener(event, listener, bubble));
+        return true;
     }
-    return true;
-}
 
+    return false;
+}
 
-bool EventObj::remove(const NPString &s, NPObject *l, bool b)
+bool EventObj::remove(const NPString &name, NPObject *listener, bool bubble)
 {
-    event_t e = find_event(s.UTF8Characters);
-    if( e>=maxbit() || !get(e) )
+    vlcplugin_event_t *event = find_event(name.UTF8Characters);
+    if( !event )
         return false;
 
-    bool any=false;
-    for(lr_l::iterator i=_llist.begin();i!=_llist.end();)
+    for( lr_l::iterator iter = _llist.begin(); iter !=_llist.end(); iter++ )
     {
-        if(i->listener()!=l || i->bubble()!=b)
-            any|=i->get(e);
-        else
+        if( iter->event_type() == event->libvlc_type &&
+            iter->listener() == listener &&
+            iter->bubble() == bubble )
         {
-            i->reset(e);
-            if(i->empty())
-            {
-                i=_llist.erase(i);
-                continue;
-            }
+            iter = _llist.erase(iter);
+            return true;
         }
-        ++i;
     }
-    if(!any)
-        unask_for_event(e);
 
-    return true;
+    return false;
 }
 
-
-void EventObj::hook_manager(libvlc_event_manager_t *em,
-                            libvlc_callback_t cb, void *udata)
+void EventObj::hook_manager( libvlc_event_manager_t *em, void *userdata )
 {
-    _em = em; _cb = cb; _ud = udata;
-    if( !_em )
-        return;
-    for(size_t i=0;i<maxbit();++i)
-        if(get(i))
-            libvlc_event_attach(_em, i, _cb, _ud);
+    _em = em;
+
+    if( _em )
+    {
+        /* attach all libvlc events we care about */
+        for( int i = 0; i < ARRAY_SIZE(vlcevents); i++ )
+        {
+            libvlc_event_attach( _em, vlcevents[i].libvlc_type,
+                                      vlcevents[i].libvlc_callback,
+                                      userdata );
+        }
+    }
 }
 
-void EventObj::unhook_manager()
+void EventObj::unhook_manager( void *userdata )
 {
-    if( !_em )
-    return;
-    for(size_t i=0;i<maxbit();++i)
-        if(get(i))
-            libvlc_event_detach(_em, i, _cb, _ud);
+    if( _em )
+    {
+               /* detach all libvlc events we cared about */
+        for( int i = 0; i < ARRAY_SIZE(vlcevents); i++ )
+        {
+            libvlc_event_detach( _em, vlcevents[i].libvlc_type,
+                                      vlcevents[i].libvlc_callback,
+                                      userdata );
+        }
+    }
 }
 
-
-bool EventObj::ask_for_event(event_t e)
+/*****************************************************************************
+ * VlcPlugin constructor and destructor
+ *****************************************************************************/
+#if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) < 20)
+VlcPlugin::VlcPlugin( NPP instance, uint16 mode ) :
+#else
+VlcPlugin::VlcPlugin( NPP instance, uint16_t mode ) :
+#endif
+    i_npmode(mode),
+    b_stream(0),
+    b_autoplay(1),
+    b_toolbar(0),
+    psz_text(NULL),
+    psz_target(NULL),
+    playlist_index(-1),
+    libvlc_instance(NULL),
+    libvlc_media_list(NULL),
+    libvlc_media_player(NULL),
+    p_scriptClass(NULL),
+    p_browser(instance),
+    psz_baseURL(NULL)
+#if defined(XP_WIN)
+    ,pf_wndproc(NULL)
+#endif
+#if defined(XP_UNIX)
+    ,i_width((unsigned)-1)
+    ,i_height((unsigned)-1)
+    ,i_tb_width(0)
+    ,i_tb_height(0)
+    ,i_last_position(0)
+    ,p_btnPlay(NULL)
+    ,p_btnPause(NULL)
+    ,p_btnStop(NULL)
+    ,p_btnMute(NULL)
+    ,p_btnUnmute(NULL)
+    ,p_btnFullscreen(NULL)
+    ,p_btnTime(NULL)
+    ,p_timeline(NULL)
+#endif
 {
-    return _em?0==libvlc_event_attach(_em, e, _cb, _ud):false;
+    memset(&npwindow, 0, sizeof(NPWindow));
+#if defined(XP_UNIX)
+    memset(&npvideo, 0, sizeof(Window));
+    memset(&npcontrol, 0, sizeof(Window));
+#endif
 }
 
+static bool boolValue(const char *value) {
+    return ( !strcmp(value, "1") ||
+             !strcasecmp(value, "true") ||
+             !strcasecmp(value, "yes") );
+}
 
-void EventObj::unask_for_event(event_t e)
+void VlcPlugin::eventAsync(void *param)
 {
-    if(_em) libvlc_event_detach(_em, e, _cb, _ud);
+    VlcPlugin *plugin = (VlcPlugin*)param;
+    plugin->events.deliver(plugin->getBrowser());
 }
 
+void VlcPlugin::event_callback(const libvlc_event_t* event,
+                NPVariant *npparams, uint32_t npcount, void *userdata)
+{
+    VlcPlugin *plugin = (VlcPlugin*)userdata;
+#if defined(XP_UNIX)
+    plugin->events.callback(event, npparams, npcount);
+    NPN_PluginThreadAsyncCall(plugin->getBrowser(), eventAsync, plugin);
+#else
+#warning NPN_PluginThreadAsyncCall not implemented yet.
+    printf("No NPN_PluginThreadAsyncCall(), doing nothing.\n");
+#endif
+}
 
 NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[])
 {
@@ -501,13 +587,13 @@ VlcPlugin::~VlcPlugin()
     {
         if( playlist_isplaying() )
             playlist_stop();
-        events.unhook_manager();
+        events.unhook_manager( this );
         libvlc_media_player_release( libvlc_media_player );
     }
     if( libvlc_media_list )
         libvlc_media_list_release( libvlc_media_list );
     if( libvlc_instance )
-        libvlc_release(libvlc_instance);
+        libvlc_release( libvlc_instance );
 }
 
 /*****************************************************************************
@@ -593,25 +679,26 @@ bool VlcPlugin::playlist_select( int idx )
     {
         if( playlist_isplaying() )
             playlist_stop();
-        events.unhook_manager();
+        events.unhook_manager( this );
         libvlc_media_player_release( libvlc_media_player );
         libvlc_media_player = NULL;
     }
 
-    libvlc_media_player = libvlc_media_player_new_from_media(p_m);
+    libvlc_media_player = libvlc_media_player_new_from_media( p_m );
     if( libvlc_media_player )
     {
         set_player_window();
-        events.hook_manager(
-                      libvlc_media_player_event_manager(libvlc_media_player),
-                      event_callback, this);
+
+        libvlc_event_manager_t *p_em;
+        p_em = libvlc_media_player_event_manager( libvlc_media_player );
+        events.hook_manager( p_em, this );
     }
 
     libvlc_media_release( p_m );
     return true;
 
 bad_unlock:
-    libvlc_media_list_unlock(libvlc_media_list);
+    libvlc_media_list_unlock( libvlc_media_list );
     return false;
 }
 
index 5e6332d65f8e460560c29ee422b0e0ac7c63bc00..e625611d030d1c5155a1d65499b9cc5522aca52c 100644 (file)
 #   define __MIN(a, b)   ( ((a) < (b)) ? (a) : (b) )
 #endif
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 #include <npapi.h>
 #include <vector>
+#include <assert.h>
 
 #include "control/nporuntime.h"
 
-
 typedef struct {
 #if defined(XP_UNIX)
     pthread_mutex_t mutex;
@@ -94,7 +96,6 @@ typedef struct {
 #endif
 } plugin_lock_t;
 
-
 typedef enum vlc_toolbar_clicked_e {
     clicked_Unknown = 0,
     clicked_Play,
@@ -107,82 +108,80 @@ typedef enum vlc_toolbar_clicked_e {
     clicked_Unmute
 } vlc_toolbar_clicked_t;
 
+typedef struct {
+    const char *name;                      /* event name */
+    const libvlc_event_type_t libvlc_type; /* libvlc event type */
+    libvlc_callback_t libvlc_callback;     /* libvlc callback function */
+} vlcplugin_event_t;
 
-// Note that the accessor functions are unsafe, but this is handled in
-// the next layer up. 64bit uints can be substituted to taste (shift=6).
-template<size_t M> class bitmap
-{
-private:
-    typedef uint32_t bitu_t; enum { shift=5 };
-    enum { bmax=M, bpu=1<<shift, mask=bpu-1, units=(bmax+bpu-1)/bpu };
-    bitu_t bits[units];
-public:
-    bool get(size_t idx) const { return bits[idx>>shift]&(1<<(idx&mask)); }
-    void set(size_t idx)       { bits[idx>>shift]|=  1<<(idx&mask);  }
-    void reset(size_t idx)     { bits[idx>>shift]&=~(1<<(idx&mask)); }
-    void toggle(size_t idx)    { bits[idx>>shift]^=  1<<(idx&mask);  }
-    size_t maxbit() const      { return bmax; }
-    void clear()               { memset(bits,0,sizeof(bits)); }
-    bitmap() { clear(); }
-    ~bitmap() { }
-    bool empty() const { // naive invert() will break this
-        for(size_t i=0;i<units;++i)
-            if(bits[i]) return false;
-        return true;
-    }
-};
-
-typedef bitmap<libvlc_VlmMediaInstanceStatusError+1> eventtypes_bitmap_t;
-
-
-class EventObj: private eventtypes_bitmap_t
+class EventObj
 {
 private:
-    typedef libvlc_event_type_t event_t;
-    bool have_event(event_t e) const { return e<maxbit()?get(e):false; }
 
-    class Listener: public eventtypes_bitmap_t
+    class Listener
     {
     public:
-        Listener(event_t e,NPObject *o,bool b): _l(o), _b(b)
-            { NPN_RetainObject(o); set(e); }
-        Listener(): _l(NULL), _b(false) { }
-        ~Listener() { if(_l) NPN_ReleaseObject(_l); }
-        NPObject *listener() const { return _l; }
-        bool bubble() const { return _b; }
+        Listener(vlcplugin_event_t *event, NPObject *p_object, bool b_bubble):
+            _event(event), _listener(p_object), _bubble(b_bubble)
+            {
+                assert(event);
+                assert(p_object);
+            }
+        Listener(): _event(NULL), _listener(NULL), _bubble(false) { }
+        ~Listener()
+            {
+            }
+        const libvlc_event_type_t event_type() const { return _event->libvlc_type; }
+        NPObject *listener() const { return _listener; }
+        bool bubble() const { return _bubble; }
     private:
-        NPObject *_l;
-        bool _b;
+        vlcplugin_event_t *_event;
+        NPObject *_listener;
+        bool _bubble;
     };
 
-    libvlc_event_manager_t *_em;
-    libvlc_callback_t _cb;
-    void *_ud;
+    class VLCEvent
+    {
+    public:
+        VLCEvent(libvlc_event_type_t libvlc_event_type, NPVariant *npparams, uint32_t npcount):
+            _libvlc_event_type(libvlc_event_type), _npparams(npparams), _npcount(npcount)
+            {
+            }
+        VLCEvent(): _libvlc_event_type(0), _npparams(NULL), _npcount(0) { }
+        ~VLCEvent()
+            {
+            }
+        const libvlc_event_type_t event_type() { return _libvlc_event_type; }
+        NPVariant *params() const { return _npparams; }
+        const uint32_t count() { return _npcount; }
+    private:
+        libvlc_event_type_t _libvlc_event_type;
+        NPVariant *_npparams;
+        uint32_t _npcount;
+    };
+    libvlc_event_manager_t *_em; /* libvlc media_player event manager */
 public:
     EventObj(): _em(NULL)  { /* deferred to init() */ }
     bool init();
     ~EventObj();
 
     void deliver(NPP browser);
-    void callback(const libvlc_event_t*);
-    bool insert(const NPString &, NPObject *, bool);
-    bool remove(const NPString &, NPObject *, bool);
-    void unhook_manager();
-    void hook_manager(libvlc_event_manager_t *,libvlc_callback_t, void *);
+    void callback(const libvlc_event_t *event, NPVariant *npparams, uint32_t count);
+    bool insert(const NPString &name, NPObject *listener, bool bubble);
+    bool remove(const NPString &name, NPObject *listener, bool bubble);
+    void unhook_manager(void *);
+    void hook_manager(libvlc_event_manager_t *, void *);
 private:
-    event_t find_event(const char *s) const;
+    vlcplugin_event_t *find_event(const char *s) const;
+    const char *find_name(const libvlc_event_t *event);
     typedef std::vector<Listener> lr_l;
-    typedef std::vector<libvlc_event_type_t> ev_l;
-    lr_l _llist;
-    ev_l _elist;
+    typedef std::vector<VLCEvent> ev_l;
+    lr_l _llist; /* list of registered listeners with 'addEventListener' method */
+    ev_l _elist; /* scheduled events list for delivery to browser */
 
     plugin_lock_t lock;
-
-    bool ask_for_event(event_t e);
-    void unask_for_event(event_t e);
 };
 
-
 class VlcPlugin
 {
 public:
@@ -314,6 +313,7 @@ public:
     static bool canUseEventListener();
 
     EventObj events;
+    static void event_callback(const libvlc_event_t *, NPVariant *, uint32_t, void *);
 private:
     bool playlist_select(int);
     void set_player_window();
@@ -352,7 +352,6 @@ private:
 #endif
 
     static void eventAsync(void *);
-    static void event_callback(const libvlc_event_t *, void *);
 };
 
 /*******************************************************************************
index a91a06e4f78083ac43c1c45642682ffc0a90e102..909bcecd2e3a5b444fde3ae986c59cb8137ba1a9 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
- * vlcshell.hp:
+ * vlcshell.h:
  *****************************************************************************
- * Copyright (C) 2009 the VideoLAN team
+ * Copyright (C) 2009-2010 the VideoLAN team
  * $Id$
  *
  * Authors: Jean-Paul Saman <jpsaman@videolan.org>