• Immutable Page
  • Info
  • Attachments

Compiz++ Plugin (Wrapping) Interface:

Usage of functions of the core/other plugins in a normal plugin:

The core/plugin plugins provide *Interface (ScreenInterface, compositeWindowInterface,...) base classes with functions that a plugin can hook into. A plugin has to derive from this base classes and can then implement one or more of its functions.

Example:

class FooScreen : 
  public ScreenInterface,
  public CompositeScreenInterface,
...
{
  ...
  // ScreenInterface
  void handleEvent (XEvent *);

  // CompositeScreenInterface
  void preparePaint (int);
  void donePaint ();

  ...
}

This plugin implements the handleEvent function form the core screen interface and the preparePaint and donePaint functions from the composite plugin screen interface.

The plugin now needs to hook into the system in the plugin class constructor:

FooScreen::FooScreen (CompScreen *screen)
{
  ...

  // Get the composite screen pointer 
  CompositeScreen *cScreen = CompositeScreen::get (screen);

  ScreenInterface::setHandler (screen);
  CompositeScreenInterface::setHandler (cScreen, false);

  ...
}

The ::setHandler ([Interface providing class] *, bool enabled = true); function replaces the calls of WRAP (...) for each implemented function in InitScreen in the C version of compiz. The optional second boolean parameter represents the initial function state. The compiz++ interface allows plugin to disable their functions if they are not needed. In this example the handleEvent function will be enabled and the preparePaint and donePaint functions will be disabled. It's not needed to unregister the interfaces in the destructor (like UNWRAP in finiScreen), because the destructors of the *Interface classes will do it automatically.

The classes that provide interface functions (CompScreen, CompWindow, CompositeScreen, ...) contain a WRAPABLE_HND macro for each of the functions of their Interface class.

This macro generates 4 functions:

WRAPABLE_HND (0, CompositeScreenInterface, void, preparePaint, int);
-->
void preparePaint (int);
void preparePaintSetEnabled (CompositeScreenInterface *, bool);
unsigned int preparePaintGetCurrentIndex ();
void preparePaintSetCurrentIndex (unsigned int);

The first function is the basic function definition to call the function chain. The second function allows a plugin to enable/disable its use of this function: cScreen->preparePaintSetEnabled (this [=FooScreen *], true); Enables the use of the preparePaint function in the Foo plugin.

The last two functions allow the manipulation of the function call chain and should be used with caution. Setting the index to a high number (MAXSHORT) will result the only the core implementation of this function will be called.

int index = cScreen->preparePaintGetCurrentIndex ();
cScreen->preparePaintSetCurrentIndex (MAXSHORT);
... [DO SOMETHING] ..
cScreen->preparePaintSetCurrentIndex (index);

Equals the following code in compiz:

PreparePaintScreenProc oldPtr = screen->preparePaintScreen;
screen->preparePaintScreen = preparePaintScreen;
... [DO SOMETHING] ..
screen->preparePaintScreen = oldPtr;

Inside of a implemented function, a plugin has then only to call the main function again to go on in the function chain:

FooScreen::handleEvent (XEvent *event)
{
....
    screen->handleEvent (event); // replaces UNWRAP/d->handleEvent/WRAP
...
}

Implementation of functions that can be used by other plugins:

A plugin has to provide a *Interface class with the functions that other plugins can use. This class has to derive from the WrapableInterface<[Function base class name],[Interface class name]> base class.

class FooWindowInterface :
  public WrapableInterface<FooWindow,FooWindowInterface>
{
  virtual void a (int i);
  virtual int b (float a, float b); 
}

In this example the Foo plugin would two window based functions a and b; The plugin also has to derive from the WrapableHandler<[Interface class name], [number of functions]> and provide WRAPABLE_HND definitions for each function. WRAPABLE_HND is defined as: WRAPABLE_HND ([function index],[Interface class name], [return type], [function name], [parameter types])

Example:

class FooWindow :
  public WrapableHandler<FooWindowInterface, 2>,
  ...
{
  ...
  WRAPABLE_HND (0, FooWindowInterface, void, a, int);
  WRAPABLE_HND (1, FooWindowInterface, int, b, float, float);
}

In the code the plugin has to provide default function implementations for the *Interface class functions. This is done with the WRAPABLE_DEF([function name], [parameters]) macro.

Example:

void FooWindowInterface::a (int i)
  WRAPABLE_DEF(a, i)

int FooWindowInterface::b (float a, float b)
  WRAPABLE_DEF(b, a, b)

The last and most important part of the whole system are the WRAPABLE_HND_FUNC ([function index],[function name],[parameters]) and WRAPABLE_HND_FUNC_RETURN ([function index],[return type],[function name],[parameters]) macros. These macros realize the whole function chain execution. One of these macros have to be added to the top of each of the main function implementations.

Example:

void FooWindow::a (int i)
{
  WRAPABLE_HND_FUNC(0, a, i)
  ... [Do something] ...
}

int FooWindow::b (float a, float b)
{
  WRAPABLE_HND_FUNC_RETURN(1, int, b, a, b)
  ... [Do something] ...
}

Development/Compiz++Documentation/C++Wrapping (last edited 2009-01-14 01:27:40 by CPE-58-161-137-105)