3
* Compiz mouse position polling plugin
7
* Copyright : (C) 2008 by Dennis Kasprzyk
8
* E-mail : onestone@opencompositing.org
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.
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.
23
#include <compiz-core.h>
25
#include "compiz-mousepoll.h"
27
static CompMetadata mousepollMetadata;
29
static int displayPrivateIndex;
30
static int functionsPrivateIndex;
32
typedef struct _MousepollClient MousepollClient;
34
struct _MousepollClient {
35
MousepollClient *next;
36
MousepollClient *prev;
38
PositionPollingHandle id;
39
PositionUpdateProc update;
42
typedef enum _MousepollDisplayOptions
44
MP_DISPLAY_OPTION_ABI,
45
MP_DISPLAY_OPTION_INDEX,
46
MP_DISPLAY_OPTION_MOUSE_POLL_INTERVAL,
48
} MousepollDisplayOptions;
50
typedef struct _MousepollDisplay {
51
int screenPrivateIndex;
53
CompOption opt[MP_DISPLAY_OPTION_NUM];
56
typedef struct _MousepollScreen {
58
MousepollClient *clients;
59
PositionPollingHandle freeId;
61
CompTimeoutHandle updateHandle;
67
#define GET_MOUSEPOLL_DISPLAY(d) \
68
((MousepollDisplay *) (d)->base.privates[displayPrivateIndex].ptr)
70
#define MOUSEPOLL_DISPLAY(d) \
71
MousepollDisplay *md = GET_MOUSEPOLL_DISPLAY (d)
73
#define GET_MOUSEPOLL_SCREEN(s, md) \
74
((MousepollScreen *) (s)->base.privates[(md)->screenPrivateIndex].ptr)
76
#define MOUSEPOLL_SCREEN(s) \
77
MousepollScreen *ms = GET_MOUSEPOLL_SCREEN (s, GET_MOUSEPOLL_DISPLAY (s->display))
79
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
82
getMousePosition (CompScreen *s)
88
unsigned int maskReturn;
93
status = XQueryPointer (s->display->display, s->root,
94
&root_return, &child_return,
95
&rootX, &rootY, &winX, &winY, &maskReturn);
97
if (!status || rootX > s->width || rootY > s->height ||
98
s->root != root_return)
101
if ((rootX != ms->posX || rootY != ms->posY))
111
updatePosition (void *c)
113
CompScreen *s = (CompScreen *)c;
116
MOUSEPOLL_SCREEN (s);
121
if (getMousePosition (s))
123
MousepollClient *next;
124
for (mc = ms->clients; mc; mc = next)
128
(*mc->update) (s, ms->posX, ms->posY);
135
static PositionPollingHandle
136
mousepollAddPositionPolling (CompScreen *s,
137
PositionUpdateProc update)
139
MOUSEPOLL_SCREEN (s);
140
MOUSEPOLL_DISPLAY (s->display);
144
MousepollClient *mc = malloc (sizeof (MousepollClient));
157
mc->next = ms->clients;
160
ms->clients->prev = mc;
166
getMousePosition (s);
169
md->opt[MP_DISPLAY_OPTION_MOUSE_POLL_INTERVAL].value.i / 2,
170
md->opt[MP_DISPLAY_OPTION_MOUSE_POLL_INTERVAL].value.i,
178
mousepollRemovePositionPolling (CompScreen *s,
179
PositionPollingHandle id)
181
MOUSEPOLL_SCREEN (s);
183
MousepollClient *mc = ms->clients;
185
if (ms->clients && ms->clients->id == id)
187
ms->clients = ms->clients->next;
189
ms->clients->prev = NULL;
195
for (mc = ms->clients; mc; mc = mc->next)
199
mc->next->prev = mc->prev;
201
mc->prev->next = mc->next;
206
if (!ms->clients && ms->updateHandle)
208
compRemoveTimeout (ms->updateHandle);
209
ms->updateHandle = 0;
214
mousepollGetCurrentPosition (CompScreen *s,
218
MOUSEPOLL_SCREEN (s);
221
getMousePosition (s);
229
static const CompMetadataOptionInfo mousepollDisplayOptionInfo[] = {
230
{ "abi", "int", 0, 0, 0 },
231
{ "index", "int", 0, 0, 0 },
232
{ "mouse_poll_interval", "int", "<min>1</min><max>500</max><default>10</default>", 0, 0 }
236
mousepollGetDisplayOptions (CompPlugin *plugin,
237
CompDisplay *display,
240
MOUSEPOLL_DISPLAY (display);
241
*count = NUM_OPTIONS (md);
246
mousepollSetDisplayOption (CompPlugin *plugin,
247
CompDisplay *display,
249
CompOptionValue *value)
256
MOUSEPOLL_DISPLAY (display);
257
o = compFindOption (md->opt, NUM_OPTIONS (md), name, &index);
262
case MP_DISPLAY_OPTION_ABI:
263
case MP_DISPLAY_OPTION_INDEX:
265
case MP_DISPLAY_OPTION_MOUSE_POLL_INTERVAL:
266
status = compSetDisplayOption (display, o, value);
267
for (s = display->screens; s; s = s->next)
269
ms = GET_MOUSEPOLL_SCREEN (s, md);
270
if (ms->updateHandle)
272
compRemoveTimeout (ms->updateHandle);
275
md->opt[MP_DISPLAY_OPTION_MOUSE_POLL_INTERVAL].value.i
277
md->opt[MP_DISPLAY_OPTION_MOUSE_POLL_INTERVAL].value.i,
284
return compSetDisplayOption (display, o, value);
290
static MousePollFunc mousepollFunctions =
292
.addPositionPolling = mousepollAddPositionPolling,
293
.removePositionPolling = mousepollRemovePositionPolling,
294
.getCurrentPosition = mousepollGetCurrentPosition,
298
mousepollInitDisplay (CompPlugin *p,
301
MousepollDisplay *md;
303
if (!checkPluginABI ("core", CORE_ABIVERSION))
306
md = malloc (sizeof (MousepollDisplay));
309
if (!compInitDisplayOptionsFromMetadata (d,
311
mousepollDisplayOptionInfo,
313
MP_DISPLAY_OPTION_NUM))
319
md->screenPrivateIndex = allocateScreenPrivateIndex (d);
320
if (md->screenPrivateIndex < 0)
322
compFiniDisplayOptions (d, md->opt, MP_DISPLAY_OPTION_NUM);
327
md->opt[MP_DISPLAY_OPTION_ABI].value.i = MOUSEPOLL_ABIVERSION;
328
md->opt[MP_DISPLAY_OPTION_INDEX].value.i = functionsPrivateIndex;
330
d->base.privates[displayPrivateIndex].ptr = md;
331
d->base.privates[functionsPrivateIndex].ptr = &mousepollFunctions;
336
mousepollFiniDisplay (CompPlugin *p,
339
MOUSEPOLL_DISPLAY (d);
341
compFiniDisplayOptions (d, md->opt, MP_DISPLAY_OPTION_NUM);
346
mousepollInitScreen (CompPlugin *p,
351
MOUSEPOLL_DISPLAY (s->display);
353
ms = malloc (sizeof (MousepollScreen));
363
ms->updateHandle = 0;
365
s->base.privates[md->screenPrivateIndex].ptr = ms;
370
mousepollFiniScreen (CompPlugin *p,
373
MOUSEPOLL_SCREEN (s);
375
if (ms->updateHandle)
376
compRemoveTimeout (ms->updateHandle);
382
mousepollInitObject (CompPlugin *p,
385
static InitPluginObjectProc dispTab[] = {
386
(InitPluginObjectProc) 0, /* InitCore */
387
(InitPluginObjectProc) mousepollInitDisplay,
388
(InitPluginObjectProc) mousepollInitScreen
391
RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
395
mousepollFiniObject (CompPlugin *p,
398
static FiniPluginObjectProc dispTab[] = {
399
(FiniPluginObjectProc) 0, /* FiniCore */
400
(FiniPluginObjectProc) mousepollFiniDisplay,
401
(FiniPluginObjectProc) mousepollFiniScreen
404
DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
408
mousepollInit (CompPlugin *p)
410
if (!compInitPluginMetadataFromInfo (&mousepollMetadata,
412
mousepollDisplayOptionInfo,
413
MP_DISPLAY_OPTION_NUM,
417
displayPrivateIndex = allocateDisplayPrivateIndex ();
418
if (displayPrivateIndex < 0)
420
compFiniMetadata (&mousepollMetadata);
424
functionsPrivateIndex = allocateDisplayPrivateIndex ();
425
if (functionsPrivateIndex < 0)
427
freeDisplayPrivateIndex (displayPrivateIndex);
428
compFiniMetadata (&mousepollMetadata);
432
compAddMetadataFromFile (&mousepollMetadata, p->vTable->name);
437
mousepollGetObjectOptions (CompPlugin *plugin,
441
static GetPluginObjectOptionsProc dispTab[] = {
442
(GetPluginObjectOptionsProc) 0, /* GetCoreOptions */
443
(GetPluginObjectOptionsProc) mousepollGetDisplayOptions
447
RETURN_DISPATCH (object, dispTab, ARRAY_SIZE (dispTab),
448
NULL, (plugin, object, count));
452
mousepollSetObjectOption (CompPlugin *plugin,
455
CompOptionValue *value)
457
static SetPluginObjectOptionProc dispTab[] = {
458
(SetPluginObjectOptionProc) 0, /* SetCoreOption */
459
(SetPluginObjectOptionProc) mousepollSetDisplayOption
462
RETURN_DISPATCH (object, dispTab, ARRAY_SIZE (dispTab), FALSE,
463
(plugin, object, name, value));
467
mousepollFini (CompPlugin *p)
469
freeDisplayPrivateIndex (displayPrivateIndex);
470
freeDisplayPrivateIndex (functionsPrivateIndex);
471
compFiniMetadata (&mousepollMetadata);
474
static CompMetadata *
475
mousepollGetMetadata (CompPlugin *plugin)
477
return &mousepollMetadata;
480
CompPluginVTable mousepollVTable = {
482
mousepollGetMetadata,
487
mousepollGetObjectOptions,
488
mousepollSetObjectOption
492
getCompPluginInfo20070830 (void)
494
return &mousepollVTable;