~compiz-team/compiz-plugins-main/oneiric

« back to all changes in this revision

Viewing changes to mousepoll/src/mousepoll.cpp

  • Committer: Sam Spilsbury
  • Date: 2011-09-29 11:34:08 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110929113408-vnew477gska3l802
Sync in changes from upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Compiz mouse position polling plugin
 
4
 *
 
5
 * mousepoll.c
 
6
 *
 
7
 * Copyright : (C) 2008 by Dennis Kasprzyk
 
8
 * E-mail    : onestone@opencompositing.org
 
9
 *
 
10
 *
 
11
 * This program is free software; you can redistribute it and/or
 
12
 * modify it under the terms of the GNU General Public License
 
13
 * as published by the Free Software Foundation; either version 2
 
14
 * of the License, or (at your option) any later version.
 
15
 *
 
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.
 
20
 *
 
21
 */
 
22
 
 
23
#include "private.h"
 
24
 
 
25
COMPIZ_PLUGIN_20090315 (mousepoll, MousepollPluginVTable);
 
26
 
 
27
bool
 
28
MousepollScreen::getMousePosition ()
 
29
{
 
30
    Window       root, child;
 
31
    int          rootX, rootY;
 
32
    int          winX, winY;
 
33
    int          w = screen->width (), h = screen->height ();
 
34
    unsigned int maskReturn;
 
35
    bool         status;
 
36
 
 
37
    status = XQueryPointer (screen->dpy (), screen->root (),
 
38
                            &root, &child, &rootX, &rootY,
 
39
                            &winX, &winY, &maskReturn);
 
40
 
 
41
    if (!status || rootX > w || rootY > h || screen->root () != root)
 
42
        return false;
 
43
 
 
44
    if (rootX != pos.x () || rootY != pos.y ())
 
45
    {
 
46
        pos.set (rootX, rootY);
 
47
        return true;
 
48
    }
 
49
 
 
50
    return false;
 
51
}
 
52
 
 
53
bool
 
54
MousepollScreen::updatePosition ()
 
55
{
 
56
 
 
57
    if (getMousePosition ())
 
58
    {
 
59
        std::list<MousePoller *>::iterator it;
 
60
        for (it = pollers.begin (); it != pollers.end (); )
 
61
        {
 
62
            MousePoller *poller = *it;
 
63
 
 
64
            it++;
 
65
            poller->mPoint = pos;
 
66
            poller->mCallback (pos);
 
67
        }
 
68
    }
 
69
 
 
70
 
 
71
    return true;
 
72
}
 
73
 
 
74
bool
 
75
MousepollScreen::addTimer (MousePoller *poller)
 
76
{
 
77
    bool                               start = pollers.empty ();
 
78
    std::list<MousePoller *>::iterator it;
 
79
 
 
80
    it = std::find (pollers.begin (), pollers.end (), poller);
 
81
    if (it != pollers.end ())
 
82
        return false;
 
83
 
 
84
    pollers.insert (it, poller);
 
85
 
 
86
    if (start)
 
87
    {
 
88
        getMousePosition ();
 
89
        timer.start ();
 
90
    }
 
91
 
 
92
    return true;
 
93
}
 
94
 
 
95
void
 
96
MousepollScreen::removeTimer (MousePoller *poller)
 
97
{
 
98
    std::list<MousePoller *>::iterator it;
 
99
 
 
100
    it = std::find (pollers.begin(), pollers.end (), poller);
 
101
    if (it == pollers.end ())
 
102
        return;
 
103
 
 
104
    pollers.erase (it);
 
105
 
 
106
    if (pollers.empty ())
 
107
        timer.stop ();
 
108
}
 
109
 
 
110
void
 
111
MousePoller::setCallback (MousePoller::CallBack callback)
 
112
{
 
113
    bool wasActive = mActive;
 
114
 
 
115
    if (mActive)
 
116
        stop ();
 
117
 
 
118
    mCallback = callback;
 
119
 
 
120
    if (wasActive)
 
121
        start ();
 
122
}
 
123
 
 
124
void
 
125
MousePoller::start ()
 
126
{
 
127
    MOUSEPOLL_SCREEN (screen);
 
128
 
 
129
    if (!ms)
 
130
    {
 
131
        compLogMessage ("mousepoll", CompLogLevelWarn,
 
132
                        "Plugin version mismatch, can't start mouse poller.");
 
133
 
 
134
        return;
 
135
    }
 
136
 
 
137
    if (mCallback.empty ())
 
138
    {
 
139
        compLogMessage ("mousepoll", CompLogLevelWarn,
 
140
                        "Can't start mouse poller without callback.");
 
141
        return;
 
142
    }
 
143
 
 
144
    ms->addTimer (this);
 
145
 
 
146
    mActive = true;
 
147
}
 
148
 
 
149
void
 
150
MousePoller::stop ()
 
151
{
 
152
    MOUSEPOLL_SCREEN (screen);
 
153
 
 
154
    /* Prevent broken plugins from calling stop () twice */
 
155
 
 
156
    if (!mActive)
 
157
        return;
 
158
 
 
159
    if (!ms)
 
160
    {
 
161
        compLogMessage ("mousepoll",
 
162
                        CompLogLevelWarn,
 
163
                        "Plugin version mismatch, can't stop mouse poller.");
 
164
 
 
165
        return;
 
166
    }
 
167
 
 
168
    mActive = false;
 
169
 
 
170
    ms->removeTimer (this);
 
171
}
 
172
 
 
173
bool
 
174
MousePoller::active ()
 
175
{
 
176
    return mActive;
 
177
}
 
178
 
 
179
CompPoint
 
180
MousePoller::getCurrentPosition ()
 
181
{
 
182
    CompPoint p;
 
183
 
 
184
    MOUSEPOLL_SCREEN (screen);
 
185
 
 
186
    if (!ms)
 
187
    {
 
188
        compLogMessage ("mousepoll", CompLogLevelWarn,
 
189
                        "Plugin version mismatch, can't get mouse position.");
 
190
    }
 
191
    else
 
192
    {
 
193
        ms->getMousePosition ();
 
194
        p = ms->pos;
 
195
    }
 
196
 
 
197
    return p;
 
198
}
 
199
 
 
200
CompPoint
 
201
MousePoller::getPosition ()
 
202
{
 
203
    return mPoint;
 
204
}
 
205
 
 
206
MousePoller::MousePoller () :
 
207
    mActive (false),
 
208
    mPoint (0, 0),
 
209
    mCallback (NULL)
 
210
{
 
211
}
 
212
 
 
213
MousePoller::~MousePoller ()
 
214
{
 
215
    if (mActive)
 
216
        stop ();
 
217
}
 
218
 
 
219
void
 
220
MousepollScreen::updateTimer ()
 
221
{
 
222
    float timeout = optionGetMousePollInterval ();
 
223
    timer.setTimes (timeout, timeout * 1.5);
 
224
 
 
225
}
 
226
 
 
227
MousepollScreen::MousepollScreen (CompScreen *screen) :
 
228
    PluginClassHandler <MousepollScreen, CompScreen, COMPIZ_MOUSEPOLL_ABI> (screen)
 
229
{
 
230
    updateTimer ();
 
231
    timer.setCallback (boost::bind (&MousepollScreen::updatePosition, this));
 
232
 
 
233
    optionSetMousePollIntervalNotify (boost::bind (&MousepollScreen::updateTimer, this));
 
234
}
 
235
 
 
236
bool
 
237
MousepollPluginVTable::init ()
 
238
{
 
239
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
 
240
        return false;
 
241
 
 
242
    CompPrivate p;
 
243
    p.uval = COMPIZ_MOUSEPOLL_ABI;
 
244
    screen->storeValue ("mousepoll_ABI", p);
 
245
 
 
246
    return true;
 
247
}
 
248
 
 
249
void
 
250
MousepollPluginVTable::fini ()
 
251
{
 
252
    screen->eraseValue ("mousepoll_ABI");
 
253
}