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"
32 #include "control/npolibvlc.h"
42 #warning "locking not implemented for this platform"
49 /*****************************************************************************
51 *****************************************************************************/
52 static void plugin_lock_init(plugin_lock_t
*lock
)
57 pthread_mutex_init(&lock
->mutex
, NULL
);
59 InitializeCriticalSection(&lock
->cs
);
61 #warning "locking not implemented in this platform"
65 static void plugin_lock_destroy(plugin_lock_t
*lock
)
70 pthread_mutex_destroy(&lock
->mutex
);
72 DeleteCriticalSection(&lock
->cs
);
74 #warning "locking not implemented in this platform"
78 static void plugin_lock(plugin_lock_t
*lock
)
83 pthread_mutex_lock(&lock
->mutex
);
85 EnterCriticalSection(&lock
->cs
);
87 #warning "locking not implemented in this platform"
91 static void plugin_unlock(plugin_lock_t
*lock
)
96 pthread_mutex_unlock(&lock
->mutex
);
98 LeaveCriticalSection(&lock
->cs
);
100 #warning "locking not implemented in this platform"
104 /*****************************************************************************
105 * VlcPlugin constructor and destructor
106 *****************************************************************************/
107 #if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) < 20)
108 VlcPlugin::VlcPlugin( NPP instance
, uint16 mode
) :
110 VlcPlugin::VlcPlugin( NPP instance
, uint16_t mode
) :
119 libvlc_instance(NULL
),
120 libvlc_media_list(NULL
),
121 libvlc_media_player(NULL
),
129 ,i_width((unsigned)-1)
130 ,i_height((unsigned)-1)
139 ,p_btnFullscreen(NULL
)
144 memset(&npwindow
, 0, sizeof(NPWindow
));
146 memset(&npvideo
, 0, sizeof(Window
));
147 memset(&npcontrol
, 0, sizeof(Window
));
151 static bool boolValue(const char *value
) {
152 return ( !strcmp(value
, "1") ||
153 !strcasecmp(value
, "true") ||
154 !strcasecmp(value
, "yes") );
157 bool EventObj::init()
159 plugin_lock_init(&lock
);
163 EventObj::~EventObj()
165 plugin_lock_destroy(&lock
);
168 void EventObj::deliver(NPP browser
)
175 for( ev_l::iterator i
=_elist
.begin();i
!=_elist
.end();++i
)
177 libvlc_event_type_t event
= *i
;
178 STRINGZ_TO_NPVARIANT(libvlc_event_type_name(event
), params
[0]);
180 // Invalid events aren't supposed to be queued up.
181 // if( !have_event(event) ) continue;
183 for( lr_l::iterator j
=_llist
.begin();j
!=_llist
.end();++j
)
187 NPN_InvokeDefault(browser
, j
->listener(), params
, 1, &result
);
188 NPN_ReleaseVariantValue(&result
);
194 plugin_unlock(&lock
);
197 void VlcPlugin::eventAsync(void *param
)
199 VlcPlugin
*plugin
= (VlcPlugin
*)param
;
200 plugin
->events
.deliver(plugin
->getBrowser());
203 void EventObj::callback(const libvlc_event_t
* event
)
207 if( have_event(event
->type
) )
208 _elist
.push_back(event
->type
);
210 plugin_unlock(&lock
);
213 void VlcPlugin::event_callback(const libvlc_event_t
* event
, void *param
)
215 VlcPlugin
*plugin
= (VlcPlugin
*)param
;
217 plugin
->events
.callback(event
);
218 NPN_PluginThreadAsyncCall(plugin
->getBrowser(), eventAsync
, plugin
);
220 #warning NPN_PluginThreadAsyncCall not implemented yet.
221 printf("No NPN_PluginThreadAsyncCall(), doing nothing.");
225 inline EventObj::event_t
EventObj::find_event(const char *s
) const
228 for(i
=0;i
<maxbit();++i
)
229 if(!strcmp(s
,libvlc_event_type_name(i
)))
234 bool EventObj::insert(const NPString
&s
, NPObject
*l
, bool b
)
236 event_t e
= find_event(s
.UTF8Characters
);
240 if( !have_event(e
) && !ask_for_event(e
) )
244 for(i
=_llist
.begin();i
!=_llist
.end();++i
)
245 if(i
->listener()==l
&& i
->bubble()==b
)
248 if( i
== _llist
.end() ) {
249 _llist
.push_back(Listener(e
,l
,b
));
259 bool EventObj::remove(const NPString
&s
, NPObject
*l
, bool b
)
261 event_t e
= find_event(s
.UTF8Characters
);
262 if( e
>=maxbit() || !get(e
) )
266 for(lr_l::iterator i
=_llist
.begin();i
!=_llist
.end();)
268 if(i
->listener()!=l
|| i
->bubble()!=b
)
288 void EventObj::hook_manager(libvlc_event_manager_t
*em
,
289 libvlc_callback_t cb
, void *udata
)
291 _em
= em
; _cb
= cb
; _ud
= udata
;
294 for(size_t i
=0;i
<maxbit();++i
)
296 libvlc_event_attach(_em
, i
, _cb
, _ud
);
299 void EventObj::unhook_manager()
303 for(size_t i
=0;i
<maxbit();++i
)
305 libvlc_event_detach(_em
, i
, _cb
, _ud
);
309 bool EventObj::ask_for_event(event_t e
)
311 return _em
?0==libvlc_event_attach(_em
, e
, _cb
, _ud
):false;
315 void EventObj::unask_for_event(event_t e
)
317 if(_em
) libvlc_event_detach(_em
, e
, _cb
, _ud
);
321 NPError
VlcPlugin::init(int argc
, char* const argn
[], char* const argv
[])
323 /* prepare VLC command line */
324 const char *ppsz_argv
[32];
328 ppsz_argv
[ppsz_argc
++] = "--no-plugins-cache";
331 /* locate VLC module path */
333 ppsz_argv
[ppsz_argc
++] = "--plugin-path=/Library/Internet\\ Plug-Ins/VLC\\ Plugin.plugin/Contents/MacOS/plugins";
334 ppsz_argv
[ppsz_argc
++] = "--vout=minimal_macosx";
335 #elif defined(XP_WIN)
337 DWORD i_type
, i_data
= MAX_PATH
+ 1;
338 char p_data
[MAX_PATH
+ 1];
339 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE
, "Software\\VideoLAN\\VLC",
340 0, KEY_READ
, &h_key
) == ERROR_SUCCESS
)
342 if( RegQueryValueEx( h_key
, "InstallDir", 0, &i_type
,
343 (LPBYTE
)p_data
, &i_data
) == ERROR_SUCCESS
)
345 if( i_type
== REG_SZ
)
347 strcat( p_data
, "\\plugins" );
348 ppsz_argv
[ppsz_argc
++] = "--plugin-path";
349 ppsz_argv
[ppsz_argc
++] = p_data
;
352 RegCloseKey( h_key
);
354 ppsz_argv
[ppsz_argc
++] = "--no-one-instance";
356 #endif /* XP_MACOSX */
358 /* common settings */
359 ppsz_argv
[ppsz_argc
++] = "-vv";
360 ppsz_argv
[ppsz_argc
++] = "--no-stats";
361 ppsz_argv
[ppsz_argc
++] = "--no-media-library";
362 ppsz_argv
[ppsz_argc
++] = "--intf=dummy";
363 ppsz_argv
[ppsz_argc
++] = "--no-video-title-show";
364 ppsz_argv
[ppsz_argc
++] = "--no-xlib";
366 const char *progid
= NULL
;
368 /* parse plugin arguments */
369 for( int i
= 0; (i
< argc
) && (ppsz_argc
< 32); i
++ )
371 /* fprintf(stderr, "argn=%s, argv=%s\n", argn[i], argv[i]); */
373 if( !strcmp( argn
[i
], "target" )
374 || !strcmp( argn
[i
], "mrl")
375 || !strcmp( argn
[i
], "filename")
376 || !strcmp( argn
[i
], "src") )
378 psz_target
= argv
[i
];
380 else if( !strcmp( argn
[i
], "text" ) )
383 psz_text
= strdup( argv
[i
] );
385 else if( !strcmp( argn
[i
], "autoplay")
386 || !strcmp( argn
[i
], "autostart") )
388 b_autoplay
= boolValue(argv
[i
]);
390 else if( !strcmp( argn
[i
], "fullscreen" ) )
392 if( boolValue(argv
[i
]) )
394 ppsz_argv
[ppsz_argc
++] = "--fullscreen";
398 ppsz_argv
[ppsz_argc
++] = "--no-fullscreen";
401 else if( !strcmp( argn
[i
], "mute" ) )
403 if( boolValue(argv
[i
]) )
405 ppsz_argv
[ppsz_argc
++] = "--volume=0";
408 else if( !strcmp( argn
[i
], "loop")
409 || !strcmp( argn
[i
], "autoloop") )
411 if( boolValue(argv
[i
]) )
413 ppsz_argv
[ppsz_argc
++] = "--loop";
417 ppsz_argv
[ppsz_argc
++] = "--no-loop";
420 else if( !strcmp( argn
[i
], "version")
421 || !strcmp( argn
[i
], "progid") )
425 else if( !strcmp( argn
[i
], "toolbar" ) )
427 /* FIXME: Remove this when toolbar functionality has been implemented on
428 * MacOS X and Win32 for Firefox/Mozilla/Safari. */
430 b_toolbar
= boolValue(argv
[i
]);
435 libvlc_instance
= libvlc_new(ppsz_argc
, ppsz_argv
);
436 if( !libvlc_instance
)
437 return NPERR_GENERIC_ERROR
;
438 libvlc_media_list
= libvlc_media_list_new(libvlc_instance
);
441 ** fetch plugin base URL, which is the URL of the page containing the plugin
442 ** this URL is used for making absolute URL from relative URL that may be
443 ** passed as an MRL argument
445 NPObject
*plugin
= NULL
;
447 if( NPERR_NO_ERROR
== NPN_GetValue(p_browser
, NPNVWindowNPObject
, &plugin
) )
450 ** is there a better way to get that info ?
452 static const char docLocHref
[] = "document.location.href";
456 script
.UTF8Characters
= docLocHref
;
457 script
.UTF8Length
= sizeof(docLocHref
)-1;
459 if( NPN_Evaluate(p_browser
, plugin
, &script
, &result
) )
461 if( NPVARIANT_IS_STRING(result
) )
463 NPString
&location
= NPVARIANT_TO_STRING(result
);
465 psz_baseURL
= (char *) malloc(location
.UTF8Length
+1);
468 strncpy(psz_baseURL
, location
.UTF8Characters
, location
.UTF8Length
);
469 psz_baseURL
[location
.UTF8Length
] = '\0';
472 NPN_ReleaseVariantValue(&result
);
474 NPN_ReleaseObject(plugin
);
479 // get absolute URL from src
480 char *psz_absurl
= getAbsoluteURL(psz_target
);
481 psz_target
= psz_absurl
? psz_absurl
: strdup(psz_target
);
484 /* assign plugin script root class */
486 p_scriptClass
= RuntimeNPClass
<LibvlcRootNPObject
>::getClass();
489 return NPERR_GENERIC_ERROR
;
491 return NPERR_NO_ERROR
;
494 VlcPlugin::~VlcPlugin()
500 if( libvlc_media_player
)
502 if( playlist_isplaying() )
504 events
.unhook_manager();
505 libvlc_media_player_release( libvlc_media_player
);
507 if( libvlc_media_list
)
508 libvlc_media_list_release( libvlc_media_list
);
509 if( libvlc_instance
)
510 libvlc_release(libvlc_instance
);
513 /*****************************************************************************
514 * VlcPlugin playlist replacement methods
515 *****************************************************************************/
516 void VlcPlugin::set_player_window()
519 libvlc_media_player_set_xwindow(libvlc_media_player
,
520 (uint32_t)getVideoWindow());
523 // XXX FIXME insert appropriate call here
526 libvlc_media_player_set_hwnd(libvlc_media_player
,
531 int VlcPlugin::playlist_add( const char *mrl
)
534 libvlc_media_t
*p_m
= libvlc_media_new_location(libvlc_instance
,mrl
);
537 assert( libvlc_media_list
);
538 libvlc_media_list_lock(libvlc_media_list
);
539 if( !libvlc_media_list_add_media(libvlc_media_list
,p_m
) )
540 item
= libvlc_media_list_count(libvlc_media_list
)-1;
541 libvlc_media_list_unlock(libvlc_media_list
);
543 libvlc_media_release(p_m
);
548 int VlcPlugin::playlist_add_extended_untrusted( const char *mrl
, const char *name
,
549 int optc
, const char **optv
)
554 assert( libvlc_media_list
);
556 p_m
= libvlc_media_new_location(libvlc_instance
, mrl
);
560 for( int i
= 0; i
< optc
; ++i
)
561 libvlc_media_add_option_flag(p_m
, optv
[i
], libvlc_media_option_unique
);
563 libvlc_media_list_lock(libvlc_media_list
);
564 if( !libvlc_media_list_add_media(libvlc_media_list
,p_m
) )
565 item
= libvlc_media_list_count(libvlc_media_list
)-1;
566 libvlc_media_list_unlock(libvlc_media_list
);
567 libvlc_media_release(p_m
);
572 bool VlcPlugin::playlist_select( int idx
)
574 libvlc_media_t
*p_m
= NULL
;
576 assert( libvlc_media_list
);
578 libvlc_media_list_lock(libvlc_media_list
);
580 int count
= libvlc_media_list_count(libvlc_media_list
);
581 if( idx
<0||idx
>=count
)
584 playlist_index
= idx
;
586 p_m
= libvlc_media_list_item_at_index(libvlc_media_list
,playlist_index
);
587 libvlc_media_list_unlock(libvlc_media_list
);
592 if( libvlc_media_player
)
594 if( playlist_isplaying() )
596 events
.unhook_manager();
597 libvlc_media_player_release( libvlc_media_player
);
598 libvlc_media_player
= NULL
;
601 libvlc_media_player
= libvlc_media_player_new_from_media(p_m
);
602 if( libvlc_media_player
)
606 libvlc_media_player_event_manager(libvlc_media_player
),
607 event_callback
, this);
610 libvlc_media_release( p_m
);
614 libvlc_media_list_unlock(libvlc_media_list
);
618 int VlcPlugin::playlist_delete_item( int idx
)
620 if( !libvlc_media_list
)
622 libvlc_media_list_lock(libvlc_media_list
);
623 int ret
= libvlc_media_list_remove_index(libvlc_media_list
,idx
);
624 libvlc_media_list_unlock(libvlc_media_list
);
628 void VlcPlugin::playlist_clear()
630 if( libvlc_media_list
)
631 libvlc_media_list_release(libvlc_media_list
);
632 libvlc_media_list
= libvlc_media_list_new(getVLC());
635 int VlcPlugin::playlist_count()
638 if( !libvlc_media_list
)
640 libvlc_media_list_lock(libvlc_media_list
);
641 items_count
= libvlc_media_list_count(libvlc_media_list
);
642 libvlc_media_list_unlock(libvlc_media_list
);
646 void VlcPlugin::toggle_fullscreen()
648 if( playlist_isplaying() )
649 libvlc_toggle_fullscreen(libvlc_media_player
);
652 void VlcPlugin::set_fullscreen( int yes
)
654 if( playlist_isplaying() )
655 libvlc_set_fullscreen(libvlc_media_player
,yes
);
658 int VlcPlugin::get_fullscreen()
661 if( playlist_isplaying() )
662 r
= libvlc_get_fullscreen(libvlc_media_player
);
666 bool VlcPlugin::player_has_vout()
669 if( playlist_isplaying() )
670 r
= libvlc_media_player_has_vout(libvlc_media_player
);
674 /*****************************************************************************
676 *****************************************************************************/
678 char *VlcPlugin::getAbsoluteURL(const char *url
)
682 // check whether URL is already absolute
683 const char *end
=strchr(url
, ':');
684 if( (NULL
!= end
) && (end
!= url
) )
686 // validate protocol header
687 const char *start
= url
;
692 while( start
!= end
)
699 || ('/' == c
)) ) /* VLC uses / to allow user to specify a demuxer */
700 // not valid protocol header, assume relative URL
704 /* we have a protocol header, therefore URL is absolute */
707 // not a valid protocol header, assume relative URL
714 size_t baseLen
= strlen(psz_baseURL
);
715 char *href
= (char *) malloc(baseLen
+strlen(url
)+1);
718 /* prepend base URL */
719 memcpy(href
, psz_baseURL
, baseLen
+1);
722 ** relative url could be empty,
723 ** in which case return base URL
729 ** locate pathname part of base URL
732 /* skip over protocol part */
733 char *pathstart
= strchr(href
, ':');
734 char *pathend
= href
+baseLen
;
737 if( '/' == *(++pathstart
) )
739 if( '/' == *(++pathstart
) )
744 /* skip over host part */
745 pathstart
= strchr(pathstart
, '/');
748 // no path, add a / past end of url (over '\0')
755 /* baseURL is just a UNIX path */
758 /* baseURL is not an absolute path */
765 /* relative URL made of an absolute path ? */
768 /* replace path completely */
769 strcpy(pathstart
, url
);
773 /* find last path component and replace it */
774 while( '/' != *pathend
)
778 ** if relative url path starts with one or more '../',
779 ** factor them out of href so that we return a
782 while( pathend
!= pathstart
)
790 /* relative url is just '.' */
796 /* relative url starts with './' */
805 /* relative url is '..' */
811 /* relative url starts with '../' */
819 while( '/' != *pathend
);
821 /* skip over '/' separator */
823 /* concatenate remaining base URL and relative URL */
824 strcpy(pathend
, url
);
833 int VlcPlugin::setSize(unsigned width
, unsigned height
)
835 int diff
= (width
!= i_width
) || (height
!= i_height
);
844 #define BTN_SPACE ((unsigned int)4)
845 void VlcPlugin::showToolbar()
847 const NPWindow
& window
= getWindow();
848 Window control
= getControlWindow();
849 Window video
= getVideoWindow();
850 Display
*p_display
= ((NPSetWindowCallbackStruct
*)window
.ws_info
)->display
;
851 unsigned int i_height
= 0, i_width
= BTN_SPACE
;
855 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/play.xpm",
856 &p_btnPlay
, NULL
, NULL
);
859 i_height
= __MAX( i_height
, p_btnPlay
->height
);
862 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/pause.xpm",
863 &p_btnPause
, NULL
, NULL
);
866 i_height
= __MAX( i_height
, p_btnPause
->height
);
868 i_width
+= __MAX( p_btnPause
->width
, p_btnPlay
->width
);
871 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/stop.xpm",
872 &p_btnStop
, NULL
, NULL
);
875 i_height
= __MAX( i_height
, p_btnStop
->height
);
876 i_width
+= BTN_SPACE
+ p_btnStop
->width
;
879 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/time_line.xpm",
880 &p_timeline
, NULL
, NULL
);
883 i_height
= __MAX( i_height
, p_timeline
->height
);
884 i_width
+= BTN_SPACE
+ p_timeline
->width
;
887 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/time_icon.xpm",
888 &p_btnTime
, NULL
, NULL
);
891 i_height
= __MAX( i_height
, p_btnTime
->height
);
892 i_width
+= BTN_SPACE
+ p_btnTime
->width
;
894 if( !p_btnFullscreen
)
895 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/fullscreen.xpm",
896 &p_btnFullscreen
, NULL
, NULL
);
897 if( p_btnFullscreen
)
899 i_height
= __MAX( i_height
, p_btnFullscreen
->height
);
900 i_width
+= BTN_SPACE
+ p_btnFullscreen
->width
;
903 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/volume_max.xpm",
904 &p_btnMute
, NULL
, NULL
);
907 i_height
= __MAX( i_height
, p_btnMute
->height
);
910 XpmReadFileToImage( p_display
, DATA_PATH
"/mozilla/volume_mute.xpm",
911 &p_btnUnmute
, NULL
, NULL
);
914 i_height
= __MAX( i_height
, p_btnUnmute
->height
);
916 i_width
+= BTN_SPACE
+ __MAX( p_btnUnmute
->width
, p_btnMute
->width
);
918 setToolbarSize( i_width
, i_height
);
920 if( !p_btnPlay
|| !p_btnPause
|| !p_btnStop
|| !p_timeline
||
921 !p_btnTime
|| !p_btnFullscreen
|| !p_btnMute
|| !p_btnUnmute
)
922 fprintf(stderr
, "Error: some button images not found in %s\n", DATA_PATH
);
924 /* reset panels position and size */
925 /* XXX use i_width */
926 XResizeWindow( p_display
, video
, window
.width
, window
.height
- i_height
);
927 XMoveWindow( p_display
, control
, 0, window
.height
- i_height
);
928 XResizeWindow( p_display
, control
, window
.width
, i_height
-1);
930 b_toolbar
= 1; /* says toolbar is now shown */
934 void VlcPlugin::hideToolbar()
936 const NPWindow
& window
= getWindow();
937 Display
*p_display
= ((NPSetWindowCallbackStruct
*)window
.ws_info
)->display
;
938 Window control
= getControlWindow();
939 Window video
= getVideoWindow();
941 i_tb_width
= i_tb_height
= 0;
943 if( p_btnPlay
) XDestroyImage( p_btnPlay
);
944 if( p_btnPause
) XDestroyImage( p_btnPause
);
945 if( p_btnStop
) XDestroyImage( p_btnStop
);
946 if( p_timeline
) XDestroyImage( p_timeline
);
947 if( p_btnTime
) XDestroyImage( p_btnTime
);
948 if( p_btnFullscreen
) XDestroyImage( p_btnFullscreen
);
949 if( p_btnMute
) XDestroyImage( p_btnMute
);
950 if( p_btnUnmute
) XDestroyImage( p_btnUnmute
);
957 p_btnFullscreen
= NULL
;
961 /* reset panels position and size */
962 /* XXX use i_width */
963 XResizeWindow( p_display
, video
, window
.width
, window
.height
);
964 XMoveWindow( p_display
, control
, 0, window
.height
-1 );
965 XResizeWindow( p_display
, control
, window
.width
, 1 );
967 b_toolbar
= 0; /* says toolbar is now hidden */
971 void VlcPlugin::redrawToolbar()
975 unsigned int dst_x
, dst_y
;
978 unsigned int i_tb_width
, i_tb_height
;
980 /* This method does nothing if toolbar is hidden. */
981 if( !b_toolbar
|| !libvlc_media_player
)
984 const NPWindow
& window
= getWindow();
985 Window control
= getControlWindow();
986 Display
*p_display
= ((NPSetWindowCallbackStruct
*)window
.ws_info
)->display
;
988 getToolbarSize( &i_tb_width
, &i_tb_height
);
991 b_mute
= libvlc_audio_get_mute( libvlc_media_player
);
993 gcv
.foreground
= BlackPixel( p_display
, 0 );
994 gc
= XCreateGC( p_display
, control
, GCForeground
, &gcv
);
996 XFillRectangle( p_display
, control
, gc
,
997 0, 0, window
.width
, i_tb_height
);
998 gcv
.foreground
= WhitePixel( p_display
, 0 );
999 XChangeGC( p_display
, gc
, GCForeground
, &gcv
);
1001 /* position icons */
1003 dst_y
= i_tb_height
>> 1; /* baseline = vertical middle */
1005 if( p_btnPause
&& (is_playing
== 1) )
1007 XPutImage( p_display
, control
, gc
, p_btnPause
, 0, 0, dst_x
,
1008 dst_y
- (p_btnPause
->height
>> 1),
1009 p_btnPause
->width
, p_btnPause
->height
);
1010 dst_x
+= BTN_SPACE
+ p_btnPause
->width
;
1012 else if( p_btnPlay
)
1014 XPutImage( p_display
, control
, gc
, p_btnPlay
, 0, 0, dst_x
,
1015 dst_y
- (p_btnPlay
->height
>> 1),
1016 p_btnPlay
->width
, p_btnPlay
->height
);
1017 dst_x
+= BTN_SPACE
+ p_btnPlay
->width
;
1021 XPutImage( p_display
, control
, gc
, p_btnStop
, 0, 0, dst_x
,
1022 dst_y
- (p_btnStop
->height
>> 1),
1023 p_btnStop
->width
, p_btnStop
->height
);
1025 dst_x
+= BTN_SPACE
+ ( p_btnStop
? p_btnStop
->width
: 0 );
1027 if( p_btnFullscreen
)
1028 XPutImage( p_display
, control
, gc
, p_btnFullscreen
, 0, 0, dst_x
,
1029 dst_y
- (p_btnFullscreen
->height
>> 1),
1030 p_btnFullscreen
->width
, p_btnFullscreen
->height
);
1032 dst_x
+= BTN_SPACE
+ ( p_btnFullscreen
? p_btnFullscreen
->width
: 0 );
1034 if( p_btnUnmute
&& b_mute
)
1036 XPutImage( p_display
, control
, gc
, p_btnUnmute
, 0, 0, dst_x
,
1037 dst_y
- (p_btnUnmute
->height
>> 1),
1038 p_btnUnmute
->width
, p_btnUnmute
->height
);
1040 dst_x
+= BTN_SPACE
+ ( p_btnUnmute
? p_btnUnmute
->width
: 0 );
1042 else if( p_btnMute
)
1044 XPutImage( p_display
, control
, gc
, p_btnMute
, 0, 0, dst_x
,
1045 dst_y
- (p_btnMute
->height
>> 1),
1046 p_btnMute
->width
, p_btnMute
->height
);
1048 dst_x
+= BTN_SPACE
+ ( p_btnMute
? p_btnMute
->width
: 0 );
1052 XPutImage( p_display
, control
, gc
, p_timeline
, 0, 0, dst_x
,
1053 dst_y
- (p_timeline
->height
>> 1),
1054 (window
.width
-(dst_x
+BTN_SPACE
)), p_timeline
->height
);
1056 /* get movie position in % */
1057 if( playlist_isplaying() )
1059 i_last_position
= (int)((window
.width
-(dst_x
+BTN_SPACE
))*
1060 libvlc_media_player_get_position(libvlc_media_player
));
1064 XPutImage( p_display
, control
, gc
, p_btnTime
,
1065 0, 0, (dst_x
+i_last_position
),
1066 dst_y
- (p_btnTime
->height
>> 1),
1067 p_btnTime
->width
, p_btnTime
->height
);
1069 XFreeGC( p_display
, gc
);
1072 vlc_toolbar_clicked_t
VlcPlugin::getToolbarButtonClicked( int i_xpos
, int i_ypos
)
1074 unsigned int i_dest
= BTN_SPACE
;
1076 bool b_mute
= false;
1079 fprintf( stderr
, "ToolbarButtonClicked:: "
1080 "trying to match (%d,%d) (%d,%d)\n",
1081 i_xpos
, i_ypos
, i_tb_height
, i_tb_width
);
1083 if( i_ypos
>= i_tb_width
)
1084 return clicked_Unknown
;
1086 /* Note: the order of testing is dependend on the original
1087 * drawing positions of the icon buttons. Buttons are tested
1092 is_playing
= playlist_isplaying();
1095 if( libvlc_media_player
)
1096 b_mute
= libvlc_audio_get_mute( libvlc_media_player
);
1098 /* is Pause of Play button clicked */
1099 if( (is_playing
!= 1) &&
1100 (i_xpos
>= (BTN_SPACE
>>1)) &&
1101 (i_xpos
<= i_dest
+ p_btnPlay
->width
+ (BTN_SPACE
>>1)) )
1102 return clicked_Play
;
1103 else if( (i_xpos
>= (BTN_SPACE
>>1)) &&
1104 (i_xpos
<= i_dest
+ p_btnPause
->width
) )
1105 return clicked_Pause
;
1107 /* is Stop button clicked */
1108 if( is_playing
!= 1 )
1109 i_dest
+= (p_btnPlay
->width
+ (BTN_SPACE
>>1));
1111 i_dest
+= (p_btnPause
->width
+ (BTN_SPACE
>>1));
1113 if( (i_xpos
>= i_dest
) &&
1114 (i_xpos
<= i_dest
+ p_btnStop
->width
+ (BTN_SPACE
>>1)) )
1115 return clicked_Stop
;
1117 /* is Fullscreen button clicked */
1118 i_dest
+= (p_btnStop
->width
+ (BTN_SPACE
>>1));
1119 if( (i_xpos
>= i_dest
) &&
1120 (i_xpos
<= i_dest
+ p_btnFullscreen
->width
+ (BTN_SPACE
>>1)) )
1121 return clicked_Fullscreen
;
1123 /* is Mute or Unmute button clicked */
1124 i_dest
+= (p_btnFullscreen
->width
+ (BTN_SPACE
>>1));
1125 if( !b_mute
&& (i_xpos
>= i_dest
) &&
1126 (i_xpos
<= i_dest
+ p_btnMute
->width
+ (BTN_SPACE
>>1)) )
1127 return clicked_Mute
;
1128 else if( (i_xpos
>= i_dest
) &&
1129 (i_xpos
<= i_dest
+ p_btnUnmute
->width
+ (BTN_SPACE
>>1)) )
1130 return clicked_Unmute
;
1132 /* is timeline clicked */
1134 i_dest
+= (p_btnMute
->width
+ (BTN_SPACE
>>1));
1136 i_dest
+= (p_btnUnmute
->width
+ (BTN_SPACE
>>1));
1137 if( (i_xpos
>= i_dest
) &&
1138 (i_xpos
<= i_dest
+ p_timeline
->width
+ (BTN_SPACE
>>1)) )
1139 return clicked_timeline
;
1141 /* is time button clicked */
1142 i_dest
+= (p_timeline
->width
+ (BTN_SPACE
>>1));
1143 if( (i_xpos
>= i_dest
) &&
1144 (i_xpos
<= i_dest
+ p_btnTime
->width
+ (BTN_SPACE
>>1)) )
1145 return clicked_Time
;
1147 return clicked_Unknown
;
1152 // Verifies the version of the NPAPI.
1153 // The eventListeners use a NPAPI function available
1155 bool VlcPlugin::canUseEventListener()
1157 int plugin_major
, plugin_minor
;
1158 int browser_major
, browser_minor
;
1160 NPN_Version(&plugin_major
, &plugin_minor
,
1161 &browser_major
, &browser_minor
);
1163 if (browser_minor
>= 19 || browser_major
> 0)