aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/arch/win32/ArchTaskBarWindows.h
blob: 0edddf895ca20b295b51d18042871dbdb1a78d80 (plain) (blame)
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
/*
 * barrier -- mouse and keyboard sharing utility
 * Copyright (C) 2012-2016 Symless Ltd.
 * Copyright (C) 2003 Chris Schoeneman
 * 
 * This package is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * found in the file LICENSE that should have accompanied this file.
 * 
 * This package 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/>.
 */

#pragma once

#include "arch/IArchTaskBar.h"
#include "arch/IArchMultithread.h"
#include "common/stdmap.h"
#include "common/stdvector.h"

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

#define ARCH_TASKBAR ArchTaskBarWindows

//! Win32 implementation of IArchTaskBar
class ArchTaskBarWindows : public IArchTaskBar {
public:
    ArchTaskBarWindows();
    virtual ~ArchTaskBarWindows();

    virtual void init();

    //! Add a dialog window 
    /*!
    Tell the task bar event loop about a dialog.  Win32 annoyingly
    requires messages destined for modeless dialog boxes to be
    dispatched differently than other messages.
    */
    static void            addDialog(HWND);

    //! Remove a dialog window
    /*!
    Remove a dialog window added via \c addDialog().
    */
    static void            removeDialog(HWND);

    // IArchTaskBar overrides
    virtual void        addReceiver(IArchTaskBarReceiver*);
    virtual void        removeReceiver(IArchTaskBarReceiver*);
    virtual void        updateReceiver(IArchTaskBarReceiver*);

private:
    class ReceiverInfo {
    public:
        UINT            m_id;
    };

    typedef std::map<IArchTaskBarReceiver*, ReceiverInfo> ReceiverToInfoMap;
    typedef std::map<UINT, ReceiverToInfoMap::iterator> CIDToReceiverMap;
    typedef std::vector<UINT> CIDStack;
    typedef std::map<HWND, bool> Dialogs;

    UINT                getNextID();
    void                recycleID(UINT);

    void                addIcon(UINT);
    void                removeIcon(UINT);
    void                updateIcon(UINT);
    void                addAllIcons();
    void                removeAllIcons();
    void                modifyIconNoLock(ReceiverToInfoMap::const_iterator,
                            DWORD taskBarMessage);
    void                removeIconNoLock(UINT id);
    void                handleIconMessage(IArchTaskBarReceiver*, LPARAM);

    bool                processDialogs(MSG*);
    LRESULT                wndProc(HWND, UINT, WPARAM, LPARAM);
    static LRESULT CALLBACK
                        staticWndProc(HWND, UINT, WPARAM, LPARAM);
    void                threadMainLoop();
    static void*        threadEntry(void*);

    HINSTANCE            instanceWin32();

private:
    static ArchTaskBarWindows*    s_instance;

    // multithread data
    ArchMutex            m_mutex;
    ArchCond            m_condVar;
    bool                m_ready;
    int                    m_result;
    ArchThread            m_thread;

    // child thread data
    HWND                m_hwnd;
    UINT                m_taskBarRestart;

    // shared data
    ReceiverToInfoMap    m_receivers;
    CIDToReceiverMap    m_idTable;
    CIDStack            m_oldIDs;
    UINT                m_nextID;

    // dialogs
    Dialogs            m_dialogs;
    Dialogs            m_addedDialogs;
};