• Immutable Page
  • Info
  • Attachments

WRAP / UNWRAP

Compiz provides a method for plugins to execute their own code in place of core functions (or other plugin's functions) by the use of the WRAP and UNWRAP macros and function pointers. The advantages to this is that you can have your plugins, for example, handle X Events, draw something on screen, modify the way a window is painted and others. In this way, your plugin can do high level drawing or event handling at the same time that core does.

Setting up your plugin

Wrappable functions that are avaliable are indicated in core by a new datatype, usually FunctionNameProc. These functions are never called directly by core, instead, they are called from a function pointer in Core's CompDisplay, CompScreen or CompWindow structures. In order for WRAP / UNWRAP to work, you need to create function pointers in your own plugin's structures, using the same data types as the core function pointers. This function pointer will store the function pointer that core's function pointer was set to before your plugin overwrites it. You must make sure that the label given to your function pointer is the same as the one in core.

Using WRAP/UNWRAP

You should always WRAP a function in your object initialization phase (relevant to the object) and UNWRAP it in your object finitialization stage. To WRAP a function, you can do something like:

typedef struct _PluginStructure
{
    FunctionNameProc functionName;
} PluginStructure;

static void
pluginFunctionName (void)
{
}

PluginStructure *ps = malloc (sizeof(PluginStructure));
CoreStructure *cs;

WRAP (ps, cs, functionName, pluginFunctionName);

What this does, is backup the current function pointer from the screen structure into your own structure, then replace core's function with your own. (!) You must make sure that your function is constructed in the same way

To UNWRAP a core function, the procedure is slightly similar, just make a call like

UNWRAP (ps, cs, functionName);

This restores core's function pointer to what your backed up function pointer was.

Passing control to other functions

All plugins, at some point in their own function called by core, will UNWRAP their function, then call core's new function, then WRAP that function again. This is done like so:

void
pluginFunctionName (CoreStructure *cs,
                    int arg1,
                    int *arg2)
{
    PLUGIN_STRUCTURE (cs); /* Creates a PluginStructure *ps */

    UNWRAP (ps, cs, functionName);
    (*cs->functionName) (cs, arg1, arg2);
    WRAP (ps, cs, functionName, pluginFunctionName);
}

(!) You must pass control to other functions or have your function end or else compiz will hang! This is especially the case with paint functions

Final Notes

After reading how it works, WRAP / UNWRAP works in this kind of way:

  • Plugin wraps a core function
  • That function pointer is backed up in it's own structure
  • Another plugin wraps the new core function
  • The first plugin's function is backed up in it's own structure
  • Etc.

When the function is called:

  • The last wrapped function is called
  • That function does what it needs then UNWRAP's and replaces current core function pointer with the backed up function pointer
  • The plugin that wrapped before that plugin's function is called
  • That function does what it needs then UNWRAP's and replaces current core function pointer with the backed up function pointer
  • Etc until core's function is called
  • The last executed function before core's function WRAP's again, then the function above it etc

A more visual way of representing it would be like this:

/* core function called */

secondPluginFunctionName (CompStructure *cs, int a)
{
     ...
     UNWRAP (ps, cs, functionName);
     firstPluginFunctionName (CompStructure *cs, int a)
     {
         ...
         UNWRAP (ps, cs, functionName);
         functionName (CompStructure *cs, int a)
         {
             ...
         }
         WRAP (ps, cs, functionName, firstPluginFunctionName);
     }
     WRAP (ps, cs, functionName, secondPluginFunctionName);
}
/* core function is called again ^^ */

Development/WRAPUNWRAP (last edited 2009-01-11 21:48:32 by cpe-173-88-213-120)