~compiz-team/compiz-showmouse-plugin/0.9.5

« back to all changes in this revision

Viewing changes to src/showmouse.cpp

  • Committer: Sam Spilsbury
  • Date: 2009-08-22 06:57:28 UTC
  • Revision ID: git-v1:663e5cad9816680467bdb4246dc9352257f4ef15
Initial C++ port. Drawing is broken to some extent, although this may because of differences to the particlesystem ABI in firepaint and showmouse

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Compiz show mouse pointer plugin
 
4
 *
 
5
 * showmouse.cpp
 
6
 *
 
7
 * Copyright : (C) 2008 by Dennis Kasprzyk
 
8
 * E-mail    : onestone@opencompositing.org
 
9
 *
 
10
 * Ported to Compiz 0.9 by:
 
11
 * Copyright : (C) 2009 by Sam Spilsbury
 
12
 * E-mail    : smpillaz@gmail.com
 
13
 *
 
14
 *
 
15
 * This program is free software; you can redistribute it and/or
 
16
 * modify it under the terms of the GNU General Public License
 
17
 * as published by the Free Software Foundation; either version 2
 
18
 * of the License, or (at your option) any later version.
 
19
 *
 
20
 * This program is distributed in the hope that it will be useful,
 
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
23
 * GNU General Public License for more details.
 
24
 *
 
25
 */
 
26
 
 
27
#include "showmouse.h"
 
28
 
 
29
COMPIZ_PLUGIN_20090315 (showmouse, ShowmousePluginVTable);
 
30
 
 
31
void
 
32
ShowmouseScreen::genNewParticles (int f_time)
 
33
{
 
34
    if (!ps)
 
35
        return;
 
36
 
 
37
    Bool rColor     = optionGetRandom ();
 
38
    float life      = optionGetLife ();
 
39
    float lifeNeg   = 1 - life;
 
40
    float fadeExtra = 0.2f * (1.01 - life);
 
41
    float max_new   = ps->particles.size () * ((float)f_time / 50) * (1.05 - life);
 
42
 
 
43
    unsigned short *c = optionGetColor ();
 
44
 
 
45
    float colr1 = (float)c[0] / 0xffff;
 
46
    float colg1 = (float)c[1] / 0xffff;
 
47
    float colb1 = (float)c[2] / 0xffff;
 
48
    float colr2 = 1.0 / 4.0 * (float)c[0] / 0xffff;
 
49
    float colg2 = 1.0 / 4.0 * (float)c[1] / 0xffff;
 
50
    float colb2 = 1.0 / 4.0 * (float)c[2] / 0xffff;
 
51
    float cola  = (float)c[3] / 0xffff;
 
52
    float rVal;
 
53
 
 
54
    float partw = optionGetSize () * 5;
 
55
    float parth = partw;
 
56
 
 
57
    int i, j;
 
58
 
 
59
    float pos[10][2];
 
60
    int nE       = MIN (10, optionGetEmiters ());
 
61
    float rA     = (2 * M_PI) / nE;
 
62
    int radius   = optionGetRadius ();
 
63
    for (i = 0; i < nE; i++)
 
64
    {
 
65
        pos[i][0]  = sin (rot + (i * rA)) * radius;
 
66
        pos[i][0] += mousePos.x ();
 
67
        pos[i][1]  = cos (rot + (i * rA)) * radius;
 
68
        pos[i][1] += mousePos.y ();
 
69
    }
 
70
 
 
71
    for (i = 0; i < ps->particles.size () && max_new > 0; i++)
 
72
    {
 
73
        Particle *part = ps->particles.at (i);
 
74
        if (part->life <= 0.0f)
 
75
        {
 
76
            // give gt new life
 
77
            rVal = (float)(random() & 0xff) / 255.0;
 
78
            part->life = 1.0f;
 
79
            part->fade = rVal * lifeNeg + fadeExtra; // Random Fade Value
 
80
 
 
81
            // set size
 
82
            part->width = partw;
 
83
            part->height = parth;
 
84
            rVal = (float)(random() & 0xff) / 255.0;
 
85
            part->w_mod = part->h_mod = -1;
 
86
 
 
87
            // choose random position
 
88
 
 
89
            j        = random() % nE;
 
90
            part->x  = pos[j][0];
 
91
            part->y  = pos[j][1];
 
92
            part->z  = 0.0;
 
93
            part->xo = part->x;
 
94
            part->yo = part->y;
 
95
            part->zo = part->z;
 
96
 
 
97
            // set speed and direction
 
98
            rVal     = (float)(random() & 0xff) / 255.0;
 
99
            part->xi = ((rVal * 20.0) - 10.0f);
 
100
            rVal     = (float)(random() & 0xff) / 255.0;
 
101
            part->yi = ((rVal * 20.0) - 10.0f);
 
102
            part->zi = 0.0f;
 
103
 
 
104
            if (rColor)
 
105
            {
 
106
                // Random colors! (aka Mystical Fire)
 
107
                rVal    = (float)(random() & 0xff) / 255.0;
 
108
                part->r = rVal;
 
109
                rVal    = (float)(random() & 0xff) / 255.0;
 
110
                part->g = rVal;
 
111
                rVal    = (float)(random() & 0xff) / 255.0;
 
112
                part->b = rVal;
 
113
            }
 
114
            else
 
115
            {
 
116
                rVal    = (float)(random() & 0xff) / 255.0;
 
117
                part->r = colr1 - rVal * colr2;
 
118
                part->g = colg1 - rVal * colg2;
 
119
                part->b = colb1 - rVal * colb2;
 
120
            }
 
121
            // set transparancy
 
122
            part->a = cola;
 
123
 
 
124
            // set gravity
 
125
            part->xg = 0.0f;
 
126
            part->yg = 0.0f;
 
127
            part->zg = 0.0f;
 
128
 
 
129
            ps->active = TRUE;
 
130
            max_new   -= 1;
 
131
        }
 
132
    }
 
133
 
 
134
    fprintf (stderr, "generated new particles at mean position %i %i\n", mousePos.x (), mousePos.y ());
 
135
 
 
136
}
 
137
 
 
138
 
 
139
void
 
140
ShowmouseScreen::damageRegion ()
 
141
{
 
142
    int          i;
 
143
    float        w, h, x1, x2, y1, y2;
 
144
 
 
145
    if (!ps)
 
146
        return;
 
147
 
 
148
    x1 = screen->width ();
 
149
    x2 = 0;
 
150
    y1 = screen->height ();
 
151
    y2 = 0;
 
152
 
 
153
    for (i = 0; i < ps->particles.size (); i++)
 
154
    {
 
155
        Particle *p = ps->particles.at (i);
 
156
 
 
157
        if (!p)
 
158
            break;
 
159
 
 
160
        w = p->width / 2;
 
161
        h = p->height / 2;
 
162
 
 
163
        w += (w * p->w_mod) * p->life;
 
164
        h += (h * p->h_mod) * p->life;
 
165
        
 
166
        x1 = MIN (x1, p->x - w);
 
167
        x2 = MAX (x2, p->x + w);
 
168
        y1 = MIN (y1, p->y - h);
 
169
        y2 = MAX (y2, p->y + h);
 
170
    }
 
171
 
 
172
    CompRegion r (floor (x1), floor (y1), (ceil (x2) - floor (x1)),
 
173
                                          (ceil (y2) - floor (y1)));
 
174
    cScreen->damageRegion (r);
 
175
}
 
176
 
 
177
void
 
178
ShowmouseScreen::positionUpdate (const CompPoint &p)
 
179
{
 
180
    mousePos = p;
 
181
}
 
182
 
 
183
 
 
184
void
 
185
ShowmouseScreen::preparePaint (int f_time)
 
186
{
 
187
    if (active && !pollHandle.active ())
 
188
    {
 
189
        mousePos = MousePoller::getCurrentPosition ();
 
190
        pollHandle.start ();
 
191
    }
 
192
 
 
193
    if (active && !ps)
 
194
    {
 
195
        ps = new ParticleSystem (optionGetNumParticles ());
 
196
        if (!ps)
 
197
        {
 
198
            cScreen->preparePaint (f_time);
 
199
            return;
 
200
        }
 
201
 
 
202
        ps->slowdown = optionGetSlowdown ();
 
203
        ps->darken = optionGetDarken ();
 
204
        ps->blendMode = (optionGetBlend()) ? GL_ONE :
 
205
                            GL_ONE_MINUS_SRC_ALPHA;
 
206
 
 
207
        glGenTextures(1, &ps->tex);
 
208
        glBindTexture(GL_TEXTURE_2D, ps->tex);
 
209
 
 
210
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
211
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
212
 
 
213
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0,
 
214
                        GL_RGBA, GL_UNSIGNED_BYTE, starTex);
 
215
        glBindTexture(GL_TEXTURE_2D, 0);
 
216
    }
 
217
 
 
218
    rot = fmod (rot + (((float)f_time / 1000.0) * 2 * M_PI *
 
219
                    optionGetRotationSpeed ()), 2 * M_PI);
 
220
 
 
221
    if (ps && ps->active)
 
222
    {
 
223
        ps->updateParticles (f_time);
 
224
        damageRegion ();
 
225
    }
 
226
 
 
227
    if (ps && active)
 
228
        genNewParticles (f_time);
 
229
 
 
230
    cScreen->preparePaint (f_time);
 
231
}
 
232
 
 
233
void
 
234
ShowmouseScreen::donePaint ()
 
235
{
 
236
    if (active || (ps && ps->active))
 
237
        damageRegion ();
 
238
 
 
239
    if (!active && pollHandle.active ())
 
240
    {
 
241
        pollHandle.stop ();
 
242
    }
 
243
 
 
244
    if (!active && ps && !ps->active)
 
245
    {
 
246
        ps->finiParticles ();
 
247
        delete ps;
 
248
        ps = NULL;
 
249
    }
 
250
 
 
251
    cScreen->donePaint ();
 
252
}
 
253
 
 
254
bool
 
255
ShowmouseScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
 
256
                                const GLMatrix            &transform,
 
257
                                const CompRegion          &region,
 
258
                                CompOutput                *output,
 
259
                                unsigned int              mask)
 
260
{
 
261
 
 
262
    bool           status;
 
263
    GLMatrix       sTransform;
 
264
 
 
265
    status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
 
266
 
 
267
    if (!ps || !ps->active)
 
268
        return status;
 
269
 
 
270
    //sTransform.reset ();
 
271
 
 
272
    sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
 
273
 
 
274
    glPushMatrix ();
 
275
    glLoadMatrixf (sTransform.getMatrix ());
 
276
 
 
277
    ps->drawParticles ();
 
278
 
 
279
    fprintf (stderr, "drawing particles\n");
 
280
 
 
281
    glPopMatrix();
 
282
 
 
283
    glColor4usv (defaultColor);
 
284
 
 
285
    return status;
 
286
}
 
287
 
 
288
bool
 
289
ShowmouseScreen::terminate (CompAction         *action,
 
290
                            CompAction::State  state,
 
291
                            CompOption::Vector options)
 
292
{
 
293
    active = false;
 
294
    damageRegion ();
 
295
 
 
296
    return true;
 
297
}
 
298
 
 
299
bool
 
300
ShowmouseScreen::initiate (CompAction         *action,
 
301
                           CompAction::State  state,
 
302
                           CompOption::Vector options)
 
303
{
 
304
    if (active)
 
305
        return terminate (action, state, options);
 
306
 
 
307
    active = true;
 
308
 
 
309
    return true;
 
310
}
 
311
 
 
312
ShowmouseScreen::ShowmouseScreen (CompScreen *screen) :
 
313
    PluginClassHandler <ShowmouseScreen, CompScreen> (screen),
 
314
    cScreen (CompositeScreen::get (screen)),
 
315
    gScreen (GLScreen::get (screen)),
 
316
    active (false),
 
317
    ps (NULL),
 
318
    rot (0.0f)
 
319
{
 
320
    CompositeScreenInterface::setHandler (cScreen);
 
321
    GLScreenInterface::setHandler (gScreen);
 
322
 
 
323
    pollHandle.setCallback (boost::bind (&ShowmouseScreen::positionUpdate, this,
 
324
                                         _1));
 
325
 
 
326
    optionSetInitiateInitiate (boost::bind (&ShowmouseScreen::initiate, this,
 
327
                                            _1, _2, _3));
 
328
    optionSetInitiateTerminate (boost::bind (&ShowmouseScreen::terminate, this,
 
329
                                             _1, _2, _3));
 
330
 
 
331
    optionSetInitiateButtonInitiate (boost::bind (&ShowmouseScreen::initiate,
 
332
                                                  this,  _1, _2, _3));
 
333
    optionSetInitiateButtonTerminate (boost::bind (&ShowmouseScreen::terminate,
 
334
                                                   this,  _1, _2, _3));
 
335
 
 
336
    optionSetInitiateEdgeInitiate (boost::bind (&ShowmouseScreen::initiate,
 
337
                                                this,  _1, _2, _3));
 
338
    optionSetInitiateEdgeTerminate (boost::bind (&ShowmouseScreen::terminate,
 
339
                                                 this,  _1, _2, _3));
 
340
}
 
341
 
 
342
ShowmouseScreen::~ShowmouseScreen ()
 
343
{
 
344
    if (ps)
 
345
    {
 
346
        ps->finiParticles ();
 
347
        delete ps;
 
348
    }
 
349
 
 
350
    if (pollHandle.active ())
 
351
        pollHandle.stop ();
 
352
}
 
353
 
 
354
bool
 
355
ShowmousePluginVTable::init ()
 
356
{
 
357
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
 
358
        !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
 
359
        !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) ||
 
360
        !CompPlugin::checkPluginABI ("particlesystem", COMPIZ_PARTICLESYSTEM_ABI) ||
 
361
        !CompPlugin::checkPluginABI ("mousepoll", COMPIZ_MOUSEPOLL_ABI))
 
362
        return false;
 
363
 
 
364
    return true;
 
365
}