• Immutable Page
  • Info
  • Attachments

Extension Plugins

class ExtensionPluginInfo
{
public:
     ExtensionPluginInfo (const CompString &name,
                          unsigned int nEffects,
                          AnimEffect *effects,
                          CompOption::Vector *effectOptions,
                          unsigned int firstEffectOptionIndex);
     
     CompString name;
     unsigned int nEffects;
     AnimEffect *effects;
     
     /// Plugin options to be used in "effect options" strings.
     CompOption::Vector *effectOptions;
     
     /// Index of first effect option.
     unsigned int firstEffectOptionIndex;
     
     // More general and/or non-window functions (including functions that access
     // persistent animation data) to be overriden
     
     /// To be run at the beginning of glPaintOutput.
     virtual void prePaintOutput (CompOutput *output) {}
     
     /// To be run at the beginning of preparePaint.
     virtual void prePreparePaintGeneral () {}
     
     /// To be run at the end of preparePaint.
     virtual void postPreparePaintGeneral () {}
     
     /// To be run when a CompWindowNotifyRestack is handled.
     virtual void handleRestackNotify (AnimWindow *aw) {}
     
     /// To be run at the beginning of initiateOpenAnim.
     virtual void preInitiateOpenAnim (AnimWindow *aw) {}
     
     /// To be run at the beginning of initiateCloseAnim.
     virtual void preInitiateCloseAnim (AnimWindow *aw) {}
     
     /// To be run at the beginning of initiateMinimizeAnim.
     virtual void preInitiateMinimizeAnim (AnimWindow *aw) {}
     
     /// To be run at the beginning of initiateUnminimizeAnim.
     virtual void preInitiateUnminimizeAnim (AnimWindow *aw) {}
     
     /// Initializes plugin's persistent animation data for a window (if any).
     virtual void initPersistentData (AnimWindow *aw) {}
     
     /// Destroys plugin's persistent animation data for a window (if any).
     virtual void destroyPersistentData (AnimWindow *aw) {}
     
     /// To be run at the end of updateEventEffects.
     virtual void postUpdateEventEffects (AnimEvent e,
                                          bool forRandom) {}
                                          
    /// To be run after the startup countdown ends.
    virtual void postStartupCountdown () {}

    virtual bool paintShouldSkipWindow (CompWindow *w) { return false; }

    virtual void cleanUpAnimation (bool closing,
                                    bool destructing) {}

    virtual void processAllRestacks () {}
};

Giving the animation plugin information about your plugin

When extending the animation plugin, the animation plugin needs an ExtensionPluginInfo class instance in order to allocate memory and do operations for the number and type of effects your plugin will be implementing. For this, it needs the name of your extension plugin, how many effects it implements and some details about your plugin's options.

Usually this is done by creating a global instance of your extension plugin info, for example

#define NUM_NONEFFECT_OPTIONS AnimationEg::FirstNonEffectOption;
#define NUM_EFFECTS 1;
AnimEffect animEffects[NUM_EFFECTS]; // static array

ExtensionPlugiInfo animEgExtPluginInfo (CompString ("animationeg"),
                                        NUM_EFFECTS, animEffects, NULL,
                                        NUM_NONEFFECT_OPTIONS);

A few things to note here: first of all, there is the wacky #define NUM_NONEFFECT_OPTIONS - this is because the animation plugin needs to know which options are there for controlling individual animations, and which options are there for controlling the selection of what animation the user wants.

Also note that #define NUM_EFFECTS is there, you must update this every time a new effect is added. animEffects is a global array, so we can pass it as a pointer directly to this object's constructor. When you add animations to this list, obviously, they will be updated in the same pointed to memory.

Finally, this plugin uses the generic ExtensionPluginInfo class, which does not include any extra data or variables or overrides for some animation plugin functions.

Once you have created this object, you can add animations to animEffects and then call AnimScreen::get (screen)->addExtension (&animEgExtPluginInfo);

Creating your own ExtensionPluginInfo class

Obviously ExtensionPluginInfo contains a number of virtual methods, so it makes sense to create your own class derived from it, overload those methods, and pass that class to AnimScreen::get (screen)->addExtension (&animEgExtPluginInfo);. For example:

class AnimationEgExtPluginInfo :
    AnimationExtPluginInfo
{
    public:

        AnimationEgExtPluginInfo (const CompString   &name,
                                  unsigned int       nEffects,
                                  AnimEffect         *effects,
                                  CompOption::Vector *effectOptions,
                                  unsigend int       firstEffectOptionIndex)
            AnimationExtPluginInfo (name, nEffects, effects, effectOptions, firstEffectOptionIndex) {};
        ~AnimationEgExtPluginInfo () {};

        void prePaintOutput (CompOutput *);
};

void
AnimationEgExtPluginInfo::prePaintOutput ()
{
    glBegin (GL_LINE);
    glLineWidth (5.0f);
    glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
    glVertex2f (0.0f, screen->height () / 2, 0.0f);
    glVertex2f (screen->width, screen->height () / 2, 0.0f);
    glEnd ();
}

This code creates some extension plugin info, sets up which options are effect options and which are not, sets up the list of animations that can be used and also registers an action to be handled before compiz starts painting windows on this output (prePaintOutput). In this case it just draws a horizontal line from one end of the screen to the other.

Adding animations to the extension plugin

You might have noticed earlier that we defined an AnimEffect animEffect[NUM_EFFECTS] earlier in the file. Before we add this extension info, we need to fill in this array with actual animations. Most extension plugins use an ::initAnimationList method in order to do this.

All you need to do is construct a new AnimEffectInfo class which describes the name of your animation, which events it can be used for (Open, Close, (Un)Minimize, Shade, Focus) and finally a factory function to create your animation class. The createAnimation<YourEffect> template function is provided for this and should be adequate for this. For example:

void
AnimationEgScreen::initAnimationList ()
{
    int i = 0;
    AnimationScreen *as = AnimationScreen::get (screen);

    animEffects[i++] = new AnimEffectInfo ("animationeg:eg",
                                           true, true, true, false, false,
                                           &createAnimation<EgAnim>);

    animEgExtPluginInfo.effectOptions = &getOptions ();
    as->addExtension (animEgExtPluginInfo);
}

Development/zero-nine/PluginClasses/Animation/MakingAnExtensionPlugin (last edited 2010-10-16 13:46:45 by 58-7-165-35)