aboutsummaryrefslogtreecommitdiff
path: root/src/media-player-list-greeter.vala
blob: 83e1d3fcc563f7684eda7965b40bc2fbd27d8625 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright 2014 Canonical Ltd.
 * Copyright 2021 Robert Tari
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *      Ted Gould <ted@canonical.com>
 *      Robert Tari <robert@tari.in>
 */

[DBus (name="org.ayatana.Greeter.List")]
public interface AyatanaGreeterList : Object {
    public abstract async string get_active_entry () throws GLib.DBusError, GLib.IOError;
    public signal void entry_selected (string entry_name);
}

public class MediaPlayerListGreeter : MediaPlayerList {
    string? selected_user = null;
    AyatanaGreeterList? proxy = null;
    HashTable<string, MediaPlayerUser> players = new HashTable<string, MediaPlayerUser>(str_hash, str_equal);

    public MediaPlayerListGreeter () {
        Bus.get_proxy.begin<AyatanaGreeterList> (
            BusType.SESSION,
            "org.ayatana.Greeter",
            "/list",
            DBusProxyFlags.NONE,
            null,
            new_proxy);
    }

    void new_proxy (GLib.Object? obj, AsyncResult res) {
        try {
            this.proxy = Bus.get_proxy.end(res);

            this.proxy.entry_selected.connect(active_user_changed);
            this.proxy.get_active_entry.begin ((obj, res) => {
                try {
                    var list = (obj as AyatanaGreeterList);

                    if (list != null)
                    {
                        var value = list.get_active_entry.end(res);
                        active_user_changed(value);
                    }
                } catch (Error e) {
                    warning("Unable to get active entry: %s", e.message);
                }
            });
        } catch (Error e) {
            this.proxy = null;
            warning("Unable to create proxy to the greeter: %s", e.message);
        }
    }

    void active_user_changed (string active_user) {
        /* No change, move along */
        if (selected_user == active_user) {
            return;
        }

        debug(@"Active user changed to: $active_user");

        var old_user = selected_user;

        /* Protect against a null user */
        if (active_user != "" && active_user[0] != '*') {
            selected_user = active_user;
        } else {
            debug(@"Blocking active user change for '$active_user'");
            selected_user = null;
        }

        if (selected_user != null && !players.contains(selected_user)) {
            players.insert(selected_user, new MediaPlayerUser(selected_user));
        }

        if (old_user != null) {
            var old_player = players.lookup(old_user);
            debug("Removing player for user: %s", old_user);
            player_removed(old_player);
        }

        if (selected_user != null) {
            var new_player = players.lookup(selected_user);

            if (new_player != null) {
                debug("Adding player for user: %s", selected_user);
                player_added(new_player);
            }
        }
    }

    /* We need to have an iterator for the interface, but eh, we can
       only ever have one player for the current user */
    public class Iterator : MediaPlayerList.Iterator {
        int i = 0;
        MediaPlayerListGreeter list;

        public Iterator (MediaPlayerListGreeter in_list) {
            list = in_list;
        }

        public override MediaPlayer? next_value () {
            MediaPlayer? retval = null;

            if (i == 0 && list.selected_user != null) {
                retval = list.players.lookup(list.selected_user);
            }
            i++;

            return retval;
        }
    }

    public override MediaPlayerList.Iterator iterator() {
        return new Iterator(this) as MediaPlayerList.Iterator;
    }
}