]> git.sesse.net Git - vlc/blobdiff - mozilla/control/npolibvlc.cpp
Fix indentation
[vlc] / mozilla / control / npolibvlc.cpp
index 506bfa69af6409bb9940c29d3962060be0cbb3b7..7e3ae5fdbb093882c74ae62904ff5eb498096e24 100755 (executable)
@@ -43,6 +43,7 @@ LibvlcRootNPObject::LibvlcRootNPObject(NPP instance, const NPClass *aClass) :
 {\r
     audioObj = NPN_CreateObject(instance, RuntimeNPClass<LibvlcAudioNPObject>::getClass());\r
     inputObj = NPN_CreateObject(instance, RuntimeNPClass<LibvlcInputNPObject>::getClass());\r
+    logObj = NPN_CreateObject(instance, RuntimeNPClass<LibvlcLogNPObject>::getClass());\r
     playlistObj = NPN_CreateObject(instance, RuntimeNPClass<LibvlcPlaylistNPObject>::getClass());\r
     videoObj = NPN_CreateObject(instance,RuntimeNPClass<LibvlcVideoNPObject>::getClass());\r
 }\r
@@ -51,6 +52,7 @@ LibvlcRootNPObject::~LibvlcRootNPObject()
 {\r
     NPN_ReleaseObject(audioObj);\r
     NPN_ReleaseObject(inputObj);\r
+    NPN_ReleaseObject(logObj);\r
     NPN_ReleaseObject(playlistObj);\r
     NPN_ReleaseObject(videoObj);\r
 }\r
@@ -59,47 +61,114 @@ const NPUTF8 * const LibvlcRootNPObject::propertyNames[] =
 {\r
     "audio",\r
     "input",\r
+    "log",\r
     "playlist",\r
     "video",\r
+    "VersionInfo",\r
 };\r
 \r
 const int LibvlcRootNPObject::propertyCount = sizeof(LibvlcRootNPObject::propertyNames)/sizeof(NPUTF8 *);\r
 \r
 enum LibvlcRootNPObjectPropertyIds\r
 {\r
-    ID_audio = 0,\r
-    ID_input,\r
-    ID_playlist,\r
-    ID_video,\r
+    ID_root_audio = 0,\r
+    ID_root_input,\r
+    ID_root_log,\r
+    ID_root_playlist,\r
+    ID_root_video,\r
+    ID_root_VersionInfo,\r
 };\r
 \r
 RuntimeNPObject::InvokeResult LibvlcRootNPObject::getProperty(int index, NPVariant &result)\r
 {\r
-    switch( index )\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
     {\r
-        case ID_audio:\r
-            OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), result);\r
-            return INVOKERESULT_NO_ERROR;\r
-        case ID_input:\r
-            OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), result);\r
-            return INVOKERESULT_NO_ERROR;\r
-        case ID_playlist:\r
-            OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);\r
-            return INVOKERESULT_NO_ERROR;\r
-        case ID_video:\r
-            OBJECT_TO_NPVARIANT(NPN_RetainObject(videoObj), result);\r
-            return INVOKERESULT_NO_ERROR;\r
+        switch( index )\r
+        {\r
+            case ID_root_audio:\r
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            case ID_root_input:\r
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            case ID_root_log:\r
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(logObj), result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            case ID_root_playlist:\r
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            case ID_root_video:\r
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(videoObj), result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            case ID_root_VersionInfo:\r
+            {\r
+                int len = strlen(VLC_Version());\r
+                NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);\r
+                if( retval )\r
+                {\r
+                    memcpy(retval, VLC_Version(), len);\r
+                    STRINGN_TO_NPVARIANT(retval, len, result);\r
+                }\r
+                else\r
+                {\r
+                    NULL_TO_NPVARIANT(result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
+        }\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
 }\r
 \r
 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =\r
 {\r
-    /* no methods */\r
+    "versionInfo",\r
 };\r
 \r
 const int LibvlcRootNPObject::methodCount = sizeof(LibvlcRootNPObject::methodNames)/sizeof(NPUTF8 *);\r
 \r
+enum LibvlcRootNPObjectMethodIds\r
+{\r
+    ID_root_versionInfo,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_exception_t ex;\r
+        libvlc_exception_init(&ex);\r
+\r
+        switch( index )\r
+        {\r
+            case ID_root_versionInfo:\r
+                if( argCount == 0 )\r
+                {\r
+                    int len = strlen(VLC_Version());\r
+                    NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);\r
+                    if( retval )\r
+                    {\r
+                        memcpy(retval, VLC_Version(), len);\r
+                        STRINGN_TO_NPVARIANT(retval, len, result);\r
+                    }\r
+                    else\r
+                    {\r
+                        NULL_TO_NPVARIANT(result);\r
+                    }\r
+                    return INVOKERESULT_NO_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_SUCH_METHOD;\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
 /*\r
 ** implementation of libvlc audio object\r
 */\r
@@ -108,14 +177,18 @@ const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] =
 {\r
     "mute",\r
     "volume",\r
+    "track",\r
+    "channel",\r
 };\r
 \r
 const int LibvlcAudioNPObject::propertyCount = sizeof(LibvlcAudioNPObject::propertyNames)/sizeof(NPUTF8 *);\r
 \r
 enum LibvlcAudioNPObjectPropertyIds\r
 {\r
-    ID_mute,\r
-    ID_volume,\r
+    ID_audio_mute,\r
+    ID_audio_volume,\r
+    ID_audio_track,\r
+    ID_audio_channel,\r
 };\r
 \r
 RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVariant &result)\r
@@ -126,11 +199,20 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVari
         libvlc_exception_t ex;\r
         libvlc_exception_init(&ex);\r
 \r
+        libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
+        if( libvlc_exception_raised(&ex) )\r
+        {\r
+            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+            libvlc_exception_clear(&ex);\r
+            return INVOKERESULT_GENERIC_ERROR;\r
+        }\r
+\r
         switch( index )\r
         {\r
-            case ID_mute:\r
+            case ID_audio_mute:\r
             {\r
                 vlc_bool_t muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);\r
+                libvlc_input_free(p_input);\r
                 if( libvlc_exception_raised(&ex) )\r
                 {\r
                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
@@ -140,9 +222,10 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVari
                 BOOLEAN_TO_NPVARIANT(muted, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_volume:\r
+            case ID_audio_volume:\r
             {\r
                 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);\r
+                libvlc_input_free(p_input);\r
                 if( libvlc_exception_raised(&ex) )\r
                 {\r
                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
@@ -152,7 +235,36 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVari
                 INT32_TO_NPVARIANT(volume, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
+            case ID_audio_track:\r
+            {\r
+                int track = libvlc_audio_get_track(p_input, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                INT32_TO_NPVARIANT(track, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_audio_channel:\r
+            {\r
+                int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                INT32_TO_NPVARIANT(channel, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
         }\r
+        libvlc_input_free(p_input);\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
 }\r
@@ -165,13 +277,22 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const
         libvlc_exception_t ex;\r
         libvlc_exception_init(&ex);\r
 \r
+        libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
+        if( libvlc_exception_raised(&ex) )\r
+        {\r
+            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+            libvlc_exception_clear(&ex);\r
+            return INVOKERESULT_GENERIC_ERROR;\r
+        }\r
+\r
         switch( index )\r
         {\r
-            case ID_mute:\r
+            case ID_audio_mute:\r
                 if( NPVARIANT_IS_BOOLEAN(value) )\r
                 {\r
                     libvlc_audio_set_mute(p_plugin->getVLC(),\r
                                           NPVARIANT_TO_BOOLEAN(value), &ex);\r
+                    libvlc_input_free(p_input);\r
                     if( libvlc_exception_raised(&ex) )\r
                     {\r
                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
@@ -181,7 +302,8 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const
                     return INVOKERESULT_NO_ERROR;\r
                 }\r
                 return INVOKERESULT_INVALID_VALUE;\r
-            case ID_volume:\r
+            case ID_audio_volume:\r
+                libvlc_input_free(p_input);\r
                 if( isNumberValue(value) )\r
                 {\r
                     libvlc_audio_set_volume(p_plugin->getVLC(),\r
@@ -195,21 +317,55 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const
                     return INVOKERESULT_NO_ERROR;\r
                 }\r
                 return INVOKERESULT_INVALID_VALUE;\r
+            case ID_audio_track:\r
+                if( isNumberValue(value) )\r
+                {\r
+                    libvlc_audio_set_track(p_input,\r
+                                           numberValue(value), &ex);\r
+                    libvlc_input_free(p_input);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                    return INVOKERESULT_NO_ERROR;\r
+                }\r
+                libvlc_input_free(p_input);\r
+                return INVOKERESULT_INVALID_VALUE;\r
+            case ID_audio_channel:\r
+                libvlc_input_free(p_input);\r
+                if( isNumberValue(value) )\r
+                {\r
+                    libvlc_audio_set_channel(p_plugin->getVLC(),\r
+                                             numberValue(value), &ex);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                    return INVOKERESULT_NO_ERROR;\r
+                }\r
+                return INVOKERESULT_INVALID_VALUE;\r
+            default:\r
+                ;\r
         }\r
+        libvlc_input_free(p_input);\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
 }\r
 \r
 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =\r
 {\r
-    "togglemute",\r
+    "toggleMute",\r
 };\r
 \r
 const int LibvlcAudioNPObject::methodCount = sizeof(LibvlcAudioNPObject::methodNames)/sizeof(NPUTF8 *);\r
 \r
 enum LibvlcAudioNPObjectMethodIds\r
 {\r
-    ID_togglemute,\r
+    ID_audio_togglemute,\r
 };\r
 \r
 RuntimeNPObject::InvokeResult LibvlcAudioNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
@@ -222,7 +378,7 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::invoke(int index, const NPVar
 \r
         switch( index )\r
         {\r
-            case ID_togglemute:\r
+            case ID_audio_togglemute:\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);\r
@@ -240,7 +396,7 @@ RuntimeNPObject::InvokeResult LibvlcAudioNPObject::invoke(int index, const NPVar
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
             default:\r
-                return INVOKERESULT_NO_SUCH_METHOD;\r
+                ;\r
         }\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
@@ -255,19 +411,23 @@ const NPUTF8 * const LibvlcInputNPObject::propertyNames[] =
     "length",\r
     "position",\r
     "time",\r
+    "state",\r
+    "rate",\r
     "fps",\r
-    "hasvout",\r
+    "hasVout",\r
 };\r
 \r
 const int LibvlcInputNPObject::propertyCount = sizeof(LibvlcInputNPObject::propertyNames)/sizeof(NPUTF8 *);\r
 \r
 enum LibvlcInputNPObjectPropertyIds\r
 {\r
-    ID_length,\r
-    ID_position,\r
-    ID_time,\r
-    ID_fps,\r
-    ID_hasvout,\r
+    ID_input_length,\r
+    ID_input_position,\r
+    ID_input_time,\r
+    ID_input_state,\r
+    ID_input_rate,\r
+    ID_input_fps,\r
+    ID_input_hasvout,\r
 };\r
 \r
 RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVariant &result)\r
@@ -281,14 +441,23 @@ RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVari
         libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
         if( libvlc_exception_raised(&ex) )\r
         {\r
-            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
-            libvlc_exception_clear(&ex);\r
-            return INVOKERESULT_GENERIC_ERROR;\r
+            if( index != ID_input_state )\r
+            {\r
+                NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                libvlc_exception_clear(&ex);\r
+                return INVOKERESULT_GENERIC_ERROR;\r
+            }\r
+            else\r
+            {\r
+                /* for input state, return CLOSED rather than an exception */\r
+                INT32_TO_NPVARIANT(0, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
         }\r
 \r
         switch( index )\r
         {\r
-            case ID_length:\r
+            case ID_input_length:\r
             {\r
                 double val = (double)libvlc_input_get_length(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -301,7 +470,7 @@ RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVari
                 DOUBLE_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_position:\r
+            case ID_input_position:\r
             {\r
                 double val = libvlc_input_get_position(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -314,7 +483,7 @@ RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVari
                 DOUBLE_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_time:\r
+            case ID_input_time:\r
             {\r
                 double val = (double)libvlc_input_get_time(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -327,7 +496,33 @@ RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVari
                 DOUBLE_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_fps:\r
+            case ID_input_state:\r
+            {\r
+                int val = libvlc_input_get_state(p_input, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                INT32_TO_NPVARIANT(val, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_input_rate:\r
+            {\r
+                float val = libvlc_input_get_rate(p_input, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                DOUBLE_TO_NPVARIANT(val, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_input_fps:\r
             {\r
                 double val = libvlc_input_get_fps(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -340,7 +535,7 @@ RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVari
                 DOUBLE_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_hasvout:\r
+            case ID_input_hasvout:\r
             {\r
                 vlc_bool_t val = libvlc_input_has_vout(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -350,16 +545,641 @@ RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVari
                     libvlc_exception_clear(&ex);\r
                     return INVOKERESULT_GENERIC_ERROR;\r
                 }\r
-                BOOLEAN_TO_NPVARIANT(val, result);\r
-                return INVOKERESULT_NO_ERROR;\r
-            }\r
+                BOOLEAN_TO_NPVARIANT(val, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
+        }\r
+        libvlc_input_free(p_input);\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
+RuntimeNPObject::InvokeResult LibvlcInputNPObject::setProperty(int index, const NPVariant &value)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_exception_t ex;\r
+        libvlc_exception_init(&ex);\r
+\r
+        libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
+        if( libvlc_exception_raised(&ex) )\r
+        {\r
+            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+            libvlc_exception_clear(&ex);\r
+            return INVOKERESULT_GENERIC_ERROR;\r
+        }\r
+\r
+        switch( index )\r
+        {\r
+            case ID_input_position:\r
+            {\r
+                if( ! NPVARIANT_IS_DOUBLE(value) )\r
+                {\r
+                    libvlc_input_free(p_input);\r
+                    return INVOKERESULT_INVALID_VALUE;\r
+                }\r
+\r
+                float val = (float)NPVARIANT_TO_DOUBLE(value);\r
+                libvlc_input_set_position(p_input, val, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_input_time:\r
+            {\r
+                vlc_int64_t val;\r
+                if( NPVARIANT_IS_INT32(value) )\r
+                    val = (vlc_int64_t)NPVARIANT_TO_INT32(value);\r
+                else if( NPVARIANT_IS_DOUBLE(value) )\r
+                    val = (vlc_int64_t)NPVARIANT_TO_DOUBLE(value);\r
+                else\r
+                {\r
+                    libvlc_input_free(p_input);\r
+                    return INVOKERESULT_INVALID_VALUE;\r
+                }\r
+\r
+                libvlc_input_set_time(p_input, val, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_input_rate:\r
+            {\r
+                float val;\r
+                if( NPVARIANT_IS_INT32(value) )\r
+                    val = (float)NPVARIANT_TO_INT32(value);\r
+                else if( NPVARIANT_IS_DOUBLE(value) )\r
+                    val = (float)NPVARIANT_TO_DOUBLE(value);\r
+                else\r
+                {\r
+                    libvlc_input_free(p_input);\r
+                    return INVOKERESULT_INVALID_VALUE;\r
+                }\r
+\r
+                libvlc_input_set_rate(p_input, val, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
+        }\r
+        libvlc_input_free(p_input);\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
+const NPUTF8 * const LibvlcInputNPObject::methodNames[] =\r
+{\r
+    /* no methods */\r
+};\r
+\r
+const int LibvlcInputNPObject::methodCount = sizeof(LibvlcInputNPObject::methodNames)/sizeof(NPUTF8 *);\r
+\r
+/*\r
+** implementation of libvlc message object\r
+*/\r
+\r
+const NPUTF8 * const LibvlcMessageNPObject::propertyNames[] = \r
+{\r
+    "severity",\r
+    "type",\r
+    "name",\r
+    "header",\r
+    "message",\r
+};\r
+\r
+const int LibvlcMessageNPObject::propertyCount = sizeof(LibvlcMessageNPObject::propertyNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcMessageNPObjectPropertyIds\r
+{\r
+    ID_message_severity,\r
+    ID_message_type,\r
+    ID_message_name,\r
+    ID_message_header,\r
+    ID_message_message,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcMessageNPObject::getProperty(int index, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        switch( index )\r
+        {\r
+            case ID_message_severity:\r
+            {\r
+                INT32_TO_NPVARIANT(_msg.i_severity, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_message_type:\r
+            {\r
+                if( _msg.psz_type )\r
+                {\r
+                    int len = strlen(_msg.psz_type);\r
+                    NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
+                    if( retval )\r
+                    {\r
+                        memcpy(retval, _msg.psz_type, len);\r
+                        STRINGN_TO_NPVARIANT(retval, len, result);\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    NULL_TO_NPVARIANT(result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_message_name:\r
+            {\r
+                if( _msg.psz_name )\r
+                {\r
+                    int len = strlen(_msg.psz_name);\r
+                    NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
+                    if( retval )\r
+                    {\r
+                        memcpy(retval, _msg.psz_name, len);\r
+                        STRINGN_TO_NPVARIANT(retval, len, result);\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    NULL_TO_NPVARIANT(result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_message_header:\r
+            {\r
+                if( _msg.psz_header )\r
+                {\r
+                    int len = strlen(_msg.psz_header);\r
+                    NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
+                    if( retval )\r
+                    {\r
+                        memcpy(retval, _msg.psz_header, len);\r
+                        STRINGN_TO_NPVARIANT(retval, len, result);\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    NULL_TO_NPVARIANT(result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_message_message:\r
+            {\r
+                if( _msg.psz_message )\r
+                {\r
+                    int len = strlen(_msg.psz_message);\r
+                    NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
+                    if( retval )\r
+                    {\r
+                        memcpy(retval, _msg.psz_message, len);\r
+                        STRINGN_TO_NPVARIANT(retval, len, result);\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    NULL_TO_NPVARIANT(result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
+const NPUTF8 * const LibvlcMessageNPObject::methodNames[] =\r
+{\r
+    /* no methods */\r
+};\r
+\r
+const int LibvlcMessageNPObject::methodCount = sizeof(LibvlcMessageNPObject::methodNames)/sizeof(NPUTF8 *);\r
+\r
+/*\r
+** implementation of libvlc message iterator object\r
+*/\r
+\r
+LibvlcMessageIteratorNPObject::LibvlcMessageIteratorNPObject(NPP instance, const NPClass *aClass) :\r
+    RuntimeNPObject(instance, aClass),\r
+    _p_iter(NULL)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_log_t *p_log = p_plugin->getLog();\r
+        if( p_log )\r
+        {\r
+            _p_iter = libvlc_log_get_iterator(p_log, NULL);\r
+        }\r
+    }\r
+};\r
+\r
+LibvlcMessageIteratorNPObject::~LibvlcMessageIteratorNPObject()\r
+{\r
+    if( _p_iter )\r
+        libvlc_log_iterator_free(_p_iter, NULL);\r
+}\r
+\r
+const NPUTF8 * const LibvlcMessageIteratorNPObject::propertyNames[] = \r
+{\r
+    "hasNext",\r
+};\r
+\r
+const int LibvlcMessageIteratorNPObject::propertyCount = sizeof(LibvlcMessageIteratorNPObject::propertyNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcMessageIteratorNPObjectPropertyIds\r
+{\r
+    ID_messageiterator_hasNext,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcMessageIteratorNPObject::getProperty(int index, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        switch( index )\r
+        {\r
+            case ID_messageiterator_hasNext:\r
+            {\r
+                if( _p_iter && p_plugin->getLog() )\r
+                {\r
+                    libvlc_exception_t ex;\r
+                    libvlc_exception_init(&ex);\r
+\r
+                    BOOLEAN_TO_NPVARIANT(libvlc_log_iterator_has_next(_p_iter, &ex), result);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    BOOLEAN_TO_NPVARIANT(0, result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
+const NPUTF8 * const LibvlcMessageIteratorNPObject::methodNames[] =\r
+{\r
+    "next",\r
+};\r
+\r
+const int LibvlcMessageIteratorNPObject::methodCount = sizeof(LibvlcMessageIteratorNPObject::methodNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcMessageIteratorNPObjectMethodIds\r
+{\r
+    ID_messageiterator_next,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcMessageIteratorNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_exception_t ex;\r
+        libvlc_exception_init(&ex);\r
+\r
+        switch( index )\r
+        {\r
+            case ID_messageiterator_next:\r
+                if( argCount == 0 )\r
+                {\r
+                    if( _p_iter && p_plugin->getLog() )\r
+                    {\r
+                        struct libvlc_log_message_t buffer;\r
+\r
+                        buffer.sizeof_msg = sizeof(buffer);\r
+\r
+                        libvlc_log_iterator_next(_p_iter, &buffer, &ex);\r
+                        if( libvlc_exception_raised(&ex) )\r
+                        {\r
+                            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                            libvlc_exception_clear(&ex);\r
+                            return INVOKERESULT_GENERIC_ERROR;\r
+                        }\r
+                        else\r
+                        {\r
+                            LibvlcMessageNPObject* message =\r
+                                static_cast<LibvlcMessageNPObject*>(NPN_CreateObject(_instance, RuntimeNPClass<LibvlcMessageNPObject>::getClass()));\r
+                            if( message )\r
+                            {\r
+                                message->setMessage(buffer);\r
+                                OBJECT_TO_NPVARIANT(message, result);\r
+                                return INVOKERESULT_NO_ERROR;\r
+                            }\r
+                            return INVOKERESULT_OUT_OF_MEMORY;\r
+                        }\r
+                    }\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_SUCH_METHOD;\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
\r
+/*\r
+** implementation of libvlc message object\r
+*/\r
+\r
+const NPUTF8 * const LibvlcMessagesNPObject::propertyNames[] = \r
+{\r
+    "count",\r
+};\r
+\r
+const int LibvlcMessagesNPObject::propertyCount = sizeof(LibvlcMessagesNPObject::propertyNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcMessagesNPObjectPropertyIds\r
+{\r
+    ID_messages_count,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcMessagesNPObject::getProperty(int index, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        switch( index )\r
+        {\r
+            case ID_messages_count:\r
+            {\r
+                libvlc_log_t *p_log = p_plugin->getLog();\r
+                if( p_log )\r
+                {\r
+                    libvlc_exception_t ex;\r
+                    libvlc_exception_init(&ex);\r
+\r
+                    INT32_TO_NPVARIANT(libvlc_log_count(p_log, &ex), result);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    INT32_TO_NPVARIANT(0, result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
+const NPUTF8 * const LibvlcMessagesNPObject::methodNames[] =\r
+{\r
+    "clear",\r
+    "iterator",\r
+};\r
+\r
+const int LibvlcMessagesNPObject::methodCount = sizeof(LibvlcMessagesNPObject::methodNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcMessagesNPObjectMethodIds\r
+{\r
+    ID_messages_clear,\r
+    ID_messages_iterator,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcMessagesNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_exception_t ex;\r
+        libvlc_exception_init(&ex);\r
+\r
+        switch( index )\r
+        {\r
+            case ID_messages_clear:\r
+                if( argCount == 0 )\r
+                {\r
+                    libvlc_log_t *p_log = p_plugin->getLog();\r
+                    if( p_log )\r
+                    {\r
+                        libvlc_log_clear(p_log, &ex);\r
+                        if( libvlc_exception_raised(&ex) )\r
+                        {\r
+                            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                            libvlc_exception_clear(&ex);\r
+                            return INVOKERESULT_GENERIC_ERROR;\r
+                        }\r
+                    }\r
+                    return INVOKERESULT_NO_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_SUCH_METHOD;\r
+\r
+            case ID_messages_iterator:\r
+                if( argCount == 0 )\r
+                {\r
+                    LibvlcMessageIteratorNPObject* iter =\r
+                        static_cast<LibvlcMessageIteratorNPObject*>(NPN_CreateObject(_instance, RuntimeNPClass<LibvlcMessageIteratorNPObject>::getClass()));\r
+                    if( iter )\r
+                    {\r
+                        OBJECT_TO_NPVARIANT(iter, result);\r
+                        return INVOKERESULT_NO_ERROR;\r
+                    }\r
+                    return INVOKERESULT_OUT_OF_MEMORY;\r
+                }\r
+                return INVOKERESULT_NO_SUCH_METHOD;\r
+\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
\r
+/*\r
+** implementation of libvlc message object\r
+*/\r
+\r
+\r
+LibvlcLogNPObject::LibvlcLogNPObject(NPP instance, const NPClass *aClass) :\r
+    RuntimeNPObject(instance, aClass)\r
+{\r
+    _p_vlcmessages = static_cast<LibvlcMessagesNPObject*>(NPN_CreateObject(instance, RuntimeNPClass<LibvlcMessagesNPObject>::getClass()));\r
+};\r
+    \r
+LibvlcLogNPObject::~LibvlcLogNPObject()\r
+{\r
+    NPN_ReleaseObject(_p_vlcmessages);\r
+};\r
+\r
+const NPUTF8 * const LibvlcLogNPObject::propertyNames[] = \r
+{\r
+    "messages",\r
+    "verbosity",\r
+};\r
+\r
+const int LibvlcLogNPObject::propertyCount = sizeof(LibvlcLogNPObject::propertyNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcLogNPObjectPropertyIds\r
+{\r
+    ID_log_messages,\r
+    ID_log_verbosity,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcLogNPObject::getProperty(int index, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_exception_t ex;\r
+        libvlc_exception_init(&ex);\r
+\r
+        switch( index )\r
+        {\r
+            case ID_log_messages:\r
+            {\r
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(_p_vlcmessages), result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_log_verbosity:\r
+            {\r
+                if( p_plugin->getLog() )\r
+                {\r
+                    INT32_TO_NPVARIANT(libvlc_get_log_verbosity(p_plugin->getVLC(),\r
+                                                                    &ex), result);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    /* log is not enabled, return -1 */\r
+                    DOUBLE_TO_NPVARIANT(-1.0, result);\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
+\r
+RuntimeNPObject::InvokeResult LibvlcLogNPObject::setProperty(int index, const NPVariant &value)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_exception_t ex;\r
+        libvlc_exception_init(&ex);\r
+\r
+        switch( index )\r
+        {\r
+            case ID_log_verbosity:\r
+                if( isNumberValue(value) )\r
+                {\r
+                    libvlc_instance_t* p_libvlc = p_plugin->getVLC();\r
+                    libvlc_log_t *p_log = p_plugin->getLog();\r
+                    int verbosity = numberValue(value);\r
+                    if( verbosity >= 0 )\r
+                    {\r
+                        if( ! p_log )\r
+                        {\r
+                            p_log = libvlc_log_open(p_libvlc, &ex);\r
+                            if( libvlc_exception_raised(&ex) )\r
+                            {\r
+                                NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                                libvlc_exception_clear(&ex);\r
+                                return INVOKERESULT_GENERIC_ERROR;\r
+                            }\r
+                            p_plugin->setLog(p_log);\r
+                        }\r
+                        libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity, &ex);\r
+                        if( libvlc_exception_raised(&ex) )\r
+                        {\r
+                            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                            libvlc_exception_clear(&ex);\r
+                            return INVOKERESULT_GENERIC_ERROR;\r
+                        }\r
+                    }\r
+                    else if( p_log )\r
+                    {\r
+                        /* close log  when verbosity is set to -1 */\r
+                        p_plugin->setLog(NULL);\r
+                        libvlc_log_close(p_log, &ex);\r
+                        if( libvlc_exception_raised(&ex) )\r
+                        {\r
+                            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                            libvlc_exception_clear(&ex);\r
+                            return INVOKERESULT_GENERIC_ERROR;\r
+                        }\r
+                    }\r
+                    return INVOKERESULT_NO_ERROR;\r
+                }\r
+                return INVOKERESULT_INVALID_VALUE;\r
+            default:\r
+                ;\r
         }\r
-        libvlc_input_free(p_input);\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
 }\r
 \r
-RuntimeNPObject::InvokeResult LibvlcInputNPObject::setProperty(int index, const NPVariant &value)\r
+const NPUTF8 * const LibvlcLogNPObject::methodNames[] =\r
+{\r
+    /* no methods */\r
+};\r
+\r
+const int LibvlcLogNPObject::methodCount = sizeof(LibvlcLogNPObject::methodNames)/sizeof(NPUTF8 *);\r
+\r
+/*\r
+** implementation of libvlc playlist items object\r
+*/\r
+\r
+const NPUTF8 * const LibvlcPlaylistItemsNPObject::propertyNames[] = \r
+{\r
+    "count",\r
+};\r
+\r
+const int LibvlcPlaylistItemsNPObject::propertyCount = sizeof(LibvlcPlaylistItemsNPObject::propertyNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcPlaylistItemsNPObjectPropertyIds\r
+{\r
+    ID_playlistitems_count,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcPlaylistItemsNPObject::getProperty(int index, NPVariant &result)\r
 {\r
     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
     if( p_plugin )\r
@@ -367,88 +1187,122 @@ RuntimeNPObject::InvokeResult LibvlcInputNPObject::setProperty(int index, const
         libvlc_exception_t ex;\r
         libvlc_exception_init(&ex);\r
 \r
-        libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
-        if( libvlc_exception_raised(&ex) )\r
-        {\r
-            NPN_SetException(this, libvlc_exception_get_message(&ex));\r
-            libvlc_exception_clear(&ex);\r
-            return INVOKERESULT_GENERIC_ERROR;\r
-        }\r
-\r
         switch( index )\r
         {\r
-            case ID_position:\r
-            {\r
-                if( ! NPVARIANT_IS_DOUBLE(value) )\r
-                {\r
-                    libvlc_input_free(p_input);\r
-                    return INVOKERESULT_INVALID_VALUE;\r
-                }\r
-\r
-                float val = (float)NPVARIANT_TO_DOUBLE(value);\r
-                libvlc_input_set_position(p_input, val, &ex);\r
-                libvlc_input_free(p_input);\r
-                if( libvlc_exception_raised(&ex) )\r
-                {\r
-                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
-                    libvlc_exception_clear(&ex);\r
-                    return INVOKERESULT_GENERIC_ERROR;\r
-                }\r
-                return INVOKERESULT_NO_ERROR;\r
-            }\r
-            case ID_time:\r
+            case ID_playlistitems_count:\r
             {\r
-                vlc_int64_t val;\r
-                if( NPVARIANT_IS_INT32(value) )\r
-                    val = (vlc_int64_t)NPVARIANT_TO_INT32(value);\r
-                else if( NPVARIANT_IS_DOUBLE(value) )\r
-                    val = (vlc_int64_t)NPVARIANT_TO_DOUBLE(value);\r
-                else\r
-                {\r
-                    libvlc_input_free(p_input);\r
-                    return INVOKERESULT_INVALID_VALUE;\r
-                }\r
-\r
-                libvlc_input_set_time(p_input, val, &ex);\r
-                libvlc_input_free(p_input);\r
+                int val = libvlc_playlist_items_count(p_plugin->getVLC(), &ex);\r
                 if( libvlc_exception_raised(&ex) )\r
                 {\r
                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
                     libvlc_exception_clear(&ex);\r
                     return INVOKERESULT_GENERIC_ERROR;\r
                 }\r
+                INT32_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
+            default:\r
+                ;\r
         }\r
-        libvlc_input_free(p_input);\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
 }\r
 \r
-const NPUTF8 * const LibvlcInputNPObject::methodNames[] =\r
+const NPUTF8 * const LibvlcPlaylistItemsNPObject::methodNames[] =\r
 {\r
-    /* no methods */\r
+    "clear",\r
+    "remove",\r
 };\r
 \r
-const int LibvlcInputNPObject::methodCount = sizeof(LibvlcInputNPObject::methodNames)/sizeof(NPUTF8 *);\r
+const int LibvlcPlaylistItemsNPObject::methodCount = sizeof(LibvlcPlaylistItemsNPObject::methodNames)/sizeof(NPUTF8 *);\r
+\r
+enum LibvlcPlaylistItemsNPObjectMethodIds\r
+{\r
+    ID_playlistitems_clear,\r
+    ID_playlistitems_remove,\r
+};\r
+\r
+RuntimeNPObject::InvokeResult LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
+{\r
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
+    if( p_plugin )\r
+    {\r
+        libvlc_exception_t ex;\r
+        libvlc_exception_init(&ex);\r
+\r
+        switch( index )\r
+        {\r
+            case ID_playlistitems_clear:\r
+                if( argCount == 0 )\r
+                {\r
+                    libvlc_playlist_clear(p_plugin->getVLC(), &ex);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                    else\r
+                    {\r
+                        VOID_TO_NPVARIANT(result);\r
+                        return INVOKERESULT_NO_ERROR;\r
+                    }\r
+                }\r
+                return INVOKERESULT_NO_SUCH_METHOD;\r
+            case ID_playlistitems_remove:\r
+                if( (argCount == 1) && isNumberValue(args[0]) )\r
+                {\r
+                    libvlc_playlist_delete_item(p_plugin->getVLC(), numberValue(args[0]), &ex);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                    else\r
+                    {\r
+                        VOID_TO_NPVARIANT(result);\r
+                        return INVOKERESULT_NO_ERROR;\r
+                    }\r
+                }\r
+                return INVOKERESULT_NO_SUCH_METHOD;\r
+            default:\r
+                ;\r
+        }\r
+    }\r
+    return INVOKERESULT_GENERIC_ERROR;\r
+}\r
 \r
 /*\r
 ** implementation of libvlc playlist object\r
 */\r
 \r
 \r
+LibvlcPlaylistNPObject::LibvlcPlaylistNPObject(NPP instance, const NPClass *aClass) :\r
+    RuntimeNPObject(instance, aClass)\r
+{\r
+    _p_vlcplaylistitems = static_cast<LibvlcPlaylistItemsNPObject*>(NPN_CreateObject(instance, RuntimeNPClass<LibvlcPlaylistItemsNPObject>::getClass()));\r
+};\r
+    \r
+LibvlcPlaylistNPObject::~LibvlcPlaylistNPObject()\r
+{\r
+    NPN_ReleaseObject(_p_vlcplaylistitems);\r
+};\r
+\r
 const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] = \r
 {\r
-    "itemscount",\r
-    "isplaying",\r
+    "itemCount", /* deprecated */\r
+    "isPlaying",\r
+    "items",\r
 };\r
 \r
 const int LibvlcPlaylistNPObject::propertyCount = sizeof(LibvlcPlaylistNPObject::propertyNames)/sizeof(NPUTF8 *);\r
 \r
 enum LibvlcPlaylistNPObjectPropertyIds\r
 {\r
-    ID_itemscount,\r
-    ID_isplaying,\r
+    ID_playlist_itemcount,\r
+    ID_playlist_isplaying,\r
+    ID_playlist_items,\r
 };\r
 \r
 RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)\r
@@ -461,7 +1315,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::getProperty(int index, NPV
 \r
         switch( index )\r
         {\r
-            case ID_itemscount:\r
+            case ID_playlist_itemcount: /* deprecated */\r
             {\r
                 int val = libvlc_playlist_items_count(p_plugin->getVLC(), &ex);\r
                 if( libvlc_exception_raised(&ex) )\r
@@ -473,7 +1327,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::getProperty(int index, NPV
                 INT32_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_isplaying:\r
+            case ID_playlist_isplaying:\r
             {\r
                 int val = libvlc_playlist_isplaying(p_plugin->getVLC(), &ex);\r
                 if( libvlc_exception_raised(&ex) )\r
@@ -485,6 +1339,13 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::getProperty(int index, NPV
                 BOOLEAN_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
+            case ID_playlist_items:\r
+            {\r
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(_p_vlcplaylistitems), result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            default:\r
+                ;\r
         }\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
@@ -494,26 +1355,28 @@ const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =
 {\r
     "add",\r
     "play",\r
-    "togglepause"\r
+    "playItem",\r
+    "togglePause",\r
     "stop",\r
     "next",\r
     "prev",\r
-    "clear",\r
-    "deleteitem"\r
+    "clear", /* deprecated */\r
+    "removeItem", /* deprecated */\r
 };\r
 \r
 const int LibvlcPlaylistNPObject::methodCount = sizeof(LibvlcPlaylistNPObject::methodNames)/sizeof(NPUTF8 *);\r
 \r
 enum LibvlcPlaylistNPObjectMethodIds\r
 {\r
-    ID_add,\r
-    ID_play,\r
-    ID_togglepause,\r
-    ID_stop,\r
-    ID_next,\r
-    ID_prev,\r
-    ID_clear,\r
-    ID_deleteitem,\r
+    ID_playlist_add,\r
+    ID_playlist_play,\r
+    ID_playlist_playItem,\r
+    ID_playlist_togglepause,\r
+    ID_playlist_stop,\r
+    ID_playlist_next,\r
+    ID_playlist_prev,\r
+    ID_playlist_clear,\r
+    ID_playlist_removeitem\r
 };\r
 \r
 RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
@@ -526,7 +1389,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
 \r
         switch( index )\r
         {\r
-            case ID_add:\r
+            case ID_playlist_add:\r
             {\r
                 if( (argCount < 1) || (argCount > 3) )\r
                     return INVOKERESULT_NO_SUCH_METHOD;\r
@@ -540,10 +1403,11 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     if( s )\r
                     {\r
                         url = p_plugin->getAbsoluteURL(s);\r
-                        delete s;\r
-                        if( ! url )\r
-                            // what happened ?\r
-                            return INVOKERESULT_GENERIC_ERROR;\r
+                        if( url )\r
+                            delete s;\r
+                        else\r
+                            // problem with combining url, use argument\r
+                            url = s;\r
                     }\r
                     else\r
                         return INVOKERESULT_OUT_OF_MEMORY;\r
@@ -616,7 +1480,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     return INVOKERESULT_NO_ERROR;\r
                 }\r
             }\r
-            case ID_play:\r
+            case ID_playlist_play:\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_playlist_play(p_plugin->getVLC(), -1, 0, NULL, &ex);\r
@@ -633,7 +1497,24 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     }\r
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
-            case ID_togglepause:\r
+            case ID_playlist_playItem:\r
+                if( (argCount == 1) && isNumberValue(args[0]) )\r
+                {\r
+                    libvlc_playlist_play(p_plugin->getVLC(), numberValue(args[0]), 0, NULL, &ex);\r
+                    if( libvlc_exception_raised(&ex) )\r
+                    {\r
+                        NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                        libvlc_exception_clear(&ex);\r
+                        return INVOKERESULT_GENERIC_ERROR;\r
+                    }\r
+                    else\r
+                    {\r
+                        VOID_TO_NPVARIANT(result);\r
+                        return INVOKERESULT_NO_ERROR;\r
+                    }\r
+                }\r
+                return INVOKERESULT_NO_SUCH_METHOD;\r
+            case ID_playlist_togglepause:\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_playlist_pause(p_plugin->getVLC(), &ex);\r
@@ -650,7 +1531,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     }\r
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
-            case ID_stop:\r
+            case ID_playlist_stop:\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_playlist_stop(p_plugin->getVLC(), &ex);\r
@@ -667,7 +1548,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     }\r
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
-            case ID_next:\r
+            case ID_playlist_next:\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_playlist_next(p_plugin->getVLC(), &ex);\r
@@ -684,7 +1565,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     }\r
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
-            case ID_prev:\r
+            case ID_playlist_prev:\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_playlist_prev(p_plugin->getVLC(), &ex);\r
@@ -701,7 +1582,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     }\r
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
-            case ID_clear:\r
+            case ID_playlist_clear: /* deprecated */\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_playlist_clear(p_plugin->getVLC(), &ex);\r
@@ -718,7 +1599,7 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                     }\r
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
-            case ID_deleteitem:\r
+            case ID_playlist_removeitem: /* deprecated */\r
                 if( (argCount == 1) && isNumberValue(args[0]) )\r
                 {\r
                     libvlc_playlist_delete_item(p_plugin->getVLC(), numberValue(args[0]), &ex);\r
@@ -736,12 +1617,12 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
                 }\r
                 return INVOKERESULT_NO_SUCH_METHOD;\r
             default:\r
-                return INVOKERESULT_NO_SUCH_METHOD;\r
+                ;\r
         }\r
     }\r
     return INVOKERESULT_GENERIC_ERROR;\r
 }\r
\r
+\r
 void LibvlcPlaylistNPObject::parseOptions(const NPString &s, int *i_options, char*** ppsz_options)\r
 {\r
     if( s.utf8length )\r
@@ -811,63 +1692,59 @@ void LibvlcPlaylistNPObject::parseOptions(const NPString &s, int *i_options, cha
 \r
 void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options, char*** ppsz_options)\r
 {\r
+    /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */\r
+\r
+    NPVariant value;\r
+\r
     /* we are expecting to have a Javascript Array object */\r
-    NPIdentifier name = NPN_GetStringIdentifier("length");\r
-    if( NPN_HasProperty(_instance, obj, name) )\r
+    NPIdentifier propId = NPN_GetStringIdentifier("length");\r
+    if( NPN_GetProperty(_instance, obj, propId, &value) )\r
     {\r
-        NPVariant value;\r
-        if( NPN_GetProperty(_instance, obj, name, &value) )\r
-        {\r
-            int count = numberValue(value);\r
-            NPN_ReleaseVariantValue(&value);\r
+        int count = numberValue(value);\r
+        NPN_ReleaseVariantValue(&value);\r
 \r
-            if( count )\r
+        if( count )\r
+        {\r
+            long capacity = 16;\r
+            char **options = (char **)malloc(capacity*sizeof(char *));\r
+            if( options )\r
             {\r
-                long capacity = 16;\r
-                char **options = (char **)malloc(capacity*sizeof(char *));\r
-                if( options )\r
+                int nOptions = 0;\r
+\r
+                while( nOptions < count )\r
                 {\r
-                    int nOptions = 0;\r
+                    propId = NPN_GetIntIdentifier(nOptions);\r
+                    if( ! NPN_GetProperty(_instance, obj, propId, &value) )\r
+                        /* return what we got so far */\r
+                        break;\r
 \r
-                    while( nOptions < count )\r
+                    if( ! NPVARIANT_IS_STRING(value) )\r
                     {\r
-                        name = NPN_GetIntIdentifier(nOptions);\r
-                        if( ! NPN_HasProperty(_instance, obj, name) )\r
-                            /* return what we got so far */\r
-                            break;\r
-\r
-                        if( ! NPN_GetProperty(_instance, obj, name, &value) )\r
-                            /* return what we got so far */\r
-                            break;\r
+                        /* return what we got so far */\r
+                        NPN_ReleaseVariantValue(&value);\r
+                        break;\r
+                    }\r
 \r
-                        if( ! NPVARIANT_IS_STRING(value) )\r
+                    if( nOptions == capacity )\r
+                    {\r
+                        capacity += 16;\r
+                        char **moreOptions = (char **)realloc(options, capacity*sizeof(char*)); \r
+                        if( ! moreOptions )\r
                         {\r
-                            /* return what we got so far */\r
+                            /* failed to allocate more memory */\r
                             NPN_ReleaseVariantValue(&value);\r
+                            /* return what we got so far */\r
+                            *i_options = nOptions;\r
+                            *ppsz_options = options;\r
                             break;\r
                         }\r
-\r
-                        if( nOptions == capacity )\r
-                        {\r
-                            capacity += 16;\r
-                            char **moreOptions = (char **)realloc(options, capacity*sizeof(char*)); \r
-                            if( ! moreOptions )\r
-                            {\r
-                                /* failed to allocate more memory */\r
-                                NPN_ReleaseVariantValue(&value);\r
-                                /* return what we got so far */\r
-                                *i_options = nOptions;\r
-                                *ppsz_options = options;\r
-                                break;\r
-                            }\r
-                            options = moreOptions;\r
-                        }\r
-\r
-                        options[nOptions++] = stringValue(value);\r
+                        options = moreOptions;\r
                     }\r
-                    *i_options = nOptions;\r
-                    *ppsz_options = options;\r
+\r
+                    options[nOptions++] = stringValue(value);\r
                 }\r
+                *i_options = nOptions;\r
+                *ppsz_options = options;\r
             }\r
         }\r
     }\r
@@ -882,13 +1759,17 @@ const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
     "fullscreen",\r
     "height",\r
     "width",\r
+    "aspectRatio",\r
+    "crop"\r
 };\r
 \r
 enum LibvlcVideoNPObjectPropertyIds\r
 {\r
-    ID_fullscreen,\r
-    ID_height,\r
-    ID_width,\r
+    ID_video_fullscreen,\r
+    ID_video_height,\r
+    ID_video_width,\r
+    ID_video_aspectratio,\r
+    ID_video_crop\r
 };\r
 \r
 const int LibvlcVideoNPObject::propertyCount = sizeof(LibvlcVideoNPObject::propertyNames)/sizeof(NPUTF8 *);\r
@@ -911,7 +1792,7 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::getProperty(int index, NPVari
 \r
         switch( index )\r
         {\r
-            case ID_fullscreen:\r
+            case ID_video_fullscreen:\r
             {\r
                 int val = libvlc_get_fullscreen(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -924,7 +1805,7 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::getProperty(int index, NPVari
                 BOOLEAN_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_height:\r
+            case ID_video_height:\r
             {\r
                 int val = libvlc_video_get_height(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -937,7 +1818,7 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::getProperty(int index, NPVari
                 INT32_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
-            case ID_width:\r
+            case ID_video_width:\r
             {\r
                 int val = libvlc_video_get_width(p_input, &ex);\r
                 libvlc_input_free(p_input);\r
@@ -950,6 +1831,38 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::getProperty(int index, NPVari
                 INT32_TO_NPVARIANT(val, result);\r
                 return INVOKERESULT_NO_ERROR;\r
             }\r
+            case ID_video_aspectratio:\r
+            {\r
+                NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_input, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                if( !psz_aspect )\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+\r
+                STRINGZ_TO_NPVARIANT(psz_aspect, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_video_crop:\r
+            {\r
+                NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_input, &ex);\r
+                libvlc_input_free(p_input);\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                if( !psz_geometry )\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+\r
+                STRINGZ_TO_NPVARIANT(psz_geometry, result);\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
         }\r
         libvlc_input_free(p_input);\r
     }\r
@@ -974,7 +1887,7 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::setProperty(int index, const
 \r
         switch( index )\r
         {\r
-            case ID_fullscreen:\r
+            case ID_video_fullscreen:\r
             {\r
                 if( ! NPVARIANT_IS_BOOLEAN(value) )\r
                 {\r
@@ -985,6 +1898,65 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::setProperty(int index, const
                 int val = NPVARIANT_TO_BOOLEAN(value);\r
                 libvlc_set_fullscreen(p_input, val, &ex);\r
                 libvlc_input_free(p_input);\r
+\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_video_aspectratio:\r
+            {\r
+                char *psz_aspect = NULL;\r
+\r
+                if( ! NPVARIANT_IS_STRING(value) )\r
+                {\r
+                    libvlc_input_free(p_input);\r
+                    return INVOKERESULT_INVALID_VALUE;\r
+                }\r
+\r
+                psz_aspect = stringValue(NPVARIANT_TO_STRING(value));\r
+                if( !psz_aspect )\r
+                {\r
+                    libvlc_input_free(p_input);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+\r
+                libvlc_video_set_aspect_ratio(p_input, psz_aspect, &ex);\r
+                free(psz_aspect );\r
+                libvlc_input_free(p_input);\r
+\r
+                if( libvlc_exception_raised(&ex) )\r
+                {\r
+                    NPN_SetException(this, libvlc_exception_get_message(&ex));\r
+                    libvlc_exception_clear(&ex);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+                return INVOKERESULT_NO_ERROR;\r
+            }\r
+            case ID_video_crop:\r
+            {\r
+                char *psz_geometry = NULL;\r
+\r
+                if( ! NPVARIANT_IS_STRING(value) )\r
+                {\r
+                    libvlc_input_free(p_input);\r
+                    return INVOKERESULT_INVALID_VALUE;\r
+                }\r
+\r
+                psz_geometry = stringValue(NPVARIANT_TO_STRING(value));\r
+                if( !psz_geometry )\r
+                {\r
+                    libvlc_input_free(p_input);\r
+                    return INVOKERESULT_GENERIC_ERROR;\r
+                }\r
+\r
+                libvlc_video_set_crop_geometry(p_input, psz_geometry, &ex);\r
+                free(psz_geometry );\r
+                libvlc_input_free(p_input);\r
+\r
                 if( libvlc_exception_raised(&ex) )\r
                 {\r
                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
@@ -1001,12 +1973,12 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::setProperty(int index, const
 \r
 const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =\r
 {\r
-    "togglefullscreen",\r
+    "toggleFullscreen",\r
 };\r
 \r
 enum LibvlcVideoNPObjectMethodIds\r
 {\r
-    ID_togglefullscreen,\r
+    ID_video_togglefullscreen,\r
 };\r
 \r
 const int LibvlcVideoNPObject::methodCount = sizeof(LibvlcVideoNPObject::methodNames)/sizeof(NPUTF8 *);\r
@@ -1029,7 +2001,7 @@ RuntimeNPObject::InvokeResult LibvlcVideoNPObject::invoke(int index, const NPVar
 \r
         switch( index )\r
         {\r
-            case ID_togglefullscreen:\r
+            case ID_video_togglefullscreen:\r
                 if( argCount == 0 )\r
                 {\r
                     libvlc_toggle_fullscreen(p_input, &ex);\r