1 /*****************************************************************************
2 * vlcplugin.cpp: a VLC plugin for Mozilla
3 *****************************************************************************
4 * Copyright (C) 2002-2010 the VideoLAN team
7 * Authors: Samuel Hocevar <sam@zoy.org>
8 * Damien Fouilleul <damienf.fouilleul@laposte.net>
9 * Jean-Paul Saman <jpsaman@videolan.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
31 #include "vlcplugin.h"
33 #include "control/npolibvlc.h"
43 #warning "locking not implemented for this platform"
50 /*****************************************************************************
52 *****************************************************************************/
53 static void plugin_lock_init(plugin_lock_t
*lock
)
58 pthread_mutex_init(&lock
->mutex
, NULL
);
60 InitializeCriticalSection(&lock
->cs
);
62 #warning "locking not implemented in this platform"
66 static void plugin_lock_destroy(plugin_lock_t
*lock
)
71 pthread_mutex_destroy(&lock
->mutex
);
73 DeleteCriticalSection(&lock
->cs
);
75 #warning "locking not implemented in this platform"
79 static void plugin_lock(plugin_lock_t
*lock
)
84 pthread_mutex_lock(&lock
->mutex
);
86 EnterCriticalSection(&lock
->cs
);
88 #warning "locking not implemented in this platform"
92 static void plugin_unlock(plugin_lock_t
*lock
)
97 pthread_mutex_unlock(&lock
->mutex
);
99 LeaveCriticalSection(&lock
->cs
);
101 #warning "locking not implemented in this platform"
105 /*****************************************************************************
107 *****************************************************************************/
108 static void handle_input_event(const libvlc_event_t
* event
, void *param
);
109 static void handle_changed_event(const libvlc_event_t
* event
, void *param
);
111 static vlcplugin_event_t vlcevents
[] = {
112 { "MediaPlayerMediaChanged", libvlc_MediaPlayerMediaChanged
, handle_input_event
},
113 { "MediaPlayerNothingSpecial", libvlc_MediaPlayerNothingSpecial
, handle_input_event
},
114 { "MediaPlayerOpening", libvlc_MediaPlayerOpening
, handle_input_event
},
115 { "MediaPlayerBuffering", libvlc_MediaPlayerBuffering
, handle_changed_event
},
116 { "MediaPlayerPlaying", libvlc_MediaPlayerPlaying
, handle_input_event
},
117 { "MediaPlayerPaused", libvlc_MediaPlayerPaused
, handle_input_event
},
118 { "MediaPlayerStopped", libvlc_MediaPlayerStopped
, handle_input_event
},
119 { "MediaPlayerForward", libvlc_MediaPlayerForward
, handle_input_event
},
120 { "MediaPlayerBackward", libvlc_MediaPlayerBackward
, handle_input_event
},
121 { "MediaPlayerEndReached", libvlc_MediaPlayerEndReached
, handle_input_event
},
122 { "MediaPlayerEncounteredError", libvlc_MediaPlayerEncounteredError
, handle_input_event
},
123 { "MediaPlayerTimeChanged", libvlc_MediaPlayerTimeChanged
, handle_changed_event
},
124 { "MediaPlayerPositionChanged", libvlc_MediaPlayerPositionChanged
, handle_changed_event
},
125 { "MediaPlayerSeekableChanged", libvlc_MediaPlayerSeekableChanged
, handle_changed_event
},
126 { "MediaPlayerPausableChanged", libvlc_MediaPlayerPausableChanged
, handle_changed_event
},
127 { "MediaPlayerTitleChanged", libvlc_MediaPlayerTitleChanged
, handle_changed_event
},
128 { "MediaPlayerLengthChanged", libvlc_MediaPlayerLengthChanged
, handle_changed_event
},
131 static void handle_input_event(const libvlc_event_t
* event
, void *param
)
133 VlcPlugin
*plugin
= (VlcPlugin
*)param
;
134 switch( event
->type
)
136 case libvlc_MediaPlayerNothingSpecial
:
137 case libvlc_MediaPlayerOpening
:
138 case libvlc_MediaPlayerPlaying
:
139 case libvlc_MediaPlayerPaused
:
140 case libvlc_MediaPlayerStopped
:
141 case libvlc_MediaPlayerForward
:
142 case libvlc_MediaPlayerBackward
:
143 case libvlc_MediaPlayerEndReached
:
144 case libvlc_MediaPlayerEncounteredError
:
145 plugin
->event_callback(event
, NULL
, 0, param
);
147 default: /* ignore all other libvlc_event_type_t */
152 static void handle_changed_event(const libvlc_event_t
* event
, void *param
)
154 uint32_t npcount
= 1;
155 NPVariant
*npparam
= (NPVariant
*) NPN_MemAlloc( sizeof(NPVariant
) * npcount
);
157 VlcPlugin
*plugin
= (VlcPlugin
*)param
;
158 switch( event
->type
)
160 case libvlc_MediaPlayerBuffering
:
161 DOUBLE_TO_NPVARIANT(event
->u
.media_player_buffering
.new_cache
, npparam
[0]);
163 case libvlc_MediaPlayerTimeChanged
:
164 DOUBLE_TO_NPVARIANT(event
->u
.media_player_time_changed
.new_time
, npparam
[0]);
166 case libvlc_MediaPlayerPositionChanged
:
167 DOUBLE_TO_NPVARIANT(event
->u
.media_player_position_changed
.new_position
, npparam
[0]);
169 case libvlc_MediaPlayerSeekableChanged
:
170 BOOLEAN_TO_NPVARIANT(event
->u
.media_player_seekable_changed
.new_seekable
, npparam
[0]);
172 case libvlc_MediaPlayerPausableChanged
:
173 BOOLEAN_TO_NPVARIANT(event
->u
.media_player_pausable_changed
.new_pausable
, npparam
[0]);
175 case libvlc_MediaPlayerTitleChanged
:
176 BOOLEAN_TO_NPVARIANT(event
->u
.media_player_title_changed
.new_title
, npparam
[0]);
178 case libvlc_MediaPlayerLengthChanged
:
179 DOUBLE_TO_NPVARIANT(event
->u
.media_player_length_changed
.new_length
, npparam
[0]);
181 default: /* ignore all other libvlc_event_type_t */
182 NPN_MemFree( npparam
);
185 plugin
->event_callback(event
, npparam
, npcount
, param
);
188 bool EventObj::init()
190 plugin_lock_init(&lock
);
194 EventObj::~EventObj()
196 plugin_lock_destroy(&lock
);
199 void EventObj::deliver(NPP browser
)
203 for( ev_l::iterator iter
= _elist
.begin(); iter
!= _elist
.end(); ++iter
)
205 for( lr_l::iterator j
= _llist
.begin(); j
!= _llist
.end(); ++j
)
207 if( j
->event_type() == iter
->event_type() )
210 NPVariant
*params
= iter
->params();
211 uint32_t count
= iter
->count();
213 NPObject
*listener
= j
->listener();
216 NPN_InvokeDefault( browser
, listener
, params
, count
, &result
);
217 NPN_ReleaseVariantValue( &result
);
219 for( uint32_t n
= 0; n
< count
; n
++ )
221 if( NPVARIANT_IS_STRING(params
[n
]) )
222 NPN_MemFree( (void*) NPVARIANT_TO_STRING(params
[n
]).UTF8Characters
);
223 else if( NPVARIANT_IS_OBJECT(params
[n
]) )
225 NPN_ReleaseObject( NPVARIANT_TO_OBJECT(params
[n
]) );
226 NPN_MemFree( (void*)NPVARIANT_TO_OBJECT(params
[n
]) );
229 if (params
) NPN_MemFree( params
);
235 plugin_unlock(&lock
);
238 void EventObj::callback(const libvlc_event_t
* event
,
239 NPVariant
*npparams
, uint32_t count
)
242 _elist
.push_back(VLCEvent(event
->type
, npparams
, count
));
243 plugin_unlock(&lock
);
246 vlcplugin_event_t
*EventObj::find_event(const char *s
) const
248 for( int i
= 0; i
< ARRAY_SIZE(vlcevents
); i
++ )
250 if( strncmp(vlcevents
[i
].name
, s
, strlen(vlcevents
[i
].name
)) == 0 )
251 return &vlcevents
[i
];
256 const char *EventObj::find_name(const libvlc_event_t
*event
)
258 for( int i
= 0; i
< ARRAY_SIZE(vlcevents
); i
++ )
260 if( vlcevents
[i
].libvlc_type
== event
->type
)
261 return vlcevents
[i
].name
;
266 bool EventObj::insert(const NPString
&name
, NPObject
*listener
, bool bubble
)
268 vlcplugin_event_t
*event
= find_event(name
.UTF8Characters
);
273 for( iter
= _llist
.begin(); iter
!= _llist
.end(); ++iter
)
274 if( iter
->listener() == listener
&& iter
->bubble() == bubble
)
277 if( iter
== _llist
.end() )
279 _llist
.push_back(Listener(event
, listener
, bubble
));
286 bool EventObj::remove(const NPString
&name
, NPObject
*listener
, bool bubble
)
288 vlcplugin_event_t
*event
= find_event(name
.UTF8Characters
);
292 for( lr_l::iterator iter
= _llist
.begin(); iter
!=_llist
.end(); iter
++ )
294 if( iter
->event_type() == event
->libvlc_type
&&
295 iter
->listener() == listener
&&
296 iter
->bubble() == bubble
)
298 iter
= _llist
.erase(iter
);
306 void EventObj::hook_manager( libvlc_event_manager_t
*em
, void *userdata
)
312 /* attach all libvlc events we care about */
313 for( int i
= 0; i
< ARRAY_SIZE(vlcevents
); i
++ )
315 libvlc_event_attach( _em
, vlcevents
[i
].libvlc_type
,
316 vlcevents
[i
].libvlc_callback
,
322 void EventObj::unhook_manager( void *userdata
)
326 /* detach all libvlc events we cared about */
327 for( int i
= 0; i
< ARRAY_SIZE(vlcevents
); i
++ )
329 libvlc_event_detach( _em
, vlcevents
[i
].libvlc_type
,
330 vlcevents
[i
].libvlc_callback
,
336 /*****************************************************************************
337 * VlcPlugin constructor and destructor
338 *****************************************************************************/
339 #if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) < 20)
340 VlcPlugin::VlcPlugin( NPP instance
, uint16 mode
) :
342 VlcPlugin::VlcPlugin( NPP instance
, uint16_t mode
) :
351 libvlc_instance(NULL
),
352 libvlc_media_list(NULL
),
353 libvlc_media_player(NULL
),
361 ,i_width((unsigned)-1)
362 ,i_height((unsigned)-1)
371 ,p_btnFullscreen(NULL
)
376 memset(&npwindow
, 0, sizeof(NPWindow
));
378 memset(&npvideo
, 0, sizeof(Window
));
379 memset(&npcontrol
, 0, sizeof(Window
));
383 static bool boolValue(const char *value
) {
384 return ( !strcmp(value
, "1") ||
385 !strcasecmp(value
, "true") ||
386 !strcasecmp(value
, "yes") );
389 void VlcPlugin::eventAsync(void *param
)
391 VlcPlugin
*plugin
= (VlcPlugin
*)param
;
392 plugin
->events
.deliver(plugin
->getBrowser());
395 void VlcPlugin::event_callback(const libvlc_event_t
* event
,
396 NPVariant
*npparams
, uint32_t npcount
, void *userdata
)
398 VlcPlugin
*plugin
= (VlcPlugin
*)userdata
;
400 plugin
->events
.callback(event
, npparams
, npcount
);
401 NPN_PluginThreadAsyncCall(plugin
->getBrowser(), eventAsync
, plugin
);
403 #warning NPN_PluginThreadAsyncCall not implemented yet.
404 printf("No NPN_PluginThreadAsyncCall(), doing nothing.\n");
408 NPError
VlcPlugin::init(int argc
, char* const argn
[], char* const argv
[])
410 /* prepare VLC command line */
411 const char *ppsz_argv
[32];
415 ppsz_argv
[ppsz_argc
++] = "--no-plugins-cache";
418 /* locate VLC module path */
420 ppsz_argv
[ppsz_argc
++] = "--plugin-path=/Library/Internet\\ Plug-Ins/VLC\\ Plugin.plugin/Contents/MacOS/plugins";
421 ppsz_argv
[ppsz_argc
++] = "--vout=minimal_macosx";
422 #elif defined(XP_WIN)
424 DWORD i_type
, i_data
= MAX_PATH
+ 1;
425 char p_data
[MAX_PATH
+ 1];
426 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE
, "Software\\VideoLAN\\VLC",
427 0, KEY_READ
, &h_key
) == ERROR_SUCCESS
)
429 if( RegQueryValueEx( h_key
, "InstallDir", 0, &i_type
,
430 (LPBYTE
)p_data
, &i_data
) == ERROR_SUCCESS
)
432 if( i_type
== REG_SZ
)
434 strcat( p_data
, "\\plugins" );
435 ppsz_argv
[ppsz_argc
++] = "--plugin-path";
436 ppsz_argv
[ppsz_argc
++] = p_data
;
439 RegCloseKey( h_key
);
441 ppsz_argv
[ppsz_argc
++] = "--no-one-instance";
443 #endif /* XP_MACOSX */
445 /* common settings */
446 ppsz_argv
[ppsz_argc
++] = "-vv";
447 ppsz_argv
[ppsz_argc
++] = "--no-stats";
448 ppsz_argv
[ppsz_argc
++] = "--no-media-library";
449 ppsz_argv
[ppsz_argc
++] = "--intf=dummy";
450 ppsz_argv
[ppsz_argc
++] = "--no-video-title-show";
451 ppsz_argv
[ppsz_argc
++] = "--no-xlib";
453 const char *progid
= NULL
;
455 /* parse plugin arguments */
456 for( int i
= 0; (i
< argc
) && (ppsz_argc
< 32); i
++ )
458 /* fprintf(stderr, "argn=%s, argv=%s\n", argn[i], argv[i]); */
460 if( !strcmp( argn
[i
], "target" )
461 || !strcmp( argn
[i
], "mrl")
462 || !strcmp( argn
[i
], "filename")
463 || !strcmp( argn
[i
], "src") )
465 psz_target
= argv
[i
];
467 else if( !strcmp( argn
[i
], "text" ) )
470 psz_text
= strdup( argv
[i
] );
472 else if( !strcmp( argn
[i
], "autoplay")
473 || !strcmp( argn
[i
], "autostart") )
475 b_autoplay
= boolValue(argv
[i
]);
477 else if( !strcmp( argn
[i
], "fullscreen" ) )
479 if( boolValue(argv
[i
]) )
481 ppsz_argv
[ppsz_argc
++] = "--fullscreen";
485 ppsz_argv
[ppsz_argc
++] = "--no-fullscreen";
488 else if( !strcmp( argn
[i
], "mute" ) )
490 if( boolValue(argv
[i
]) )
492 ppsz_argv
[ppsz_argc
++] = "--volume=0";
495 else if( !strcmp( argn
[i
], "loop")
496 || !strcmp( argn
[i
], "autoloop") )
498 if( boolValue(argv
[i
]) )
500 ppsz_argv
[ppsz_argc
++] = "--loop";
504 ppsz_argv
[ppsz_argc
++] = "--no-loop";
507 else if( !strcmp( argn
[i
], "version")
508 || !strcmp( argn
[i
], "progid") )
512 else if( !strcmp( argn
[i
], "toolbar" ) )
514 /* FIXME: Remove this when toolbar functionality has been implemented on
515 * MacOS X and Win32 for Firefox/Mozilla/Safari. */
517 b_toolbar
= boolValue(argv
[i
]);
522 libvlc_instance
= libvlc_new(ppsz_argc
, ppsz_argv
);
523 if( !libvlc_instance
)
524 return NPERR_GENERIC_ERROR
;
525 libvlc_media_list
= libvlc_media_list_new(libvlc_instance
);
528 ** fetch plugin base URL, which is the URL of the page containing the plugin
529 ** this URL is used for making absolute URL from relative URL that may be
530 ** passed as an MRL argument
532 NPObject
*plugin
= NULL
;
534 if( NPERR_NO_ERROR
== NPN_GetValue(p_browser
, NPNVWindowNPObject
, &plugin
) )
537 ** is there a better way to get that info ?
539 static const char docLocHref
[] = "document.location.href";
543 script
.UTF8Characters
= docLocHref
;
544 script
.UTF8Length
= sizeof(docLocHref
)-1;
546 if( NPN_Evaluate(p_browser
, plugin
, &script
, &result
) )
548 if( NPVARIANT_IS_STRING(result
) )
550 NPString
&location
= NPVARIANT_TO_STRING(result
);
552 psz_baseURL
= (char *) malloc(location
.UTF8Length
+1);
555 strncpy(psz_baseURL
, location
.UTF8Characters
, location
.UTF8Length
);
556 psz_baseURL
[location
.UTF8Length
] = '\0';
559 NPN_ReleaseVariantValue(&result
);
561 NPN_ReleaseObject(plugin
);
566 // get absolute URL from src
567 char *psz_absurl
= getAbsoluteURL(psz_target
);
568 psz_target
= psz_absurl
? psz_absurl
: strdup(psz_target
);
571 /* assign plugin script root class */
573 p_scriptClass
= RuntimeNPClass
<LibvlcRootNPObject
>::getClass();
576 return NPERR_GENERIC_ERROR
;
578 return NPERR_NO_ERROR
;
581 VlcPlugin::~VlcPlugin()
587 if( libvlc_media_player
)
589 if( playlist_isplaying() )
591 events
.unhook_manager( this );
592 libvlc_media_player_release( libvlc_media_player
);
594 if( libvlc_media_list
)
595 libvlc_media_list_release( libvlc_media_list
);
596 if( libvlc_instance
)
597 libvlc_release( libvlc_instance
);
600 /*****************************************************************************
601 * VlcPlugin playlist replacement methods
602 *****************************************************************************/
603 void VlcPlugin::set_player_window()
606 libvlc_media_player_set_xwindow(libvlc_media_player
,
607 (uint32_t)getVideoWindow());
610 // XXX FIXME insert appropriate call here
613 libvlc_media_player_set_hwnd(libvlc_media_player
,
618 int VlcPlugin::playlist_add( const char *mrl
)
621 libvlc_media_t
*p_m
= libvlc_media_new_location(libvlc_instance
,mrl
);
624 assert( libvlc_media_list
);
625 libvlc_media_list_lock(libvlc_media_list
);
626 if( !libvlc_media_list_add_media(libvlc_media_list
,p_m
) )
627 item
= libvlc_media_list_count(libvlc_media_list
)-1;
628 libvlc_media_list_unlock(libvlc_media_list
);
630 libvlc_media_release(p_m
);
635 int VlcPlugin::playlist_add_extended_untrusted( const char *mrl
, const char *name
,
636 int optc
, const char **optv
)
641 assert( libvlc_media_list
);
643 p_m
= libvlc_media_new_location(libvlc_instance
, mrl
);
647 for( int i
= 0; i
< optc
; ++i
)
648 libvlc_media_add_option_flag(p_m
, optv
[i
], libvlc_media_option_unique
);
650 libvlc_media_list_lock(libvlc_media_list
);
651 if( !libvlc_media_list_add_media(libvlc_media_list
,p_m
) )
652 item
= libvlc_media_list_count(libvlc_media_list
)-1;
653 libvlc_media_list_unlock(libvlc_media_list
);
654 libvlc_media_release(p_m
);
659 bool VlcPlugin::playlist_select( int idx
)
661 libvlc_media_t
*p_m
= NULL
;
663 assert( libvlc_media_list
);
665 libvlc_media_list_lock(libvlc_media_list
);
667 int count
= libvlc_media_list_count(libvlc_media_list
);
668 if( idx
<0||idx
>=count
)
671 playlist_index
= idx
;
673 p_m
= libvlc_media_list_item_at_index(libvlc_media_list
,playlist_index
);
674 libvlc_media_list_unlock(libvlc_media_list
);
679 if( libvlc_media_player
)
681 if( playlist_isplaying() )
683 events
.unhook_manager( this );
684 libvlc_media_player_release( libvlc_media_player
);
685 libvlc_media_player
= NULL
;
688 libvlc_media_player
= libvlc_media_player_new_from_media( p_m
);
689 if( libvlc_media_player
)
693 libvlc_event_manager_t
*p_em
;
694 p_em
= libvlc_media_player_event_manager( libvlc_media_player
);
695 events
.hook_manager( p_em
, this );
698 libvlc_media_release( p_m
);
702 libvlc_media_list_unlock( libvlc_media_list
);
706 int VlcPlugin::playlist_delete_item( int idx
)
708 if( !libvlc_media_list
)
710 libvlc_media_list_lock(libvlc_media_list
);
711 int ret
= libvlc_media_list_remove_index(libvlc_media_list
,idx
);
712 libvlc_media_list_unlock(libvlc_media_list
);
716 void VlcPlugin::playlist_clear()
718 if( libvlc_media_list
)
719 libvlc_media_list_release(libvlc_media_list
);
720 libvlc_media_list
= libvlc_media_list_new(getVLC());
723 int VlcPlugin::playlist_count()
726 if( !libvlc_media_list
)
728 libvlc_media_list_lock(libvlc_media_list
);
729 items_count
= libvlc_media_list_count(libvlc_media_list
);
730 libvlc_media_list_unlock(libvlc_media_list
);
734 void VlcPlugin::toggle_fullscreen()
736 if( playlist_isplaying() )
737 libvlc_toggle_fullscreen(libvlc_media_player
);
740 void VlcPlugin::set_fullscreen( int yes
)
742 if( playlist_isplaying() )
743 libvlc_set_fullscreen(libvlc_media_player
,yes
);
746 int VlcPlugin::get_fullscreen()
749 if( playlist_isplaying() )
750 r
= libvlc_get_fullscreen(libvlc_media_player
);
754 bool VlcPlugin::player_has_vout()
757 if( playlist_isplaying() )
758 r
= libvlc_media_player_has_vout(libvlc_media_player
);
762 /*****************************************************************************
764 *****************************************************************************/
766 char *VlcPlugin::getAbsoluteURL(const char *url
)
770 // check whether URL is already absolute
771 const char *end
=strchr(url
, ':');
772 if( (NULL
!= end
) && (end
!= url
) )
774 // validate protocol header
775 const char *start
= url
;
780 while( start
!= end
)
787 || ('/' == c
)) ) /* VLC uses / to allow user to specify a demuxer */
788 // not valid protocol header, assume relative URL
792 /* we have a protocol header, therefore URL is absolute */
795 // not a valid protocol header, assume relative URL
802 size_t baseLen
= strlen(psz_baseURL
);
803 char *href
= (char *) malloc(baseLen
+strlen(url
)+1);
806 /* prepend base URL */
807 memcpy(href
, psz_baseURL
, baseLen
+1);
810 ** relative url could be empty,
811 ** in which case return base URL
817 ** locate pathname part of base URL
820 /* skip over protocol part */
821 char *pathstart
= strchr(href
, ':');
822 char *pathend
= href
+baseLen
;
825 if( '/' == *(++pathstart
) )
827 if( '/' == *(++pathstart
) )
832 /* skip over host part */
833 pathstart
= strchr(pathstart
, '/');
836 // no path, add a / past end of url (over '\0')
843 /* baseURL is just a UNIX path */
846 /* baseURL is not an absolute path */
853 /* relative URL made of an absolute path ? */
856 /* replace path completely */
857 strcpy(pathstart
, url
);
861 /* find last path component and replace it */
862 while( '/' != *pathend
)
866 ** if relative url path starts with one or more '../',
867 ** factor them out of href so that we return a
870 while( pathend
!= pathstart
)
878 /* relative url is just '.' */
884 /* relative url starts with './' */
893 /* relative url is '..' */
899 /* relative url starts with '../' */
907 while( '/' != *pathend
);
909 /* skip over '/' separator */
911 /* concatenate remaining base URL and relative URL */
912 strcpy(pathend
, url
);
921 int VlcPlugin::setSize(unsigned width
, unsigned height
)
923 int diff
= (width
!= i_width
) || (height
!= i_height
);
932 #define BTN_SPACE ((unsigned int)4)
933 void VlcPlugin::showToolbar()
935 const NPWindow
& window
= getWindow();
936 Window control
= getControlWindow();
937 Window video
= getVideoWindow();
938 Display
*p_display
= ((NPSetWindowCallbackStruct
*)window
.ws_info
)->display
;
939 unsigned int i_height
= 0, i_width
= BTN_SPACE
;
943 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/play.xpm",
944 &p_btnPlay
, NULL
, NULL
);
947 i_height
= __MAX( i_height
, p_btnPlay
->height
);
950 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/pause.xpm",
951 &p_btnPause
, NULL
, NULL
);
954 i_height
= __MAX( i_height
, p_btnPause
->height
);
956 i_width
+= __MAX( p_btnPause
->width
, p_btnPlay
->width
);
959 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/stop.xpm",
960 &p_btnStop
, NULL
, NULL
);
963 i_height
= __MAX( i_height
, p_btnStop
->height
);
964 i_width
+= BTN_SPACE
+ p_btnStop
->width
;
967 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/time_line.xpm",
968 &p_timeline
, NULL
, NULL
);
971 i_height
= __MAX( i_height
, p_timeline
->height
);
972 i_width
+= BTN_SPACE
+ p_timeline
->width
;
975 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/time_icon.xpm",
976 &p_btnTime
, NULL
, NULL
);
979 i_height
= __MAX( i_height
, p_btnTime
->height
);
980 i_width
+= BTN_SPACE
+ p_btnTime
->width
;
982 if( !p_btnFullscreen
)
983 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/fullscreen.xpm",
984 &p_btnFullscreen
, NULL
, NULL
);
985 if( p_btnFullscreen
)
987 i_height
= __MAX( i_height
, p_btnFullscreen
->height
);
988 i_width
+= BTN_SPACE
+ p_btnFullscreen
->width
;
991 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/volume_max.xpm",
992 &p_btnMute
, NULL
, NULL
);
995 i_height
= __MAX( i_height
, p_btnMute
->height
);
998 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/volume_mute.xpm",
999 &p_btnUnmute
, NULL
, NULL
);
1002 i_height
= __MAX( i_height
, p_btnUnmute
->height
);
1004 i_width
+= BTN_SPACE
+ __MAX( p_btnUnmute
->width
, p_btnMute
->width
);
1006 setToolbarSize( i_width
, i_height
);
1008 if( !p_btnPlay
|| !p_btnPause
|| !p_btnStop
|| !p_timeline
||
1009 !p_btnTime
|| !p_btnFullscreen
|| !p_btnMute
|| !p_btnUnmute
)
1010 fprintf(stderr
, "Error: some button images not found in %s\n", DATA_PATH
);
1012 /* reset panels position and size */
1013 /* XXX use i_width */
1014 XResizeWindow( p_display
, video
, window
.width
, window
.height
- i_height
);
1015 XMoveWindow( p_display
, control
, 0, window
.height
- i_height
);
1016 XResizeWindow( p_display
, control
, window
.width
, i_height
-1);
1018 b_toolbar
= 1; /* says toolbar is now shown */
1022 void VlcPlugin::hideToolbar()
1024 const NPWindow
& window
= getWindow();
1025 Display
*p_display
= ((NPSetWindowCallbackStruct
*)window
.ws_info
)->display
;
1026 Window control
= getControlWindow();
1027 Window video
= getVideoWindow();
1029 i_tb_width
= i_tb_height
= 0;
1031 if( p_btnPlay
) XDestroyImage( p_btnPlay
);
1032 if( p_btnPause
) XDestroyImage( p_btnPause
);
1033 if( p_btnStop
) XDestroyImage( p_btnStop
);
1034 if( p_timeline
) XDestroyImage( p_timeline
);
1035 if( p_btnTime
) XDestroyImage( p_btnTime
);
1036 if( p_btnFullscreen
) XDestroyImage( p_btnFullscreen
);
1037 if( p_btnMute
) XDestroyImage( p_btnMute
);
1038 if( p_btnUnmute
) XDestroyImage( p_btnUnmute
);
1045 p_btnFullscreen
= NULL
;
1049 /* reset panels position and size */
1050 /* XXX use i_width */
1051 XResizeWindow( p_display
, video
, window
.width
, window
.height
);
1052 XMoveWindow( p_display
, control
, 0, window
.height
-1 );
1053 XResizeWindow( p_display
, control
, window
.width
, 1 );
1055 b_toolbar
= 0; /* says toolbar is now hidden */
1059 void VlcPlugin::redrawToolbar()
1062 bool b_mute
= false;
1063 unsigned int dst_x
, dst_y
;
1066 unsigned int i_tb_width
, i_tb_height
;
1068 /* This method does nothing if toolbar is hidden. */
1069 if( !b_toolbar
|| !libvlc_media_player
)
1072 const NPWindow
& window
= getWindow();
1073 Window control
= getControlWindow();
1074 Display
*p_display
= ((NPSetWindowCallbackStruct
*)window
.ws_info
)->display
;
1076 getToolbarSize( &i_tb_width
, &i_tb_height
);
1079 b_mute
= libvlc_audio_get_mute( libvlc_media_player
);
1081 gcv
.foreground
= BlackPixel( p_display
, 0 );
1082 gc
= XCreateGC( p_display
, control
, GCForeground
, &gcv
);
1084 XFillRectangle( p_display
, control
, gc
,
1085 0, 0, window
.width
, i_tb_height
);
1086 gcv
.foreground
= WhitePixel( p_display
, 0 );
1087 XChangeGC( p_display
, gc
, GCForeground
, &gcv
);
1089 /* position icons */
1091 dst_y
= i_tb_height
>> 1; /* baseline = vertical middle */
1093 if( p_btnPause
&& (is_playing
== 1) )
1095 XPutImage( p_display
, control
, gc
, p_btnPause
, 0, 0, dst_x
,
1096 dst_y
- (p_btnPause
->height
>> 1),
1097 p_btnPause
->width
, p_btnPause
->height
);
1098 dst_x
+= BTN_SPACE
+ p_btnPause
->width
;
1100 else if( p_btnPlay
)
1102 XPutImage( p_display
, control
, gc
, p_btnPlay
, 0, 0, dst_x
,
1103 dst_y
- (p_btnPlay
->height
>> 1),
1104 p_btnPlay
->width
, p_btnPlay
->height
);
1105 dst_x
+= BTN_SPACE
+ p_btnPlay
->width
;
1109 XPutImage( p_display
, control
, gc
, p_btnStop
, 0, 0, dst_x
,
1110 dst_y
- (p_btnStop
->height
>> 1),
1111 p_btnStop
->width
, p_btnStop
->height
);
1113 dst_x
+= BTN_SPACE
+ ( p_btnStop
? p_btnStop
->width
: 0 );
1115 if( p_btnFullscreen
)
1116 XPutImage( p_display
, control
, gc
, p_btnFullscreen
, 0, 0, dst_x
,
1117 dst_y
- (p_btnFullscreen
->height
>> 1),
1118 p_btnFullscreen
->width
, p_btnFullscreen
->height
);
1120 dst_x
+= BTN_SPACE
+ ( p_btnFullscreen
? p_btnFullscreen
->width
: 0 );
1122 if( p_btnUnmute
&& b_mute
)
1124 XPutImage( p_display
, control
, gc
, p_btnUnmute
, 0, 0, dst_x
,
1125 dst_y
- (p_btnUnmute
->height
>> 1),
1126 p_btnUnmute
->width
, p_btnUnmute
->height
);
1128 dst_x
+= BTN_SPACE
+ ( p_btnUnmute
? p_btnUnmute
->width
: 0 );
1130 else if( p_btnMute
)
1132 XPutImage( p_display
, control
, gc
, p_btnMute
, 0, 0, dst_x
,
1133 dst_y
- (p_btnMute
->height
>> 1),
1134 p_btnMute
->width
, p_btnMute
->height
);
1136 dst_x
+= BTN_SPACE
+ ( p_btnMute
? p_btnMute
->width
: 0 );
1140 XPutImage( p_display
, control
, gc
, p_timeline
, 0, 0, dst_x
,
1141 dst_y
- (p_timeline
->height
>> 1),
1142 (window
.width
-(dst_x
+BTN_SPACE
)), p_timeline
->height
);
1144 /* get movie position in % */
1145 if( playlist_isplaying() )
1147 i_last_position
= (int)((window
.width
-(dst_x
+BTN_SPACE
))*
1148 libvlc_media_player_get_position(libvlc_media_player
));
1152 XPutImage( p_display
, control
, gc
, p_btnTime
,
1153 0, 0, (dst_x
+i_last_position
),
1154 dst_y
- (p_btnTime
->height
>> 1),
1155 p_btnTime
->width
, p_btnTime
->height
);
1157 XFreeGC( p_display
, gc
);
1160 vlc_toolbar_clicked_t
VlcPlugin::getToolbarButtonClicked( int i_xpos
, int i_ypos
)
1162 unsigned int i_dest
= BTN_SPACE
;
1164 bool b_mute
= false;
1167 fprintf( stderr
, "ToolbarButtonClicked:: "
1168 "trying to match (%d,%d) (%d,%d)\n",
1169 i_xpos
, i_ypos
, i_tb_height
, i_tb_width
);
1171 if( i_ypos
>= i_tb_width
)
1172 return clicked_Unknown
;
1174 /* Note: the order of testing is dependend on the original
1175 * drawing positions of the icon buttons. Buttons are tested
1180 is_playing
= playlist_isplaying();
1183 if( libvlc_media_player
)
1184 b_mute
= libvlc_audio_get_mute( libvlc_media_player
);
1186 /* is Pause of Play button clicked */
1187 if( (is_playing
!= 1) &&
1188 (i_xpos
>= (BTN_SPACE
>>1)) &&
1189 (i_xpos
<= i_dest
+ p_btnPlay
->width
+ (BTN_SPACE
>>1)) )
1190 return clicked_Play
;
1191 else if( (i_xpos
>= (BTN_SPACE
>>1)) &&
1192 (i_xpos
<= i_dest
+ p_btnPause
->width
) )
1193 return clicked_Pause
;
1195 /* is Stop button clicked */
1196 if( is_playing
!= 1 )
1197 i_dest
+= (p_btnPlay
->width
+ (BTN_SPACE
>>1));
1199 i_dest
+= (p_btnPause
->width
+ (BTN_SPACE
>>1));
1201 if( (i_xpos
>= i_dest
) &&
1202 (i_xpos
<= i_dest
+ p_btnStop
->width
+ (BTN_SPACE
>>1)) )
1203 return clicked_Stop
;
1205 /* is Fullscreen button clicked */
1206 i_dest
+= (p_btnStop
->width
+ (BTN_SPACE
>>1));
1207 if( (i_xpos
>= i_dest
) &&
1208 (i_xpos
<= i_dest
+ p_btnFullscreen
->width
+ (BTN_SPACE
>>1)) )
1209 return clicked_Fullscreen
;
1211 /* is Mute or Unmute button clicked */
1212 i_dest
+= (p_btnFullscreen
->width
+ (BTN_SPACE
>>1));
1213 if( !b_mute
&& (i_xpos
>= i_dest
) &&
1214 (i_xpos
<= i_dest
+ p_btnMute
->width
+ (BTN_SPACE
>>1)) )
1215 return clicked_Mute
;
1216 else if( (i_xpos
>= i_dest
) &&
1217 (i_xpos
<= i_dest
+ p_btnUnmute
->width
+ (BTN_SPACE
>>1)) )
1218 return clicked_Unmute
;
1220 /* is timeline clicked */
1222 i_dest
+= (p_btnMute
->width
+ (BTN_SPACE
>>1));
1224 i_dest
+= (p_btnUnmute
->width
+ (BTN_SPACE
>>1));
1225 if( (i_xpos
>= i_dest
) &&
1226 (i_xpos
<= i_dest
+ p_timeline
->width
+ (BTN_SPACE
>>1)) )
1227 return clicked_timeline
;
1229 /* is time button clicked */
1230 i_dest
+= (p_timeline
->width
+ (BTN_SPACE
>>1));
1231 if( (i_xpos
>= i_dest
) &&
1232 (i_xpos
<= i_dest
+ p_btnTime
->width
+ (BTN_SPACE
>>1)) )
1233 return clicked_Time
;
1235 return clicked_Unknown
;
1240 // Verifies the version of the NPAPI.
1241 // The eventListeners use a NPAPI function available
1243 bool VlcPlugin::canUseEventListener()
1245 int plugin_major
, plugin_minor
;
1246 int browser_major
, browser_minor
;
1248 NPN_Version(&plugin_major
, &plugin_minor
,
1249 &browser_major
, &browser_minor
);
1251 if (browser_minor
>= 19 || browser_major
> 0)