~ubuntu-branches/ubuntu/oneiric/cairo-dock-plug-ins/oneiric-updates

« back to all changes in this revision

Viewing changes to musicPlayer/src/applet-mpris.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe), Matthieu Baerts (matttbe), Iain Lane
  • Date: 2011-10-09 00:19:16 UTC
  • mfrom: (1.1.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20111009001916-9czstskx2t6l0b3x
Tags: 2.4.0~2-0ubuntu1
[ Matthieu Baerts (matttbe) ]
* New upstream bug fix release. (LP: #859984)
* Upstream (short) ChangeLog (2.4.0~0beta2 -> 2.4.0~1):
 - Powermanager: correctly release the reference on the device object
 - logout: now works if there is no session-manager
 - Status-Notifier: fixed a small bug
    (wrong callback in cairo_dock_stop_watching_dbus_name_owner)
 - Folders: fixed the positionning of the new icon
    and the dialog when dropping a folder inside the dock
    and fixed the icon-rendering
 - Dustbin: use the default theme if no icon is found
 - Impulse: the default context seems to be ok and not an error
 - Status-Notifier: On Ubuntu Oneiric (with indicator-0.4)
    the ApplicationAdded signal has changed and has a new parameter
 - Disable MeMenu on Oneiric (no longer available with indicator-0.4)
 - CMakeLists.txt: Improved output messages
 - Slide view: fixed a small offset in vertical view
 - musicPlayer:
  + split MPRIS 1.0 and 2.0 to help debugging and finding the right
     name of the bug.
  + 'rhythmbox-client' tool is no longer available: used MPRIS
  + Disable Amazon service (it no longer work)
  + Cover: fixed corrupted icons: some players (e.g. the latest version
     of RB) copy covers on their cache forlder but it takes a few time.
  + Fixed the update the icon and its name if the player is stopped.
  + Prevent a crash if the name given by MPRIS is NULL
 - Powermanager: try to prevent to have a few dialogues at the same time
 - PowerManager and AlsaMixer: hidden gnome2 or 3 apps if not available
 - Messaging-Menu: Updated for Natty and Oneiric
    (dbus-menu gives us GVariant instead of GValue objects)
 - Alsamixer: fixed a small bug on reload
 - Dbus: Bash interface: Fixed a typo with emblem positions
 - Sys-monitor: fixed a bug which prevented from getting
    the CPU temperature in some cases
 - Compiz (0.9): type filter: replaced type=utility by type=Utility
 - Updated the version of all applets that have gauges
   in order to use the right directory
 - Wifi: Fixed the status if we are not connected
 - Dbus: removed a conflict with the Help applet
 - Messaging-Menu: updated applet-menu.c => Memory leaks on pixbufs
 - Dbus: Fixed a crash when changing dock theme if a 'third-party' applet
    is running
 - Netspeed: in /proc/net/dev, there are 8 values to drop after the card id
    except if there is whitespaces just after this ':' character
    and fixed order and value for ON_ICON display
 - dock-rendering/toto: removed a useless file
 - Clipper: fixed the loading of the remembered items
    (they had the wrong type) and fixed a bug if we reduce the list of items
 - Folders, dustbin, Network-Monitor: tried to not use cast if it's possible
 - Code cleaned and re-organised a few functions
   (e.g. emblem references has been renamed)
 - Removed useless files: powermanager-dbus*
 - Updating translations
 - Fixed a few warnings at the compilation
 - Removed a few useless output messages
 - Fixed these LP bugs:
  + Empty trash from the trashcan does not delete files
     from usb harddisks: LP: #658681
  + Switcher applet doesn't respect desktop numbers LP: #626782
* Upstream (short) ChangeLog (2.4.0~1 -> 2.4.0~2):
 - Messaging-Menu: fixed a wrong g_object_unref (double free)
    and a small memory leak
 - Folders: fixed a tiny warning at the compilation (32bits)
 - switcher: removed an unnecessary config parameter
 - Folders: file size: used English instead of French translation.
 - Indicator applet: Forced a cast to remove an annoying warning
    due to clumsy dbusmenu_gtkmenu_new() declaration
 - Fixed the detection of the screensaver
 - Fixed tiny warnings at the compilation (with CAIRO_CONTAINER)
* debian/control:
 - Updated the version of cairo-dock-[core;data;dev].
 - Added gvfs as 'Suggests' for cairo-dock-plug-ins-integration
    (Used for managing files)
 - Removed 'libthunar-vfs-1-dev' (libthunar-vfs is no longer installed
    by default since XFCE 4.8 and it is replaced by gvfs)
 - Removed 'indicator-me' (no longer available
    and the installation of Cairo-Dock produces an error)
 - Moved 'indicator-messages' to 'Recommends'
* debian/rules:
 - Updated the name of CMake extras flags
* debian/cairo-dock-plug-ins-data.lintian-overrides:
 - Deleted (now useless)
* debian/cairo-dock-plug-ins.lintian-overrides:
 - Cairo-Dock Plug-Ins are not linked to gldi
 - shlib-without-versioned-soname: forwarded to upstream.
* debian/cairo-dock-plug-ins-integration.lintian-overrides:
 - Cairo-Dock Plug-Ins are not linked to gldi
 - ldconfig and shlibs are not needed
* debian/cairo-dock-plug-ins.install:
 - Fixed lintian errors: package-installs-python-bytecode
* debian/control: Fixed lintian warnings:
 - python-script-but-no-python-dep
 - description-synopsis-starts-with-article
* debian/changelog:
 - Fixed lintian warning: old-fsf-address-in-copyright-file
* debian/patches/01-switcher-force-compact-view.patch: 
 - Forced the compact view because the other doesn't work

[ Iain Lane ]
* Fix Mono/CLI build to be ~policy compliant and use correct compiler

Show diffs side-by-side

added added

removed removed

Lines of Context:
250
250
        
251
251
        CD_APPLET_LEAVE ();
252
252
}
253
 
void cd_mpris_getPlaying_async (void)  // used by Audacious.
 
253
void cd_mpris_getPlaying_async (void)
254
254
{
255
255
        if (s_pGetStatusCall != NULL)
256
256
                return;
264
264
 
265
265
/* Teste si MP joue de la musique ou non
266
266
 */
267
 
void cd_mpris_getPlaying (void)  // used by Audacious too.
 
267
void cd_mpris_getPlaying (void)  // sync version, used by Audacious.
268
268
{
269
269
        cd_debug ("%s ()\n", __func__);
270
270
        int iStatus = _mpris_get_status (0);
451
451
        cd_musicplayer_get_cover_path (cCoverPath, TRUE);
452
452
}
453
453
 
454
 
/* Recupere les infos de la chanson courante, y compris le chemin de la couverture (la telecharge au besoin).
455
 
 */
456
 
/**static void cd_mpris_getSongInfos (void)
457
 
{
458
 
        GHashTable *data_list = NULL;
459
 
        const gchar *data;
460
 
                
461
 
        if(dbus_g_proxy_call (myData.dbus_proxy_player, "GetMetadata", NULL,
462
 
                G_TYPE_INVALID,
463
 
                MP_DBUS_TYPE_SONG_METADATA,
464
 
                &data_list,
465
 
                G_TYPE_INVALID))
466
 
        {
467
 
                _extract_metadata (data_list);
468
 
                
469
 
                g_hash_table_destroy (data_list);
470
 
        }
471
 
        else
472
 
        {
473
 
                cd_warning ("  can't get song properties");
474
 
                g_free (myData.cPlayingUri);
475
 
                myData.cPlayingUri = NULL;
476
 
                g_free (myData.cTitle);
477
 
                myData.cTitle = NULL;
478
 
                g_free (myData.cAlbum);
479
 
                myData.cAlbum = NULL;
480
 
                g_free (myData.cArtist);
481
 
                myData.cArtist = NULL;
482
 
                g_free (myData.cCoverPath);
483
 
                myData.cCoverPath = NULL;
484
 
                myData.iSongLength = 0;
485
 
                myData.iTrackNumber = 0;
486
 
                myData.cover_exist = FALSE;
487
 
        }
488
 
}*/
489
 
 
490
454
static void _on_got_song_infos (DBusGProxy *proxy, DBusGProxyCall *call_id, CairoDockModuleInstance *myApplet)
491
455
{
492
456
        cd_debug ("=== %s ()", __func__);
562
526
        if (metadata != NULL)
563
527
        {
564
528
                _extract_metadata (metadata);
565
 
                myData.bIsRunning = TRUE;
566
529
                myData.iPlayingStatus = PLAYER_PLAYING;  // pour les lecteurs bugues comem Exaile qui envoit un statut "stop" au changement de musique sans envoyer de status "play" par la suite. On considere donc que si le lecteur joue une nouvelle musique, c'est qu'il est en "play".
567
530
        }
568
531
        else
581
544
                myData.iSongLength = 0;
582
545
                myData.iTrackNumber = 0;
583
546
                myData.cover_exist = FALSE;
584
 
                
585
 
                cd_musicplayer_dbus_detect_player ();
586
547
        }
587
548
        cd_musicplayer_update_icon (TRUE);
588
549
        CD_APPLET_LEAVE ();
594
555
{
595
556
        CD_APPLET_ENTER;
596
557
        //cd_debug ("MP : %s (%x)\n", __func__, status);
597
 
        myData.bIsRunning = TRUE;
598
558
        myData.iGetTimeFailed = 0;
599
559
        int iStatus = _extract_status_mpris (status, 0);
600
560
        _set_playing_status_mpris (iStatus);
603
563
        if (myData.iPlayingStatus == PLAYER_PLAYING)  // le handler est stoppe lorsque le lecteur ne joue rien.
604
564
                cd_musicplayer_relaunch_handler ();
605
565
        
606
 
        if(! myData.cover_exist && (myData.cPlayingUri != NULL || myData.cTitle != NULL))
 
566
        if (myData.iPlayingStatus == PLAYER_STOPPED)
 
567
                CD_APPLET_SET_QUICK_INFO_ON_MY_ICON (NULL);
 
568
        
 
569
        if(! myData.cover_exist/** && (myData.cPlayingUri != NULL || myData.cTitle != NULL)*/)
607
570
        {
608
571
                cd_musicplayer_set_surface (myData.iPlayingStatus);
609
572
        }
629
592
// Definition du backend. //
630
593
////////////////////////////
631
594
 
632
 
/* Fonction de connexion au bus de MP.
633
 
 */
634
 
static gboolean cd_mpris_dbus_connect_to_bus (void)
635
 
{
636
 
        if (cairo_dock_dbus_is_enabled ())
637
 
        {
638
 
                // cree les proxys.
639
 
                myData.dbus_enable = cd_musicplayer_dbus_connect_to_bus ();
640
 
                
641
 
                myData.dbus_enable_shell = musicplayer_dbus_connect_to_bus_Shell ();
642
 
                
643
 
                dbus_g_proxy_add_signal(myData.dbus_proxy_player, "StatusChange",
644
 
                        MP_DBUS_TYPE_PLAYER_STATUS_MPRIS,
645
 
                        G_TYPE_INVALID);
646
 
                dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "StatusChange",
647
 
                        G_CALLBACK(onChangePlaying_mpris), NULL, NULL);
648
 
                
649
 
                dbus_g_proxy_add_signal(myData.dbus_proxy_player, "TrackChange",
650
 
                        MP_DBUS_TYPE_SONG_METADATA,
651
 
                        G_TYPE_INVALID);
652
 
                dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "TrackChange",
653
 
                        G_CALLBACK(onChangeSong_mpris), NULL, NULL);
654
 
                
655
 
                dbus_g_proxy_add_signal(myData.dbus_proxy_shell, "TrackListChange",
656
 
                        MP_DBUS_TYPE_TRACKLIST_DATA,
657
 
                        G_TYPE_INVALID);
658
 
                dbus_g_proxy_connect_signal(myData.dbus_proxy_shell, "TrackListChange",
659
 
                        G_CALLBACK(onChangeTrackList_mpris), NULL, NULL);
660
 
                
661
 
                return TRUE;
662
 
        }
663
 
        return FALSE;
664
 
}
665
 
 
666
595
/* Permet de liberer la memoire prise par le backend.
667
596
 */
668
 
static void cd_mpris_free_data (void)
 
597
static void cd_mpris_stop (void)
669
598
{
670
599
        if (myData.dbus_proxy_player != NULL)
671
600
        {
698
627
                dbus_g_proxy_disconnect_signal(myData.dbus_proxy_shell, "TrackListChange",
699
628
                        G_CALLBACK(onChangeTrackList_mpris), NULL);
700
629
        }
701
 
        
702
 
        musicplayer_dbus_disconnect_from_bus();
703
 
        musicplayer_dbus_disconnect_from_bus_Shell();
704
630
}
705
631
 
706
632
 
769
695
 
770
696
/* Recupere le temps ecoule chaque seconde (pas de signal pour ca).
771
697
 */
772
 
static void cd_mpris_read_data (void)
 
698
static void cd_mpris_get_data (void)
773
699
{
774
 
        if (myData.dbus_enable)
 
700
        if (myData.iPlayingStatus == PLAYER_PLAYING)
775
701
        {
776
 
                if (myData.bIsRunning)
 
702
                cd_mpris_get_time_elapsed ();
 
703
                if (myData.iCurrentTime < 0)  // aucune info de temps sur le bus => lecteur ferme.
777
704
                {
778
 
                        if (myData.iPlayingStatus == PLAYER_PLAYING)
779
 
                        {
780
 
                                cd_mpris_get_time_elapsed ();
781
 
                                if (myData.iCurrentTime < 0)  // aucune info de temps sur le bus => lecteur ferme.
782
 
                                {
783
 
                                        myData.iGetTimeFailed ++;  // certains lecteurs (qmmp par exemple) envoient le signal 'playing' trop tot lorsqu'on les relance, ils ne fournissent pas de duree tout de suite, et donc l'applet stoppe. On fait donc 3 tentatives avant de declarer le lecteur ferme.
784
 
                                        cd_debug ("failed to get time %d time(s)", myData.iGetTimeFailed);
785
 
                                        if (myData.iGetTimeFailed > 2)
786
 
                                        {
787
 
                                                cd_debug (" => player is likely closed");
788
 
                                                myData.iPlayingStatus = PLAYER_NONE;
789
 
                                                myData.iCurrentTime = -2;  // le temps etait a -1, on le change pour provoquer un redraw.
790
 
                                                myData.bIsRunning = FALSE;
791
 
                                        }
792
 
                                }
793
 
                                else
794
 
                                        myData.iGetTimeFailed = 0;
795
 
                        }
796
 
                        else if (myData.iPlayingStatus != PLAYER_PAUSED)  // en pause le temps reste constant.
797
 
                        {
798
 
                                myData.iCurrentTime = 0;
799
 
                                myData.iGetTimeFailed = 0;
 
705
                        myData.iGetTimeFailed ++;  // certains lecteurs (qmmp par exemple) envoient le signal 'playing' trop tot lorsqu'on les relance, ils ne fournissent pas de duree tout de suite, et donc l'applet stoppe. On fait donc 3 tentatives avant de declarer le lecteur ferme.
 
706
                        cd_debug ("failed to get time %d time(s)", myData.iGetTimeFailed);
 
707
                        if (myData.iGetTimeFailed > 2)
 
708
                        {
 
709
                                cd_debug (" => player is likely closed");
 
710
                                myData.iPlayingStatus = PLAYER_NONE;
 
711
                                myData.iCurrentTime = -2;  // le temps etait a -1, on le change pour provoquer un redraw.
800
712
                        }
801
713
                }
802
 
                else 
803
 
                {
804
 
                        myData.iCurrentTime = 0;
 
714
                else
805
715
                        myData.iGetTimeFailed = 0;
806
 
                }
807
 
                //cd_message (" myData.iCurrentTime <- %d", __func__, myData.iCurrentTime);
808
716
        }
809
 
}
810
 
 
811
 
/* Initialise le backend de MP.
812
 
 */
813
 
static void _on_detect_player (void)
814
 
{
815
 
        if (myApplet == NULL)  // precaution.
816
 
                return ;
817
 
        cd_debug ("myData.bIsRunning : %d\n", myData.bIsRunning);
818
 
        if(myData.bIsRunning)  // player en cours d'execution, on recupere son etat.
 
717
        else if (myData.iPlayingStatus != PLAYER_PAUSED)  // en pause le temps reste constant.
819
718
        {
820
 
                cd_debug ("MP : MP is running\n");
821
 
                
822
 
                cd_mpris_getPlaying_async ();  // will get song infos after playing status.
823
 
                /**cd_mpris_getPlaying ();
824
 
                cd_mpris_getSongInfos ();
825
 
                cd_musicplayer_update_icon (TRUE);
826
 
                cd_musicplayer_relaunch_handler ();*/
 
719
                myData.iCurrentTime = 0;
 
720
                myData.iGetTimeFailed = 0;
827
721
        }
828
722
}
829
723
 
830
 
static void cd_mpris_configure (void)
 
724
static void cd_mpris_start (void)
831
725
{
832
 
        myData.DBus_commands.path = "/Player";
833
 
        myData.DBus_commands.path2 = "/TrackList";
834
 
        myData.DBus_commands.interface = "org.freedesktop.MediaPlayer";
835
 
        myData.DBus_commands.interface2 = "org.freedesktop.MediaPlayer";
 
726
        // register to the signals
 
727
        dbus_g_proxy_add_signal(myData.dbus_proxy_player, "StatusChange",
 
728
                MP_DBUS_TYPE_PLAYER_STATUS_MPRIS,
 
729
                G_TYPE_INVALID);
 
730
        dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "StatusChange",
 
731
                G_CALLBACK(onChangePlaying_mpris), NULL, NULL);
 
732
 
 
733
        dbus_g_proxy_add_signal(myData.dbus_proxy_player, "TrackChange",
 
734
                MP_DBUS_TYPE_SONG_METADATA,
 
735
                G_TYPE_INVALID);
 
736
        dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "TrackChange",
 
737
                G_CALLBACK(onChangeSong_mpris), NULL, NULL);
 
738
 
 
739
        dbus_g_proxy_add_signal(myData.dbus_proxy_shell, "TrackListChange",
 
740
                MP_DBUS_TYPE_TRACKLIST_DATA,
 
741
                G_TYPE_INVALID);
 
742
        dbus_g_proxy_connect_signal(myData.dbus_proxy_shell, "TrackListChange",
 
743
                G_CALLBACK(onChangeTrackList_mpris), NULL, NULL);
836
744
        
837
 
        myData.dbus_enable = cd_mpris_dbus_connect_to_bus ();  // se connecte au bus et aux signaux du lecteur.
838
 
        if (myData.dbus_enable)
839
 
        {
840
 
                cd_musicplayer_dbus_detect_player_async (_on_detect_player);  // on teste la presence du lecteur sur le bus <=> s'il est ouvert ou pas.
841
 
                cd_musicplayer_set_surface (PLAYER_NONE);  // en attendant de le savoir, on considere qu'il est eteint.
842
 
        }
843
 
        else  // sinon on signale par l'icone appropriee que le bus n'est pas accessible.
844
 
        {
845
 
                cd_musicplayer_set_surface (PLAYER_BROKEN);
846
 
        }
 
745
        // get the current state.
 
746
        cd_mpris_getPlaying_async ();  // will get song infos after playing status.
 
747
        /**cd_mpris_getPlaying ();
 
748
        cd_mpris_getSongInfos ();
 
749
        cd_musicplayer_update_icon (TRUE);
 
750
        cd_musicplayer_relaunch_handler ();*/
847
751
}
848
752
 
849
 
MusicPlayerHandeler *cd_mpris_new_handler (void)
 
753
MusicPlayerHandler *cd_mpris_new_handler (void)
850
754
{
851
 
        MusicPlayerHandeler *pHandler = g_new0 (MusicPlayerHandeler, 1);
852
 
        pHandler->read_data = cd_mpris_read_data;
853
 
        pHandler->free_data = cd_mpris_free_data;
854
 
        pHandler->configure = cd_mpris_configure;
 
755
        MusicPlayerHandler *pHandler = g_new0 (MusicPlayerHandler, 1);
 
756
        pHandler->get_data = cd_mpris_get_data;
 
757
        pHandler->stop = cd_mpris_stop;
 
758
        pHandler->start = cd_mpris_start;
855
759
        pHandler->control = cd_mpris_control;
856
760
        pHandler->iPlayerControls = PLAYER_PREVIOUS | PLAYER_PLAY_PAUSE | PLAYER_NEXT | PLAYER_STOP | PLAYER_SHUFFLE | PLAYER_REPEAT | PLAYER_ENQUEUE;
857
761
        pHandler->bSeparateAcquisition = FALSE;
858
762
        pHandler->iLevel = PLAYER_GOOD;
 
763
        
 
764
        pHandler->path = "/Player";
 
765
        pHandler->interface = "org.freedesktop.MediaPlayer";
 
766
        pHandler->path2 = "/TrackList";
 
767
        pHandler->interface2 = "org.freedesktop.MediaPlayer";
 
768
        
859
769
        return pHandler;
860
770
}