summaryrefslogtreecommitdiff
path: root/src/example.cpp
blob: 2589ebb4275deb81a865f9c9b1f7064feb6a2a02 (plain)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
/* Compiz example plugin
 * example.cpp
 *
 * Copyright (c) 2008 Sam Spilsbury <smspillaz@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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.
 *
 * Your own copyright notice would go above. You are free to choose whatever
 * licence you want, just take note that some compiz code is GPL and you will
 * not be able to re-use it if you want to use a different licence.
 */

#include "example.h"

/* You must also call this. This creates a proper vTable for a plugin name in the 
 * first argument (it's a macro, so you don't need a string). This changes from
 * time to time as the vTable changes, so it is a good way of ensure plugins keep
 * current */

COMPIZ_PLUGIN_20090315 (example, ExamplePluginVTable);

/* This is the function that is called before the screen is 're-painted'. It is used for animation
 * and such because it gives you a time difference between when the last time the screen was repainted
 * and the current time of the execution of the functions in milliseconds). It's part of the composite
 * plugin's interface
 */

void
ExampleScreen::preparePaint (int ms)
{
    /* compLogMessage is a framework for reporting messages to the terminal via compiz */
    compLogMessage ("example", CompLogLevelInfo, "preparePaint Called\n");

    /* At the end of every function, you must call BaseClass->functionName (args) in order to pass on
     * the call chain */
    cScreen->preparePaint (ms);
}

/* This is the guts of the paint function. You can transform the way the entire output is painted
 * or you can just draw things on screen with openGL. The unsigned int here is a mask for painting
 * the screen, see opengl/opengl.h on how you can change it */

bool
ExampleScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, // Some basic attribs on how the screen should be painted
			      const GLMatrix		&transform, // Screen transformation matrix
			      const CompRegion		&region, // Region of screen being painted
			      CompOutput 		*output, // Output properties. Use this to the get output width and height for the output being painted
			      unsigned int		mask /* Some other paint properties, see opengl.h */)
{
    bool ret;
    compLogMessage ("example", CompLogLevelInfo, "glPaintOutput Called\n");

    /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
    ret = gScreen->glPaintOutput (attrib, transform, region, output, mask);

    return ret;
}

/* This is called when the output is transformed by a matrix. Basically the same, but core has
 * done a few things for us like clip planes etc */

void
ExampleScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &attrib, // Some basic attribs on how the screen should be painted
			      		 const GLMatrix		&transform, // Screen transformation matrix
			      		 const CompRegion		&region, // Region of screen being painted
			      		 CompOutput 		*output, // Output properties. Use this to the get output width and height for the output being painted
			      		 unsigned int		mask /* Some other paint properties, see opengl.h */)
{
    compLogMessage ("example", CompLogLevelInfo, "glPaintOutput Called\n");

    /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
    gScreen->glPaintOutput (attrib, transform, region, output, mask);
}

/* This is called after screen painting is finished. It gives you a chance to do any cleanup and or
 * call another repaint with screen->damageScreen (). It's also part of the composite plugin's
 * interface.
 */

void
ExampleScreen::donePaint ()
{
    compLogMessage ("example", CompLogLevelInfo, "donePaint Called\n");

    cScreen->donePaint ();
}

/* This is our event handler. It directly hooks into the screen's X Event handler and allows us to handle
 * our raw X Events
 */

void
ExampleScreen::handleEvent (XEvent *event)
{
    compLogMessage ("example", CompLogLevelInfo, "handleEventCalled\n");

    /* Switch event->type to see what kind of even we received */

    switch (event->type)
    {
	/* Read event->xbutton for properties on this */
	case ButtonPress:
	    fprintf (stderr, " * - Button Pressed Event!\n");
	    break;
	/* Read event->xbutton for properties on this */
	case ButtonRelease:
	    fprintf (stderr, " * - Button Released Event!\n");
	    break;
	/* Read event->xmotion for properties on this */
	case MotionNotify:
	    fprintf (stderr, " * - Motion Notify Event!\n");
	    break;
	/* Read event->xkey for properties on this */
	case KeyPress:
	    fprintf (stderr, " * - Key Pressed Event!\n");
	    break;
	/* Read event->xkey for properties on this */
	case KeyRelease:
	    fprintf (stderr, " * - Key Released Event!\n");
	    break;
	/* Read event->xcrossing for properties on this */
	case EnterNotify:
	    fprintf (stderr, " * - Enter Notify Event!\n");
	    break;
	/* Read event->xcrossing for properties on this */
	case LeaveNotify:
	    fprintf (stderr, " * - Leave Notify Event!\n");
	    break;
	/* Read event->xconfigure for properties on this */
	case ConfigureNotify:
	    fprintf (stderr, " * - ConfigureNotify Event!\n");
	    break;
	default:
	    fprintf (stderr, " * - Unknown Event!\n");
	    break;
    }

    screen->handleEvent (event);
}

/* This gets called whenever the window needs to be repainted. WindowPaintAttrib gives you some
 * attributes like brightness/saturation etc to play around with. GLMatrix is the window's
 * transformation matrix. the unsigned int is the mask, have a look at opengl.h on what you can do
 * with it */

bool
ExampleWindow::glPaint (const GLWindowPaintAttrib &attrib, // Brightness, Saturation, Opacity etc
		        const GLMatrix &transform, // Transformation Matrix
		 	const CompRegion &region, // Repaint region
			unsigned int mask) // Other flags. See opengl.h
{
    bool ret;
    compLogMessage ("example", CompLogLevelInfo, "glPaint called!\n");

    ret = gWindow->glPaint (attrib, transform, region, mask);

    return ret;
}

/* This get's called whenever a window's rect is damaged. You can do stuff here or you can adjust the damage
 * rectangle so that the window will update properly. Part of the CompositeWindowInterface.
 */

bool
ExampleWindow::damageRect (bool initial, // initial damage?
			   const CompRect &rect) // The actual rect. Modifyable.
{
    bool ret;
    compLogMessage ("example", CompLogLevelInfo, "damageRect called!\n");

    ret = cWindow->damageRect (initial, rect);

    return ret;
}

/* This is called whenever the window is focussed */

bool
ExampleWindow::focus ()
{
    bool ret;
    compLogMessage ("example", CompLogLevelInfo, "focus called!\n");

    ret = window->focus ();

    return ret;
}

/* This is called whenever the window is activated */

void
ExampleWindow::activate ()
{
    compLogMessage ("example", CompLogLevelInfo, "activate called!\n");

    window->activate ();
}

/* This is called whenever the window must be placed. You can alter the placement position by altering
 * the CompPoint & */

bool
ExampleWindow::place (CompPoint &point)
{
    bool ret;
    compLogMessage ("example", CompLogLevelInfo, "place called!\n");

    ret = window->place (point);
    return ret;
}

/* This is called whenever the window is moved. It tells you how far it's been moved and whether that
 * move should be immediate or animated. (Immediate is usually for a sudden move, false for that
 * usually means the user moved the window */

void
ExampleWindow::moveNotify (int dx,
	    		   int dy,
	    		   bool immediate)
{
    compLogMessage ("example", CompLogLevelInfo, "moveNotify called!\n");

    window->moveNotify (dx, dy, immediate);
}

/* This is called whenever the window is resized. It tells you how much the window has been resized */

void
ExampleWindow::resizeNotify (int dx,
	      		     int dy,
	      		     int dwidth,
	      		     int dheight)
{
    compLogMessage ("example", CompLogLevelInfo, "resizeNotify called!\n");

    window->resizeNotify (dx, dy, dwidth, dheight);
}

/* This is called when another plugin deems a window to be 'grabbed'. You can't actually 'grab' a
 * window in X, but it is useful in case you need to know when a user has grabbed a window for some reason */

void
ExampleWindow::grabNotify (int x,
	    		   int y,
	    		   unsigned int state,
	    		   unsigned int mask)
{
    compLogMessage ("example", CompLogLevelInfo, "grabNotify called!\n");

    window->grabNotify (x, y, state, mask);
}

/* This is called when a window in released from a grab. See above */

void
ExampleWindow::ungrabNotify ()
{
    compLogMessage ("example", CompLogLevelInfo, "ungrabNotify called!\n");

    window->ungrabNotify ();
}

/* This is called when another misc notification arises, such as Map/Unmap etc */

void
ExampleWindow::windowNotify (CompWindowNotify n)
{
    compLogMessage ("example", CompLogLevelInfo, "windowNotify called!\n");

    window->windowNotify (n);
}

/* This is an action. It is called on a keybinding as set in the options. It is binded when
 *  the class is constructed
 */

bool
ExampleScreen::exampleInitiate (CompAction         *action,
		          	CompAction::State  state,
		          	CompOption::Vector &options)
{
    compLogMessage ("example", CompLogLevelInfo, "exampleInitaite called!\n");

    return false;
}

/* Some actions are initiated until the key is let go of, at which point they are terminated */

bool
ExampleScreen::specialInitiate (CompAction         *action,
				CompAction::State  state,
				CompOption::Vector &options)
{
    compLogMessage ("example", CompLogLevelInfo, "specialInitiate called!\n");

    /* You have to set the state to StateTerm* once you've finished with the action */

    if (state & CompAction::StateInitButton)
    {
	action->setState (action->state () | CompAction::StateTermButton);
    }

    if (state & CompAction::StateInitKey)
	action->setState (action->state () | CompAction::StateTermKey);

    return false;
}

bool
ExampleScreen::specialTerminate (CompAction         *action,
				 CompAction::State  state,
				 CompOption::Vector &options)
{
    compLogMessage ("example", CompLogLevelInfo, "specialTerminate called!\n");

    /* It's always good practice to remove that state too */

    action->setState (action->state () &
		      ~(CompAction::StateTermKey |
			CompAction::StateTermButton));

    return false;
}

/* Some actions are so awesome that you can have custom parameters with boost::bind */

bool
ExampleScreen::customInitiate (CompAction	  *action,
			       CompAction::State  state,
			       CompOption::Vector options,
			       int                theMeaningOfLife)
{
    compLogMessage ("example", CompLogLevelInfo, "customInitiate called! The meaning of life is %i\n", theMeaningOfLife);

    return false;
}

/* These are your constructors. You should initialize variables in the order that they are in the classes in your .h file */

/* Lets get into buisness. This is the constructor, it replaces the initScreen, initEtc
 * things that used to be in compiz and is called automatically when an instance of this
 * class is created. Notice how it is the same name as the class name. It has to be that way.
 */

ExampleScreen::ExampleScreen (CompScreen *screen) :// The constructor takes a CompScreen *,
    PluginClassHandler <ExampleScreen, CompScreen> (screen), // Initiate PluginClassHandler class template
    screen (screen),
    cScreen (CompositeScreen::get (screen)),
    gScreen (GLScreen::get (screen)),
    foo (42)
{
    compLogMessage ("example", CompLogLevelInfo, "ExampleScreen constructor called!");
    ScreenInterface::setHandler (screen); // Sets the screen function hook handler
    CompositeScreenInterface::setHandler (cScreen); // Ditto for cScreen
    GLScreenInterface::setHandler (gScreen); // Ditto for gScreen

    optionSetExampleInitiate (exampleInitiate); // Initiate handler for 'example' action
    optionSetSpecialInitiate (specialInitiate); // Initiate handler for 'special' action
    optionSetSpecialTerminate (specialTerminate); // Terminate handler for 'custorm' action
    optionSetCustomInitiate (boost::bind (customInitiate, _1, _2, _3, 42)); // Initiate handler for 'special' action. Note how boost::bind is used to create a new function with more args? Neat eh?
}

/* This is the destructor. It is called when the class is destroyed. If you allocated any
 * memory or need to do some cleanup, here is where you do it. Note the tilde (~)?
 */

ExampleScreen::~ExampleScreen ()
{
    compLogMessage ("example", CompLogLevelInfo, "ExampleScreen destructor called!\n");
}

ExampleWindow::ExampleWindow (CompWindow *window) :
    PluginClassHandler <ExampleWindow, CompWindow> (window), // Initiate our PrivateHandler class template
    window (window), 
    cWindow (CompositeWindow::get (window)),
    gWindow (GLWindow::get (window))
{
    compLogMessage ("example", CompLogLevelInfo, "ExampleWindow constructor called!");
    WindowInterface::setHandler (window); // Sets the window function hook handler
    CompositeWindowInterface::setHandler (cWindow); // Ditto for cWindow
    GLWindowInterface::setHandler (gWindow); // Ditto for gWindow
}

ExampleWindow::~ExampleWindow ()
{
    compLogMessage ("example", CompLogLevelInfo, "ExampleWindow destructor called!\n");
}

/* This is the very first function compiz calls. It kicks off plugin initialization */

bool
ExamplePluginVTable::init ()
{
    /* Calls to checkPluginABI check the ABI of a particular plugin to see if it is loaded
     * and in sync with your current build. If it fails the plugin will not load otherwise
     * compiz will crash.
     */

    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
	 return false;
    if (!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
	 return false;
    if (!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
	 return false;

    return true;
}