~mc-return/compiz/compiz.merge-src-screen.cpp-improvements

« back to all changes in this revision

Viewing changes to plugins/obs.cpp

  • Committer: Dennis kasprzyk
  • Author(s): Dennis Kasprzyk
  • Date: 2009-03-15 05:09:18 UTC
  • Revision ID: git-v1:163f6b6f3c3b7764987cbdf8e03cc355edeaa499
New generalized build system.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2008 Danny Baumann
3
 
 *
4
 
 * Permission to use, copy, modify, distribute, and sell this software
5
 
 * and its documentation for any purpose is hereby granted without
6
 
 * fee, provided that the above copyright notice appear in all copies
7
 
 * and that both that copyright notice and this permission notice
8
 
 * appear in supporting documentation, and that the name of
9
 
 * Danny Baumann not be used in advertising or publicity pertaining to
10
 
 * distribution of the software without specific, written prior permission.
11
 
 * Danny Baumann makes no representations about the suitability of this
12
 
 * software for any purpose. It is provided "as is" without express or
13
 
 * implied warranty.
14
 
 *
15
 
 * DANNY BAUMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
 
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
 
 * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
 
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
 
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
 
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21
 
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
 
 *
23
 
 * Author: Danny Baumann <dannybaumann@web.de>
24
 
 */
25
 
 
26
 
#include "obs.h"
27
 
 
28
 
COMPIZ_PLUGIN_20081216 (obs, ObsPluginVTable);
29
 
 
30
 
void
31
 
ObsWindow::changePaintModifier (unsigned int modifier,
32
 
                                int          direction)
33
 
{
34
 
    int value, step;
35
 
 
36
 
    if (window->overrideRedirect ())
37
 
        return;
38
 
 
39
 
    if (modifier == MODIFIER_OPACITY &&
40
 
        (window->type () & CompWindowTypeDesktopMask))
41
 
    {
42
 
        return;
43
 
    }
44
 
 
45
 
    step   = oScreen->stepOptions[modifier]->value ().i ();
46
 
    value  = customFactor[modifier] + (step * direction);
47
 
 
48
 
    value = MAX (MIN (value, 100), step);
49
 
 
50
 
    if (value != customFactor[modifier])
51
 
    {
52
 
        customFactor[modifier] = value;
53
 
        modifierChanged (modifier);
54
 
    }
55
 
}
56
 
 
57
 
void
58
 
ObsWindow::updatePaintModifier (unsigned int modifier)
59
 
{
60
 
    int lastFactor;
61
 
 
62
 
    lastFactor = customFactor[modifier];
63
 
 
64
 
    if (modifier == MODIFIER_OPACITY &&
65
 
        (window->type ()& CompWindowTypeDesktopMask))
66
 
    {
67
 
        customFactor[modifier] = 100;
68
 
        matchFactor[modifier]  = 100;
69
 
    }
70
 
    else
71
 
    {
72
 
        int                       i, min, lastMatchFactor;
73
 
        CompOption::Value::Vector *matches, *values;
74
 
 
75
 
        matches = &oScreen->matchOptions[modifier]->value ().list ();
76
 
        values  = &oScreen->valueOptions[modifier]->value ().list ();
77
 
        min     = MIN (matches->size (), values->size ());
78
 
 
79
 
        lastMatchFactor       = matchFactor[modifier];
80
 
        matchFactor[modifier] = 100;
81
 
 
82
 
        for (i = 0; i < min; i++)
83
 
        {
84
 
            if (matches->at (i).match ().evaluate (window))
85
 
            {
86
 
                matchFactor[modifier] = values->at (i).i ();
87
 
                break;
88
 
            }
89
 
        }
90
 
 
91
 
        if (customFactor[modifier] == lastMatchFactor)
92
 
            customFactor[modifier] = matchFactor[modifier];
93
 
    }
94
 
 
95
 
    if (customFactor[modifier] != lastFactor)
96
 
        modifierChanged (modifier);
97
 
}
98
 
 
99
 
void
100
 
ObsWindow::modifierChanged (unsigned int modifier)
101
 
{
102
 
    bool hasCustom = false;
103
 
 
104
 
    if (modifier == MODIFIER_OPACITY)
105
 
        gWindow->glPaintSetEnabled (this, customFactor[modifier] != 100);
106
 
 
107
 
    for (unsigned int i = 0; i < MODIFIER_COUNT; i++)
108
 
        if (customFactor[i] != 100)
109
 
        {
110
 
            hasCustom = true;
111
 
            break;
112
 
        }
113
 
 
114
 
    gWindow->glDrawSetEnabled (this, hasCustom);
115
 
    cWindow->addDamage ();
116
 
}
117
 
 
118
 
static bool
119
 
alterPaintModifier (CompAction          *action,
120
 
                    CompAction::State   state,
121
 
                    CompOption::Vector& options,
122
 
                    unsigned int        modifier,
123
 
                    int                 direction)
124
 
{
125
 
    CompWindow *w;
126
 
    Window     xid;
127
 
 
128
 
    xid = CompOption::getIntOptionNamed (options, "window", 0);
129
 
    w   = screen->findTopLevelWindow (xid);
130
 
 
131
 
    if (w)
132
 
        ObsWindow::get (w)->changePaintModifier (modifier, direction);
133
 
 
134
 
    return true;
135
 
}
136
 
 
137
 
bool
138
 
ObsWindow::glPaint (const GLWindowPaintAttrib& attrib,
139
 
                    const GLMatrix&            transform,
140
 
                    const CompRegion&          region,
141
 
                    unsigned int               mask)
142
 
{
143
 
    mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
144
 
 
145
 
    return gWindow->glPaint (attrib, transform, region, mask);
146
 
}
147
 
 
148
 
/* Note: Normally plugins should wrap into PaintWindow to modify opacity,
149
 
         brightness and saturation. As some plugins bypass paintWindow when
150
 
         they draw windows and our custom values always need to be applied,
151
 
         we wrap into DrawWindow here */
152
 
 
153
 
bool
154
 
ObsWindow::glDraw (const GLMatrix&     transform,
155
 
                   GLFragment::Attrib& attrib,
156
 
                   const CompRegion&   region,
157
 
                   unsigned int        mask)
158
 
{
159
 
    int factor;
160
 
 
161
 
    factor = customFactor[MODIFIER_OPACITY];
162
 
    if (factor != 100)
163
 
    {
164
 
        attrib.setOpacity (factor * attrib.getOpacity () / 100);
165
 
        mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
166
 
    }
167
 
 
168
 
    factor = customFactor[MODIFIER_BRIGHTNESS];
169
 
    if (factor != 100)
170
 
        attrib.setBrightness (factor * attrib.getBrightness () / 100);
171
 
 
172
 
    factor = customFactor[MODIFIER_SATURATION];
173
 
    if (factor != 100)
174
 
        attrib.setSaturation (factor * attrib.getSaturation () / 100);
175
 
 
176
 
    return gWindow->glDraw (transform, attrib, region, mask);
177
 
}
178
 
 
179
 
void
180
 
ObsScreen::matchExpHandlerChanged ()
181
 
{
182
 
    screen->matchExpHandlerChanged ();
183
 
 
184
 
    /* match options are up to date after the call to matchExpHandlerChanged */
185
 
    foreach (CompWindow *w, screen->windows ())
186
 
    {
187
 
        for (unsigned int i = 0; i < MODIFIER_COUNT; i++)
188
 
            ObsWindow::get (w)->updatePaintModifier (i);
189
 
    }
190
 
}
191
 
 
192
 
void
193
 
ObsScreen::matchPropertyChanged (CompWindow  *w)
194
 
{
195
 
    unsigned int i;
196
 
 
197
 
    for (i = 0; i < MODIFIER_COUNT; i++)
198
 
        ObsWindow::get (w)->updatePaintModifier (i);
199
 
 
200
 
    screen->matchPropertyChanged (w);
201
 
}
202
 
 
203
 
#define MODIFIERBIND(modifier, direction) \
204
 
    boost::bind (alterPaintModifier, _1, _2, _3, modifier, direction)
205
 
 
206
 
static const CompMetadata::OptionInfo obsOptionInfo[] = {
207
 
    { "opacity_increase_key", "key", 0,
208
 
      MODIFIERBIND (MODIFIER_OPACITY, 1), 0 },
209
 
    { "opacity_increase_button", "button", 0,
210
 
      MODIFIERBIND (MODIFIER_OPACITY, 1), 0 },
211
 
    { "opacity_decrease_key", "key", 0,
212
 
      MODIFIERBIND (MODIFIER_OPACITY, -1), 0 },
213
 
    { "opacity_decrease_button", "button", 0,
214
 
      MODIFIERBIND (MODIFIER_OPACITY, -1), 0 },
215
 
    { "saturation_increase_key", "key", 0,
216
 
      MODIFIERBIND (MODIFIER_SATURATION, 1), 0 },
217
 
    { "saturation_increase_button", "button", 0,
218
 
       MODIFIERBIND (MODIFIER_SATURATION, 1), 0 },
219
 
    { "saturation_decrease_key", "key", 0,
220
 
      MODIFIERBIND (MODIFIER_SATURATION, -1), 0 },
221
 
    { "saturation_decrease_button", "button", 0,
222
 
      MODIFIERBIND (MODIFIER_SATURATION, -1), 0 },
223
 
    { "brightness_increase_key", "key", 0,
224
 
      MODIFIERBIND (MODIFIER_BRIGHTNESS, 1), 0 },
225
 
    { "brightness_increase_button", "button", 0,
226
 
      MODIFIERBIND (MODIFIER_BRIGHTNESS, 1), 0 },
227
 
    { "brightness_decrease_key", "key", 0,
228
 
      MODIFIERBIND (MODIFIER_BRIGHTNESS, -1), 0 },
229
 
    { "brightness_decrease_button", "button", 0,
230
 
      MODIFIERBIND (MODIFIER_BRIGHTNESS, -1), 0 },
231
 
    { "opacity_step", "int", 0, 0, 0 },
232
 
    { "saturation_step", "int", 0, 0, 0 },
233
 
    { "brightness_step", "int", 0, 0, 0 },
234
 
    { "opacity_matches", "list", "<type>match</type>", 0, 0 },
235
 
    { "opacity_values", "list",
236
 
      "<type>int</type><min>0</min><max>100</max>", 0, 0 },
237
 
    { "saturation_matches", "list", "<type>match</type>", 0, 0 },
238
 
    { "saturation_values", "list",
239
 
      "<type>int</type><min>0</min><max>100</max>", 0, 0 },
240
 
    { "brightness_matches", "list", "<type>match</type>", 0, 0 },
241
 
    { "brightness_values", "list",
242
 
      "<type>int</type><min>0</min><max>100</max>", 0, 0 }
243
 
};
244
 
 
245
 
ObsScreen::ObsScreen (CompScreen *s) :
246
 
    PrivateHandler<ObsScreen, CompScreen> (s),
247
 
    opt (OBS_OPTION_NUM)
248
 
{
249
 
    unsigned int mod;
250
 
 
251
 
    if (!obsVTable->getMetadata ()->initOptions (obsOptionInfo,
252
 
                                                 OBS_OPTION_NUM, opt))
253
 
    {
254
 
        setFailed ();
255
 
        return;
256
 
    }
257
 
 
258
 
    ScreenInterface::setHandler (screen);
259
 
 
260
 
    mod = MODIFIER_OPACITY;
261
 
    stepOptions[mod]  = &opt[OBS_OPTION_OPACITY_STEP];
262
 
    matchOptions[mod] = &opt[OBS_OPTION_OPACITY_MATCHES];
263
 
    valueOptions[mod] = &opt[OBS_OPTION_OPACITY_VALUES];
264
 
 
265
 
    mod = MODIFIER_SATURATION;
266
 
    stepOptions[mod]  = &opt[OBS_OPTION_SATURATION_STEP];
267
 
    matchOptions[mod] = &opt[OBS_OPTION_SATURATION_MATCHES];
268
 
    valueOptions[mod] = &opt[OBS_OPTION_SATURATION_VALUES];
269
 
 
270
 
    mod = MODIFIER_BRIGHTNESS;
271
 
    stepOptions[mod]  = &opt[OBS_OPTION_BRIGHTNESS_STEP];
272
 
    matchOptions[mod] = &opt[OBS_OPTION_BRIGHTNESS_MATCHES];
273
 
    valueOptions[mod] = &opt[OBS_OPTION_BRIGHTNESS_VALUES];
274
 
}
275
 
 
276
 
CompOption::Vector &
277
 
ObsScreen::getOptions ()
278
 
{
279
 
    return opt;
280
 
}
281
 
 
282
 
bool
283
 
ObsScreen::setOption (const char         *name,
284
 
                      CompOption::Value& value)
285
 
{
286
 
   CompOption   *o;
287
 
  unsigned  int i;
288
 
 
289
 
    o = CompOption::findOption (opt, name, NULL);
290
 
    if (!o)
291
 
        return false;
292
 
 
293
 
    for (i = 0; i < MODIFIER_COUNT; i++)
294
 
    {
295
 
        if (o == matchOptions[i])
296
 
        {
297
 
            if (o->set (value))
298
 
            {
299
 
                foreach (CompOption::Value &item, o->value ().list ())
300
 
                    item.match ().update ();
301
 
 
302
 
                foreach (CompWindow *w, screen->windows ())
303
 
                    ObsWindow::get (w)->updatePaintModifier (i);
304
 
 
305
 
                return true;
306
 
            }
307
 
        }
308
 
        else if (o == valueOptions[i])
309
 
        {
310
 
            if (o->set (value))
311
 
            {
312
 
                foreach (CompWindow *w, screen->windows ())
313
 
                    ObsWindow::get (w)->updatePaintModifier (i);
314
 
 
315
 
                return true;
316
 
            }
317
 
        }
318
 
    }
319
 
 
320
 
    return CompOption::setOption (*o, value);
321
 
}
322
 
 
323
 
ObsWindow::ObsWindow (CompWindow *w) :
324
 
    PrivateHandler<ObsWindow, CompWindow> (w),
325
 
    window (w),
326
 
    cWindow (CompositeWindow::get (w)),
327
 
    gWindow (GLWindow::get (w)),
328
 
    oScreen (ObsScreen::get (screen))
329
 
{
330
 
    GLWindowInterface::setHandler (gWindow, false);
331
 
 
332
 
    for (unsigned int i = 0; i < MODIFIER_COUNT; i++)
333
 
    {
334
 
        customFactor[i] = 100;
335
 
        matchFactor[i]  = 100;
336
 
 
337
 
        updatePaintModifier (i);
338
 
    }
339
 
}
340
 
 
341
 
bool
342
 
ObsPluginVTable::init ()
343
 
{
344
 
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
345
 
        !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
346
 
        !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
347
 
    {
348
 
         return false;
349
 
    }
350
 
 
351
 
    getMetadata ()->addFromOptionInfo (obsOptionInfo, OBS_OPTION_NUM);
352
 
    getMetadata ()->addFromFile (name ());
353
 
 
354
 
    return true;
355
 
}